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