Android – how to apply Jake Wharton’s robot mode to espresso UI testing?

Jack Wharton delivered a fascinating speech. He proposed some smart ways to improve our UI testing and abstract the details of how we execute UI from testing: https://news.realm.io/news/kau-jake-wharton-testing-robots/

Invalid Sign

@Test public void singleFundingSourceSuccess {
    PaymentRobot payment = new PaymentRobot();
    ResultRobot result = payment
        .amount(42_00)
        .recipient("foo@bar.com")
        .send();
    result.isSuccess();
}

It provides an overview of how to construct a robot class. It uses an explicit issuccess () response to return another robot, which is the next screen or the current state:

class PaymentRobot {
    PaymentRobot amount(long amount) { ... }
    PaymentRobot recipient(String recipient) { .. }
    ResultRobot send() { ... }
}

class ResultRobot { 
    ResultRobot isSuccess() { ... }
}

My question is:

>How does robot interface with activity / fragment? Where is it instantiated? I hope this will happen in the runner's test, but his example seems to imply other aspects. This method seems very useful, but I don't know how to implement it in practice, whether for a single activity / fragment or for their sequence. > how to extend this method so that the issuccess () method can handle various scenarios. For example, if we are testing the login screen, So how does issuccess () handle various expected results, such as authentication success, API network failure and authentication failure (such as 403 server response)? Ideally, the API will be simulated after retrofit, and each result will be tested using end - to - end UI tests

Apart from Jake's overview, I haven't found any implementation examples

@R_ 419_ 1911@:

I have completely misunderstood the working principle of espresso, which makes me more confused about how to apply it to the page object mode. Now I see that espresso does not need to make any type of reference to the activity under test, but only runs in the context of the runner rule. For anyone else struggling, here is a rich example, Apply the robot / page object mode to the authentication test on the login screen, which contains the user name and password fields. We are testing when any field displays an error message empty:

Loginrobot.java (used to abstract the automation of login activities)

public class LoginRobot {

    public LoginRobot() {
        onView(withId(R.id.username)).check(matches(isDisplayed()));
    }

    public void enterUsername(String username) {
        onView(withId(R.id.username)).perform(replaceText(username));
    }

    public void enterPassword(String password) {
        onView(withId(R.id.password)).perform(replaceText(password));
    }

    public void clickLogin() {
        onView(withId(R.id.login_button)).perform(click());
    }

}

(note that the constructor is being tested to ensure that the current screen is what we expect.)

LoginValidationTests.java:

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

    @Rule
    public ActivityTestRule<LoginActivity> mActivityTestRule = new ActivityTestRule<>(LoginActivity.class);

    @Test
    public void loginPasswordValidationtest() {
        LoginRobot loginPage = new LoginRobot();
        loginPage.enterPassword("");
        loginPage.enterUsername("123");
        loginPage.clickLogin();
        onView(withText(R.string.login_bad_password))
 .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)));
    }

    @Test
    public void loginUsernameValidationtest() {
        LoginRobot loginPage = new LoginRobot();
        loginPage.enterUsername("");
        loginPage.enterPassword("123");
        loginPage.clickLogin();
        onView(withText(R.string.login_bad_username)).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)));
    }

}

Abstracting a mechanism to automate the UI like this can avoid a large number of repetitions across tests, which also means that changes are unlikely to be reflected in many tests. For example, if the layout ID changes, only the machine human needs to be updated, rather than each test that references the field. The tests are also significantly shorter and easier to read

Robot methods, such as the login button method, can return to the next robot in the chain (i.e. operate the activity after the login screen). For example, loginrobot. Clicklogin() returns to a homerobot (the main home screen for the application)

I have put assertions in tests, but if assertions are reused in many tests, it may make sense to abstract some assertions into robots

In some cases, it may be meaningful to use the view model object to save a set of pseudo data reused in the test. For example, if the test has the registration screen of many tests with many tests, it may be meaningful to build a factory to create a registrationviewmodel including first name, last name, e-mail address, etc., and refer to it in the test instead of copying that code

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>