2016-06-16 51 views
20

Sto imparando i test di strumentazione Android con l'espresso. Ho una app che ha un drawermenu e c'è un menu chiamato About. Stavo testando clic su quella voce di menu e il contenuto dell'attività.Errore test Espresso fallito

TestFunction:

@Test 
public void testNavigationDrawerAboutMenu() { 
    onView(withId(R.id.drawer_layout)) 
      .perform(DrawerActions.open()); //open drawer 
    onView(withText("About")).perform(click()); 
    onView(withId(R.id.aboutsptemail)).check(matches(withText(R.string.screen_about_support_email))); 
    onView(withId(R.id.aboutcpright)).check(matches(isDisplayed())); 
    onView(withId(R.id.aboutprivacy)).check(matches(isDisplayed())); 
    onView(withId(R.id.abouttermsconditions)).check(matches(isDisplayed())); 
    onView(withId(R.id.aboutsptemail)).perform(click()); 
} 

ora l'ultimo TextView ha weblink embeded in esso. così quando fai clic su di esso si apre il link (www.support.com) in una webview in app stesso. Voglio testare questa fumactionality. così ho provato questo:

intended(hasComponent(WebViewActivity.class.getName())); //check if webview called on supportEmail link click 

ma test non riesce con questo Traccia di errore:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.test.espresso.intent.OngoingStubbing android.support.test.espresso.intent.Intents.internalIntending(org.hamcrest.Matcher)' on a null object reference 
at android.support.test.espresso.intent.Intents.intending(Intents.java:155) 
at com.ScanBuy.SmartLabel.NavigationDrawerActivityTests.testNavigationDrawerAboutMenu(NavigationDrawerActivityTests.java:94) 
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.statement.UiThreadStatement.evaluate(UiThreadStatement.java:55) 
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:270) 
at org.junit.rules.RunRules.evaluate(RunRules.java:20) 
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.junit.runners.Suite.runChild(Suite.java:128) 
at org.junit.runners.Suite.runChild(Suite.java:27) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
at org.junit.runner.JUnitCore.run(JUnitCore.java:115) 
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59) 
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262) 
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1879) 

Ho anche cercato di risolvere da al minimo le risorse prima di controllare per dolo. Ma non ha funzionato. Qualcuno può aiutare?

risposta

53

Ho avuto lo stesso problema e l'ho risolto utilizzando IntentsTestRule anziché ActivityTestRule. IntentsTestRule è una sottoclasse di ActivityTestRule. Imposta il tuo @Rule che crea l'attività in questo modo:

@Rule 
public IntentsTestRule<MyActivity> mActivity = new IntentsTestRule<MyActivity>(MyActivity.class) { 
    @Override 
    protected Intent getActivityIntent() { 
     ... 
    } 
}; 

Uso IntentsTestRule invece di ActivityTestRule quando si utilizzano Espresso-Intenti. https://google.github.io/android-testing-support-library/docs/espresso/intents/index.html

+0

ya. Perfezionare. Grazie. –

3

Se si utilizza un personalizzato ActivityTestRule, è possibile aggiungere la corretta Intents.init(), Intents.release() chiamate:

@Override 
protected void afterActivityLaunched() { 
    Intents.init(); 
    super.afterActivityLaunched(); 
} 

@Override 
protected void afterActivityFinished() { 
    super.afterActivityFinished(); 
    Intents.release(); 
} 
+0

È preferibile utilizzare ** IntentsTestRule **? –

+1

In realtà è la stessa cosa. Se hai già un ActivityTestRule personalizzato o vuoi abilitare questa funzione dinamicamente, ha senso usare questo approccio, altrimenti usa semplicemente IntentsTestRule. – bonnyz

0

Ho avuto lo stesso problema, però, il passaggio a IntentsTestRule non ha funzionato, anche. Quindi torno a ActivityTestRule e chiama Intents.init() prima e Intents.release() dopo il test che ha inviato l'Intento.

Per ulteriori informazioni, vedere questo reference.