Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to run Espresso test with multiple test methods but only one setup method?

I have a simple test today:

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

But for every test method the setActivity is run, which, if you have 10-15 methods, in the end will be time consuming (if you have a lot of views too).

@BeforeClass doesn't seem to work since it has to be static and thus forcing the ActivityTestRule to be static as well.

So is there any other way to do this? Rather than having multiple asserts in the same test method?

like image 476
peuhse Avatar asked May 29 '15 09:05

peuhse


1 Answers

@Before annotation should only precede methods containing preliminary setup. Initialization of needed objects, getting the current session or the current activity, you get the idea.

It is replacing the old setUp() method from the ActivityInstrumentationTestCase2, just as @After replaces the tearDown(). That means that it is intended to be executed before every test in the class and it should stay that way.

You should have no ViewInteraction, no DataInteraction, no Assertions nor View actions in this method, since that is not its purpose.

In your case, simply remove the onView() call from setActivity() and put it inside the actual test methods, in every test method if necessary, like 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()));
    }
}
like image 133
appoll Avatar answered Nov 06 '22 00:11

appoll