Espresso wird mit der Funktion angekündigt, dass es immer darauf wartet, dass der UI-Thread von Android im Leerlauf ist, so dass Sie sich um kein Timing kümmern müssen Probleme. Aber ich habe anscheinend eine Ausnahme gefunden: -/Espresso wartet nicht darauf, dass der Wischvorgang auf einem ViewPager beendet wird
Die Einstellung ist ein ViewPager
mit einem EditText
in jedem Fragment. Ich möchte Espresso Text in das EditText
auf das erste Fragment geben, streichen Sie mit dem zweiten Fragment und das gleiche zu tun mit dem EditText
in diesem Fragment (3-mal):
@MediumTest
public void testSwipe() throws InterruptedException {
onView(withIdInActiveFragment(EXTERN_HOURS_INPUT))
.perform(typeText("8.0"));
onView(withIdInActiveFragment(DAY_PAGER))
.perform(swipeLeft());
//Thread.sleep(2000); // <--- uncomment this and the test runs fine
onView(withIdInActiveFragment(EXTERN_HOURS_INPUT))
.perform(typeText("8.0"));
onView(withIdInActiveFragment(DAY_PAGER))
.perform(swipeLeft());
//Thread.sleep(2000);
onView(withIdInActiveFragment(EXTERN_HOURS_INPUT))
.perform(typeText("8.0"));
onView(withIdInActiveFragment(DAY_PAGER))
.perform(swipeLeft());
}
public static Matcher<View> withIdInActiveFragment(int id) {
return Matchers.allOf(withParent(isDisplayed()), withId(id));
}
Aber ich diesen Fehler erhalten, während die erste Durchführung streichen:
android.support.test.espresso.AmbiguousViewMatcherException: '(has parent matching: is displayed on the screen to the user and with id: de.cp.cp_app_android:id/extern_hours_input)' matches multiple views in the hierarchy.
Problem views are marked with '****MATCHES****' below.
View Hierarchy:
...
+-------->AppCompatEditText{id=2131558508, res-name=extern_hours_input, visibility=VISIBLE, width=110, height=91, has-focus=true, has-focusable=true, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=true, is-focusable=true, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=true, editor-info=[inputType=0x2002 imeOptions=0x6 privateImeOptions=null actionLabel=null actionId=0 initialSelStart=3 initialSelEnd=3 initialCapsMode=0x0 hintText=null label=null packageName=null fieldId=0 fieldName=null extras=null ], x=165.0, y=172.0, text=8.0, input-type=8194, ime-target=true, has-links=false} ****MATCHES****
...
+-------->AppCompatEditText{id=2131558508, res-name=extern_hours_input, visibility=VISIBLE, width=110, height=91, 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, root-is-layout-requested=false, has-input-connection=true, editor-info=[inputType=0x2002 imeOptions=0x6 privateImeOptions=null actionLabel=null actionId=0 initialSelStart=0 initialSelEnd=0 initialCapsMode=0x2000 hintText=null label=null packageName=null fieldId=0 fieldName=null extras=null ], x=165.0, y=172.0, text=, input-type=8194, ime-target=false, has-links=false} ****MATCHES****
Espresso in eine EditText
mit der ID schreiben will EXTERN_HOURS_INPUT
, die sichtbar ist. Da die Swipe-Aktion noch nicht beendet ist, sind sowohl das EditTexts
im ersten als auch das zweite Fragment sichtbar, weshalb der passende onView(withIdInActiveFragment(EXTERN_HOURS_INPUT))
mit 2 Übereinstimmungen fehlschlägt.
Wenn ich manuell eine Pause erzwinge, indem ich Thread.sleep(2000);
nach der Swipe-Aktion hinzufüge, ist alles in Ordnung.
Kann jemand Espresso warten, bis die Wischaktion ausgeführt wird? Oder weiß jemand zumindest, warum das passiert? Da der UI-Thread nicht inaktiv sein kann, wenn eine Wischaktion ausgeführt wird, kann er? Hier
ist die activity_day_time_record.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="timerecord"
type="de.cp.cp_app_android.model.TimerecordDatabindingWrapper" />
</data>
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
style="@style/cp_relative_layout"
android:descendantFocusability="afterDescendants"
tools:context=".activities.DayRecordActivity">
<include
android:id="@+id/toolbar"
layout="@layout/cp_toolbar"></include>
<!-- Arbeitsstunden -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/section_title_workhours"
style="?android:attr/listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="25dip"
android:layout_below="@id/toolbar"
android:text="@string/dayrecord_section_workhours" />
<TextView
android:id="@+id/extern_hours"
style="@style/dayrecord_label"
android:layout_below="@id/section_title_workhours"
android:text="@string/dayrecord_label_extern_hours" />
<EditText
android:id="@+id/extern_hours_input"
style="@style/dayrecord_decimal_input"
android:layout_alignBaseline="@id/extern_hours"
android:layout_toEndOf="@id/extern_hours"
android:layout_toRightOf="@id/extern_hours"
bind:addTextChangedListener="@{timerecord.changed}"
bind:binding="@{timerecord.hoursExtern}"
bind:setOnFocusChangeListener="@{timerecord.hoursExternChanged}" />
<!-- android:text='@{timerecord.hoursExtern != null ? String.format("%.1f", timerecord.hoursExtern) : ""}' -->
</RelativeLayout>
</ScrollView>
Und die activity_swipe_day.xml
:
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/day_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
Ich bin nicht sicher ViewPager nur ein Fragment 'active' macht. Es hält auch benachbarte Fragmente. –
Es behält benachbarte Fragmente (in meinem Fall eine vorherige und eine folgende), aber sie sind nicht sichtbar. Wenn also Espresso warten würde, dass die Wischaktion beendet wird, würde nur ein'EditText' sichtbar sein und der Abgleich würde gelingen. – Ruik
Ich vermute 'withIdInActiveFragment'. Ist das Ihre benutzerdefinierte 'Matcher'-Implementierung? Nicht alle Matchierer filtern nach Sichtbarkeit. –