Search code examples
androidandroid-testingui-testingandroid-espressospoon

Spoon and Espresso testing


So, I have a test that goes through my whole application. Now, I want to take a picture of everything. Since it has 2 activities and numerous fragments in it, I can't make it work since it only takes first fragment of every activity.

How can I achieve that I take picture of every fragment?

   @RunWith(AndroidJUnit4.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class HearthBeatUITest {

    private final int MILISECONDS_TIMEOUT = 700;

    @Rule
    public ActivityTestRule<IntroActivity> mActivityRule = new ActivityTestRule<>(IntroActivity.class);
    @Rule
    public ActivityTestRule<LoginActivity> mLoginActivityRule = new ActivityTestRule<>(LoginActivity.class);

    @Test
    /**
     * Testing all the screens on the application if they are actually there
     */
    public void startTest() {
        Session.clear();
        Spoon.screenshot(mActivityRule.getActivity(), "initial_state");
        threadSleep(MILISECONDS_TIMEOUT);
        onView(withId(R.id.button_register)).check(matches(isDisplayed())).perform(click());
        threadSleep(MILISECONDS_TIMEOUT);
        Spoon.screenshot(mLoginActivityRule.getActivity(), "register_intro");
        onView(withId(R.id.register_with_email)).check(matches(isDisplayed())).perform(click());
        threadSleep(MILISECONDS_TIMEOUT);
        Spoon.screenshot(mLoginActivityRule.getActivity(), "register_detailed");
        onView(withId(R.id.image_left_button)).check(matches(isDisplayed())).perform(click());
        threadSleep(MILISECONDS_TIMEOUT);
        Spoon.screenshot(mLoginActivityRule.getActivity(), "register_intro");
        onView(withId(R.id.image_left_button)).check(matches(isDisplayed())).perform(click());
        threadSleep(MILISECONDS_TIMEOUT);
        Spoon.screenshot(mActivityRule.getActivity(), "initial_state");
        onView(withId(R.id.button_signin)).check(matches(isDisplayed())).perform(click());
        threadSleep(MILISECONDS_TIMEOUT);
        Spoon.screenshot(mLoginActivityRule.getActivity(), "login_intro");
        onView(withId(R.id.sign_in_emal)).check(matches(isDisplayed())).perform(click());
        threadSleep(MILISECONDS_TIMEOUT);
        Spoon.screenshot(mLoginActivityRule.getActivity(), "login_detailed");
    }

}

Solution

  • Firstly, you will need only one rule:

    @RunWith(AndroidJUnit4.class)
    @FixMethodOrder(MethodSorters.NAME_ASCENDING)
    public class HearthBeatUITest {
    
        private final int MILISECONDS_TIMEOUT = 300;
        @Rule
        public IntentsTestRule<IntroActivity> mActivityRule = new IntentsTestRule<>(IntroActivity.class);
        private Activity currentActivity;
    }
    

    now, when you need context for creating screenshots, you will call this method:

       private Activity getActivityInstance() {
            getInstrumentation().runOnMainSync(new Runnable() {
                public void run() {
                    Collection resumedActivities = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(RESUMED);
                    if (resumedActivities.iterator().hasNext()) {
                        currentActivity = (Activity) resumedActivities.iterator().next();
                    }
                }
            });
    
            return currentActivity;
        }
    

    It will get you current activity and you will be able to take screenshots. Just fyi, you can't take screenshot of dialogs.