Issue
Hi I am trying to test the fragments using Espresso. I am having two buttons in a activity and I am replacing the fragments while click the button. My XML is following.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Fragment No.1"
android:onClick="selectFrag" />
<Button
android:id="@+id/button2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="selectFrag"
android:text="Fragment No.2" />
<fragment
android:name="com.example.admin1.espressotestingsample.fragment.FragmentOne"
android:id="@+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
I am having two fragments. Each fragment having a button and textview.
The fragments are
FragmentOne XML:-
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@android:color/holo_blue_bright">
<TextView
android:textSize="28dp"
android:id="@+id/fragment_textview_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="First Fragment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textColor="@android:color/white"
/>
<Button
android:id="@+id/fragment_button_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button One"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
FragmentTwo XML:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@android:color/holo_orange_dark">
<TextView
android:textSize="28dp"
android:id="@+id/fragment_textview_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Second Fragment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textColor="@android:color/white"/>
<Button
android:id="@+id/fragment_button_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button Two"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
My Activity code is
public class ActivityFragment extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_activity);
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_place, new FragmentOne()).addToBackStack(null)
.commit();
}
public void selectFrag(View view) {
Fragment fr;
if(view == findViewById(R.id.button2)) {
fr = new FragmentTwo();
}else {
fr = new FragmentOne();
}
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_place, fr).addToBackStack(null)
.commit();
}
}
My test case are following.
@Rule
public ActivityTestRule<ActivityFragment> testRule =
new ActivityTestRule<>(ActivityFragment.class);
@Before
public void init(){
testRule.getActivity()
.getSupportFragmentManager().beginTransaction();
}
@Test
public void testSecondFragment() {
onView(withId(R.id.button2)).perform(click());
onView(allOf(withId(R.id.fragment_textview_two),withEffectiveVisibility(VISIBLE))).
check(matches(isDisplayed()));
}
When I run this test it's working fine. But when I try the second one I am getting error.
@Test
public void testFirstFragment() {
onView(withId(R.id.button1)).perform(click());
onView(allOf(withId(R.id.fragment_textview_one),withEffectiveVisibility(VISIBLE))).
check(matches(isDisplayed()));
}
But when I run this test I am getting the following error.
android.support.test.espresso.AmbiguousViewMatcherException: '(with id: com.example.admin1.espressotestingsample:id/fragment_textview_one and view has effective visibility=VISIBLE)' matches multiple views in the hierarchy.
Problem views are marked with '****MATCHES****' below.
View Hierarchy:
+>DecorView{id=-1, visibility=VISIBLE, width=1080, height=1920, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params={(0,0)(fillxfill) ty=BASE_APPLICATION wanim=0x10302f8
fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
pfl=FORCE_DRAW_STATUS_BAR_BACKGROUND}, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=3}
|
+->LinearLayout{id=-1, visibility=VISIBLE, width=1080, height=1794, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.FrameLayout$LayoutParams@704500d, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
|
+-->ViewStub{id=16908682, res-name=action_mode_bar_stub, 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, layout-params=android.widget.LinearLayout$LayoutParams@4483bc2, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0}
|
+-->FrameLayout{id=16908290, res-name=content, visibility=VISIBLE, width=1080, height=1731, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.LinearLayout$LayoutParams@e334d10, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=63.0, child-count=1}
|
+--->LinearLayout{id=-1, visibility=VISIBLE, width=1080, height=1731, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.FrameLayout$LayoutParams@9682a3c, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=3}
|
+---->Button{id=2131165220, res-name=button1, visibility=VISIBLE, width=1080, height=126, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=false, is-selected=false, layout-params=android.widget.LinearLayout$LayoutParams@4a073c5, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, text=Fragment No.1, input-type=0, ime-target=true, has-links=false}
|
+---->Button{id=2131165221, res-name=button2, visibility=VISIBLE, width=1080, height=126, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=false, is-selected=false, layout-params=android.widget.LinearLayout$LayoutParams@af5811a, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=126.0, text=Fragment No.2, input-type=0, ime-target=false, has-links=false}
|
+---->ConstraintLayout{id=2131165244, res-name=fragment_place, visibility=VISIBLE, width=1080, height=1479, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.LinearLayout$LayoutParams@e5a94e6, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=252.0, child-count=4}
|
+----->TextView{id=2131165245, res-name=fragment_textview_one, visibility=VISIBLE, width=479, height=100, 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=false, is-selected=false, layout-params=android.support.constraint.ConstraintLayout$LayoutParams@5d3aa27, tag=null, root-is-layout-requested=false, has-input-connection=false, x=301.0, y=690.0, text=First Fragment, input-type=0, ime-target=false, has-links=false} ****MATCHES****
|
+----->Button{id=2131165242, res-name=fragment_button_one, visibility=VISIBLE, width=286, height=126, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=false, is-selected=false, layout-params=android.support.constraint.ConstraintLayout$LayoutParams@a2184d4, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, text=Button One, input-type=0, ime-target=false, has-links=false}
|
+----->ConstraintLayout{id=-1, visibility=VISIBLE, width=1080, height=1479, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.support.constraint.ConstraintLayout$LayoutParams@bab1972, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
|
+------>TextView{id=2131165245, res-name=fragment_textview_one, visibility=VISIBLE, width=479, height=100, 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=false, is-selected=false, layout-params=android.support.constraint.ConstraintLayout$LayoutParams@9c6c1c3, tag=null, root-is-layout-requested=false, has-input-connection=false, x=301.0, y=690.0, text=First Fragment, input-type=0, ime-target=false, has-links=false} ****MATCHES****
|
+------>Button{id=2131165242, res-name=fragment_button_one, visibility=VISIBLE, width=286, height=126, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=false, is-selected=false, layout-params=android.support.constraint.ConstraintLayout$LayoutParams@87c1a40, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, text=Button One, input-type=0, ime-target=false, has-links=false}
|
+----->ConstraintLayout{id=-1, visibility=VISIBLE, width=1080, height=1479, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.support.constraint.ConstraintLayout$LayoutParams@30d5abe, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
|
+------>TextView{id=2131165245, res-name=fragment_textview_one, visibility=VISIBLE, width=479, height=100, 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=false, is-selected=false, layout-params=android.support.constraint.ConstraintLayout$LayoutParams@b49b71f, tag=null, root-is-layout-requested=false, has-input-connection=false, x=301.0, y=690.0, text=First Fragment, input-type=0, ime-target=false, has-links=false} ****MATCHES****
|
+------>Button{id=2131165242, res-name=fragment_button_one, visibility=VISIBLE, width=286, height=126, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=false, is-selected=false, layout-params=android.support.constraint.ConstraintLayout$LayoutParams@5289a6c, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, text=Button One, input-type=0, ime-target=false, has-links=false}
|
+->View{id=16908336, res-name=navigationBarBackground, visibility=VISIBLE, width=1080, height=126, 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=false, is-selected=false, layout-params=android.widget.FrameLayout$LayoutParams@cded835, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=1794.0}
|
+->View{id=16908335, res-name=statusBarBackground, visibility=VISIBLE, width=1080, height=63, 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=false, is-selected=false, layout-params=android.widget.FrameLayout$LayoutParams@ec064ca, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0}
|
at dalvik.system.VMStack.getThreadStackTrace(Native Method)
at java.lang.Thread.getStackTrace(Thread.java:1538)
at android.support.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:88)
at android.support.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:51)
at android.support.test.espresso.ViewInteraction.waitForAndHandleInteractionResults(ViewInteraction.java:312)
at android.support.test.espresso.ViewInteraction.check(ViewInteraction.java:297)
at com.example.admin1.espressotestingsample.FragmentTest.testSecondFragment(FragmentTest.java:67)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at android.support.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:80)...
I am confused. First code is working. But second code is not working. Please let me know the reason and help me to test the fragments. Because my entire project build with fragments only.
Solution
Your test throws AmbigousViewMatcherException
because it finds 3 of the same matcher withId(R.id.fragment_textview_one), withEffectiveVisibility(VISIBLE))
, that means 3 of FragmentOne
were created.
In your activity XML layout, change the fragment
in the following:
<fragment
android:name="com.example.admin1.espressotestingsample.fragment.FragmentOne"
android:id="@+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent" />
To other types of ViewGroup
, say a FrameLayout
:
<FrameLayout
android:name="com.example.admin1.espressotestingsample.fragment.FragmentOne"
android:id="@+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent" />
I'm not sure about the third fragment, but you shouldn't need to call testRule.getActivity().getSupportFragmentManager().beginTransaction()
especially when you're not doing anything with it in your test.
Answered By - Aaron
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.