How can i open tab in Espresso test? I tried to do Espresso.onView(ViewMatchers.withId(R.id.practice_results_tab)).perform(ViewActions.click());
, but that doesn't working. In that code i opened Layout of this tab.
There is the XML file:
<TabHost
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/practice_tabHost">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</TabWidget>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:id="@+id/practice_settings_tab"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:id="@+id/practice_results_tab"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
</LinearLayout>
</FrameLayout>
</LinearLayout>
</TabHost>
What ID should I use to open tab?
Error in logcat:
Caused by: java.lang.RuntimeException: Action will not be performed because the target view does not match one or more of the following constraints:
at least 90 percent of the view's area is displayed to the user.
Target view: "LinearLayout{id=2131296384, res-name=practice_results_tab, visibility=GONE, width=0, height=0, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=true, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}"
The Espresso Test Recorder tool lets you create UI tests for your app without writing any test code. By recording a test scenario, you can record your interactions with a device and add assertions to verify UI elements in particular snapshots of your app.
Espresso is an open source android user interface (UI) testing framework developed by Google. The term Espresso is of Italian origin, meaning Coffee. Espresso is a simple, efficient and flexible testing framework.
check is a method which accepts an argument of type ViewAssertion and do assertion using passed in ViewAssertion object. matches(withText(“Hello”)) returns a view assertion, which will do the real job of asserting that both actual view (found using withId) and expected view (found using withText) are one and the same.
You really need to add code for us to give a proper answer. I'm guessing here that you used a TabHost and TabWidget in the way this example does: https://maxalley.wordpress.com/2012/10/25/android-creating-a-tab-layout-with-tabhost-and-tabwidget/
I've created a sample project at https://github.com/hanscappelle/SO-25016397
Your Activity could then look like this:
public class MainActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TabHost tabHost = getTabHost();
// setNewTab(context, tabHost, tag, title, icon, contentID);
this.setNewTab(this, tabHost, "tab1", R.string.textTabTitle1, R.drawable.ic_tab_settings, R.id.practice_settings_tab);
this.setNewTab(this, tabHost, "tab2", R.string.textTabTitle2, R.drawable.ic_tab_results, R.id.practice_results_tab);
}
private void setNewTab(Context context, TabHost tabHost, String tag, int title, int icon, int contentID ){
TabSpec tabSpec = tabHost.newTabSpec(tag);
String titleString = getString(title);
tabSpec.setIndicator(titleString, context.getResources().getDrawable(android.R.drawable.star_on));
tabSpec.setContent(contentID);
tabHost.addTab(tabSpec);
}
}
I found another code example at https://maxalley.wordpress.com/2012/10/27/android-styling-the-tabs-in-a-tabwidget/ with a helper method that injects an ImageView
for the tabs.
private View getTabIndicator(Context context, int title, int icon) {
View view = LayoutInflater.from(context).inflate(R.layout.tab_layout, null);
ImageView iv = (ImageView) view.findViewById(R.id.imageView);
iv.setImageResource(icon);
TextView tv = (TextView) view.findViewById(R.id.textView);
tv.setText(title);
return view;
}
Now it gets interesting cause this way we can easily set an ID or a tag on these injected View
objects and use these in Espresso.
If you adapt that helper to accept a tag for each view helper code will look something like this:
private View getTabIndicator(Context context, int title, int icon, int viewId, String viewTag) {
View view = LayoutInflater.from(context).inflate(R.layout.tab_layout, null);
ImageView iv = (ImageView) view.findViewById(R.id.image_view);
iv.setImageResource(icon);
TextView tv = (TextView) view.findViewById(R.id.text_view);
tv.setText(title);
tv.setTag(viewTag);
return view;
}
If you use only icons you can set the ID on the ImageView also.
And the Espresso code to click these tabs:
Espresso.onView(ViewMatchers.withTagValue(Matchers.is((Object)"tab1"))).perform(ViewActions.click());
If you go for IDs you need these IDs to be defined somewhere. Use a simple Android resource file with some ID definitions.
The view ID resource file, named /values/ids.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="tab1" type="id" />
</resources>
The adapted helper:
private View getTabIndicator(Context context, int title, int icon, int viewId, String viewTag) {
View view = LayoutInflater.from(context).inflate(R.layout.tab_layout, null);
ImageView iv = (ImageView) view.findViewById(R.id.image_view);
iv.setImageResource(icon);
TextView tv = (TextView) view.findViewById(R.id.text_view);
tv.setText(title);
tv.setId(viewId);
return view;
}
If you use only icons you can set the ID on the ImageView also.
And the Espresso code to click these tabs:
Espresso.onView(ViewMatchers.withId(R.id.tab1)).perform(ViewActions.click());
Why did you use this TabHost in the first place? Note that this class is deprecated by now. A ViewPager with tabs or the ActionBar might be better options depending on your use case.
In cases like this the first problem is often to find the proper view. For this use the View Hierarchy tool. It's part of the android SDK and lives in the tools directory.
You can start it from command line like this:
cd ANDROID_SDK_LOCATION/tools
hierarchyviewer
Or use Android Studio menu: Tools > Android > Android Device Monitor. Then open the Hierarchy View perspective from the menu in the device monitor: Window > Open Perspective > Hierarchy View .
I prefer the first option just because the Device Monitor does way too much for our intentions.
Now use the Layout View in combination with the View Properties view to find the ID and tags of the view you want.
Some instructions on this tool: http://developer.android.com/tools/debugging/debugging-ui.html
the only thing that works for me is:
public void clickOnTab(String tabText) {
Matcher<View> matcher = allOf(withText(tabText),
isDescendantOfA(withId(R.id.ll_tab_container)));
onView(matcher).perform(click());
}
where ll_tab_container
is the linearlayout for my custom tab layout. and if you had a tab called "shopping" then you would pass that as the tabText.
onView(withText("Your tab label")).perform(click())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With