Android Espresso falsch eingestellt, oder funktioniert das nicht stabil?

Ich implementiere seit einer Woche einen Android-Espresso-Test. Was ist die reale Sache - ist die Implementierung eines Serveraufrufs und warten Sie mit Espresso darauf. Dies nennt man Idle Resourse Call, und wir müssen Regeln befolgen, die ziemlich klar sind. Eigentlich habe ich eine Lösung gefunden, aber das Ergebnis ist erschüttert - ich bin nur erfolgreich, wenn ich Kommentarzeilen mache

Espresso.onView(ViewMatchers.withId(R.id.email)).perform(ViewActions.typeText("some shit"));
Espresso.onView(ViewMatchers.withId(R.id.password)).perform(ViewActions.typeText("123"));

und ersetze sie durch "huck":

final EditText email = (EditText) act.findViewById(R.id.email);
        final EditText password = (EditText) act.findViewById(R.id.password);
        getInstrumentation().runOnMainSync(new Runnable() {
            public void run() {
                email.setText("Engineer");
                password.setText("2342");
            }
        });

.. bevor Sie auf die Schaltfläche klicken, die nach dem emulierten Aufruf des Servers eine neue Aktivität startet. Das sind meine ganzen Dateien: build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "shoppinglist.kizema.anton.testappespresso"
        minSdkVersion 14
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    packagingOptions {
        exclude 'LICENSE.txt'
        exclude 'META-INF/notice.txt'
        exclude 'META-INF/license.txt'
        exclude 'META-INF/ASL2.0'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/DEPENDENCIES'
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'

    // App's dependencies, including test
    compile 'com.android.support:support-annotations:21.0.3'

    // Testing-only dependencies
    androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
}

LoginActivity (Erste Aktivität):

//set up initial listener
private void initLoginHelper(){
    loginHelper = new Server() {
        @Override
        public void login(String email, String code, String phone, String password, boolean loginByPhoneNumber) {
            //ask server
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //done
            Intent intent = new Intent(LoginActivity.this, SecondActivity.class);
            startActivityForResult(intent, 0);
        }
    };
}

//onButtonClick handler
public void btnLogInSuka(View v) {
    performLogin();
}
void performLogin() {
    new Thread(new Runnable() {
        @Override
        public void run() {
                loginHelper.login(emailParam,codeParam,phoneParam,passwordParam,false);
        }
    }).start();
}

And AplicationTest.java (Espresso-Tests): @LargeTest öffentliche Klasse ApplicationTest erweitert ActivityInstrumentationTestCase2

public ApplicationTest() {
    super(LoginActivity.class);
}

CountingIdlingResource idleRes;

@Override
public void setUp() throws Exception {
    super.setUp();
    getActivity();

    idleRes = new CountingIdlingResource("server");
    Espresso.registerIdlingResources(idleRes);
}

public void testSample(){
    final LoginActivity act = (LoginActivity) getCurrentActivity();
    Server aHelper = act.getUserHelper();

    MyUserHelperExternalIdleRes helper2 = new MyUserHelperExternalIdleRes(idleRes, aHelper);
    act.setUserHelper(helper2);


    //if comment this and uncomment next two lines we receive PerformException
    final EditText email = (EditText) act.findViewById(R.id.email);
    final EditText password = (EditText) act.findViewById(R.id.password);
    getInstrumentation().runOnMainSync(new Runnable() {
        public void run() {
            email.setText("Engineer");
            password.setText("2342");
        }
    });

//        Espresso.onView(ViewMatchers.withId(R.id.email)).perform(ViewActions.typeText("some shit"));
//        Espresso.onView(ViewMatchers.withId(R.id.password)).perform(ViewActions.typeText("123"));

    Espresso.closeSoftKeyboard();
    Espresso.onView(ViewMatchers.withId(R.id.btnLogIn)).check(ViewAssertions.matches(ViewMatchers.isDisplayed()));

    Espresso.onView(ViewMatchers.withId(R.id.btnLogIn)).perform(ViewActions.click());
    Espresso.onView(ViewMatchers.withId(R.id.secondActivityOpened)).check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
    Espresso.pressBack();

    Espresso.closeSoftKeyboard();
    Espresso.onView(ViewMatchers.withId(R.id.btnLogIn)).perform(ViewActions.click());
}

Activity getCurrentActivity() {
    getInstrumentation().waitForIdleSync();
    final Activity[] activity = new Activity[1];
    try {
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                java.util.Collection<Activity> activites = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED);
                activity[0] = Iterables.getOnlyElement(activites);
            }});
    } catch (Throwable throwable) {
        throwable.printStackTrace();
    }
    return activity[0];
}

class MyUserHelperExternalIdleRes implements Server {
    private Server aHelper;
    private CountingIdlingResource udleRes;

    public MyUserHelperExternalIdleRes(CountingIdlingResource udleRes, Server aHelper) {
        this.aHelper = aHelper;
        this.udleRes = udleRes;
    }

    @Override
    public void login(String email, String code, String phone, String password, boolean loginByPhoneNumber) {

        udleRes.increment();
        try {
            aHelper.login(email,code, phone,password,loginByPhoneNumber);
        } finally {
            udleRes.decrement();
        }
    }
}

}

So, wenn wir tatsächlich eine grundlegende Espresso-Operation ausführen: Espresso.onView (ViewMatchers.withId (R.id.password)). Perform (ViewActions.typeText ("123"));

Wir erhalten eine PerformException: Der Button kann nicht anhand der ID gefunden werden. Wenn wir einen Huck machen (mit der Einstellung Runnable auf UI-Thread), sind wir mit dieser einfachen Demo erfolgreich. In meiner Haupt-App gibt es andere Bugs mit Espresso (das "huck" oben hat nicht funktioniert, wir bekommen den gleichen Fehler). Mit Sicherheit habe ich einen kniffligen Fehler, ich nehme an, dass etwas mit den Projekteinstellungen (Espresso) nicht stimmt - ich bin zu schlecht mit gradle. Bitte helfen Sie mir dabei, oder stellen Sie einen Link zur Android Studio-Beispiel-App mit Espresso-Tests bereit (ich habe keine gefunden, alle Apps sind schlecht konfiguriert (kein Gradle), und nach dem Import in Android Studio kann ich sie nicht mit @ starte

gradlew connectedAndroidTest

Antworten auf die Frage(2)

Ihre Antwort auf die Frage