2015-05-29 10 views
7

Ho un semplice test di oggi:Esiste un modo per eseguire il test Espresso con più metodi di prova ma solo un metodo di installazione?

@RunWith(AndroidJUnit4.class) 
@LargeTest 
public class WhenNavigatingToUsersView { 

    @Rule 
    public ActivityTestRule<MainActivity> mActivityRule = 
     new ActivityTestRule(MainActivity.class); 
    private MainActivity mainActivity; 

    @Before 
    public void setActivity() { 
     mainActivity = mActivityRule.getActivity(); 
     onView(allOf(withId(R.id.icon), hasSibling(withText(R.string.users)))).perform(click()); 
    } 

    @Test 
    public void thenCorrectViewTitleShouldBeShown() { 
     onView(withText("This is the Users Activity.")).check(matches(isDisplayed())); 
    } 

    @Test 
    public void thenCorrectUserShouldBeShown() { 
     onView(withText("Donald Duck (1331)")).check(matches(isDisplayed())); 
    } 
} 

Ma per ogni metodo di prova della setActivity è gestito, che, se si dispone di 10-15 metodi, alla fine sarà in termini di tempo (se si dispone di un sacco di viste anche).

@BeforeClass non sembra funzionare in quanto deve essere statico e quindi forzare lo ActivityTestRule ad essere statico pure.

Quindi c'è un altro modo per farlo? Piuttosto che avere più affermazioni nello stesso metodo di prova?

risposta

3

@Before l'annotazione deve precedere solo i metodi contenenti l'impostazione preliminare. Inizializzazione degli oggetti necessari, acquisizione della sessione corrente o dell'attività corrente, si ottiene l'idea.

Sostituisce il vecchio metodo setUp() da ActivityInstrumentationTestCase2, proprio comesostituisce lo tearDown(). Ciò significa che lo deve essere eseguito prima di ogni test della classe e dovrebbe rimanere in questo modo.

non dovresti avere ViewInteraction, no DataInteraction, nessun AssertionsView azioni in questo metodo, dal momento che non è il suo scopo.

Nel tuo caso, è sufficiente rimuovere la chiamata onView() da setActivity() e metterlo dentro i metodi di prova attuali, in ogni metodo di prova, se necessario, in questo modo:

@RunWith(AndroidJUnit4.class) 
@LargeTest 
public class WhenNavigatingToUsersView { 

    @Rule 
    public ActivityTestRule<MainActivity> mActivityRule = 
     new ActivityTestRule(MainActivity.class); 
    private MainActivity mainActivity; 

    @Before 
    public void setActivity() { 
     mainActivity = mActivityRule.getActivity(); 
     // other required initializations/definitions 
    } 

    @Test 
    public void thenCorrectViewTitleShouldBeShown() { 
     onView(allOf(withId(R.id.icon), hasSibling(withText(R.string.users)))).perform(click()); 
     onView(withText("This is the Users Activity.")).check(matches(isDisplayed())); 
    } 

    @Test 
    public void thenCorrectUserShouldBeShown() { 
     onView(allOf(withId(R.id.icon), hasSibling(withText(R.string.users)))).perform(click()); 
     onView(withText("Donald Duck (1331)")).check(matches(isDisplayed())); 
    } 
} 
+0

Ti manca il mio punto ... C'è un modo per non dover definire l'interazione della vista per ogni metodo di prova? Un buon test unitario per me è che un metodo di test dovrebbe avere solo un assert per test e l'impostazione deve essere fatta in un altro metodo. Considerare che questa vista sarebbe piena di campi che voglio verificare se esistono, sarebbe molto costoso interagire con la vista per ogni test. Quando voglio solo "aprire" quella vista una volta ed eseguire più test. – peuhse

+0

Perché non dovrei visualizzare l'interazione e altre cose in setActivity? Un nome migliore sarebbe setupContext o qualcosa del genere e aggiungere tutti i prerequisiti per il test lì. Questa è l'intenzione della parola chiave @Before in junit ... – peuhse

0

Un'altra opzione per voi sarebbe la separazione di queste prove .

Cliccando sull'icona l'utente sarà nella classe di test HomeActivity mentre il resto delle prove sarà nella classe di test UserActivity.

La classe di test UserActivity avvierà UserActivity con l'Intent appropriato (è possibile farlo passando il falso Boolean nel costruttore Rule e chiamando manualmente launchActivity(intent)).

Ciò eliminerà la necessità di impostare l'attività ogni volta. Si libererà anche dalla costante dipendenza dall'attività principale. Se qualcosa va storto, i test UserActivity saranno intatti e produrranno i risultati, mentre il problema verrà catturato dal test in MainActivity.

In realtà, i test potrebbero diventare di dimensioni medie in quanto il tempo di esecuzione diminuirà drasticamente.

+0

Potrei probabilmente fare qualcosa del genere. Ma UsersActivity non è un'attività, è un frammento. Ho solo un'attività fino ad ora; Attività principale. E tutta la navigazione va a diversi frammenti. – peuhse

0

Si può provare questo:

**** Setting **** 
public void testStory() throws Exception { 

} 

public void testStory2() throws Exception { 

} 

public void testStory3() throws Exception { 

} 

Provare a eseguire il test da questo comando:

./gradlew cC 
0

hai provato a farlo come segue o una variazione minore di in base alle proprie esigenze:

@Rule 
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule(MainActivity.class); 
private MainActivity mainActivity = mActivityRule.getActivity(); 

@BeforeClass 
public static void setActivity() { 
    onView(allOf(withId(R.id.icon), hasSibling(withText(R.string.users)))).perform(click()); 
} 

questo modo, si 'mainActivity' non devono essere statica.Inoltre, il metodo setActivity() verrà chiamato solo una volta.

Problemi correlati