Dienstag, Januar 21, 2020

Gibt es eine Möglichkeit zu laufen, Espresso-test mit mehreren test-Methoden, aber nur eine setup-Methode?

Habe ich einen einfachen test heute:

@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()));
    }
}

Aber für jede test-Methode die setActivity ausgeführt, die, wenn Sie 10-15 Methoden, am Ende wird sehr zeitaufwändig sein, (wenn Sie haben eine Menge von Ansichten zu).

@BeforeClass scheint nicht zu funktionieren, da es zu statisch und so zwingt die ActivityTestRule werden sowohl statische als auch.

Also gibt es irgendeine andere Möglichkeit, dies zu tun? Anstatt mehrere asserts in die gleiche test Methode?

InformationsquelleAutor peuhse | 2015-05-29

4 Kommentare

  1. 4

    @Before annotation soll nur vorangehen Methoden mit vorläufigen setup. Initialisierung der benötigten Objekte, immer in der aktuellen Sitzung oder der aktuellen Aktivität, Sie bekommen die Idee.

    Ablösung der alten setUp() Methode aus der ActivityInstrumentationTestCase2, nur als @After ersetzt die tearDown().
    Das bedeutet, dass es ausgeführt werden soll, vor jedem test in der Klasse und es sollte so bleiben.

    Sollten Sie keine ViewInteraction keine DataInteraction keine Assertions noch View Aktionen, die in dieser Methode, denn das ist nicht sein Zweck.

    In Ihrem Fall, entfernen Sie einfach die onView() Anruf von setActivity() und legte es in die eigentlichen test-Methoden, in jeder test-Methode, wenn es notwendig ist, etwa so:

    @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()));
        }
    }
    • Irgendwie fehlt mein Punkt… gibt es eine Möglichkeit nicht zu haben, um zu definieren, Blick Interaktion für jede test-Methode? Eine gute unit test für mich ist, dass eine test-Methode sollte nur ein assert pro test, und die Einrichtung gemacht werden, die in einer anderen Methode. Betrachten Sie diese Ansicht wäre voll der Felder, die ich will, um zu überprüfen, wenn Sie vorhanden sind, wäre es sehr teuer, um die Interaktion mit den anzeigen, für jeden test. Wenn ich nur wollen „öffnen“, die anzeigen einmal, und führen Sie mehrere tests.
    • Warum sollte ich nicht Blick Interaktion und andere Sachen in setActivity? Ein besserer name wäre setupContext oder etwas, und fügen Sie alle Voraussetzungen, um den test dort. Das ist die Absicht der @Before-Schlüsselwort in junit…
  2. 0

    Eine weitere option für Sie wäre die Trennung dieser tests.

    Klick auf das Benutzer-Symbol in der HomeActivity test-Klasse, während der rest des tests werden in den UserActivity test-Klasse.

    UserActivity test-Klasse starten UserActivity mit der richtigen Absicht ( Sie können dies tun, indem die false-Boolean-in der Regel-Konstruktor, und ruft launchActivity(intent) manuell).

    Dadurch wird verhindert, dass die Notwendigkeit der Einstellung der Tätigkeit jede einzelne Zeit. Es wird auch loswerden ständige Abhängigkeit von der Haupttätigkeit. Wenn etwas schief geht, Ihre UserActivity tests sind intakt und produzieren die Ergebnisse, während das Problem gefangen werden, durch den test in der MainActivity.

    Eigentlich damit, dass Ihre tests werden könnten MediumSize, da die Laufzeit drastisch verringern.

    • Ich könnte wahrscheinlich so etwas wie, dass. Aber UsersActivity ist nicht eine Tätigkeit, es ist ein fragment. Ich habe nur eine Aktivität so weit; MainActivity. Und alle die navigation geht an verschiedene Fragmente.
  3. 0

    Können Sie versuchen, diese :

    **** Setting ****
    public void testStory() throws Exception {
    
    }
    
    public void testStory2() throws Exception {
    
    }
    
    public void testStory3() throws Exception {
    
    }

    Versuchen, führen Sie Ihren test, indem Sie diesen Befehl:

    ./gradlew cC 
  4. 0

    Haben Sie versucht, es zu tun, wie folgt, oder eine kleine Variante davon, um Ihre Bedürfnisse anzupassen:

    @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());
    }

    Diese Weise, Sie ‚mainActivity‘ müssen nicht statisch sein. Auch die setActivity() Methode wird aufgerufen, nur einmal.

Kostenlose Online-Tests