in a TextView onView(withId(R.id.etInput)).perform(typeText("Adam")) onView(withId(R.id.tvOutput)).check(matches(withText("Adam"))) @AdamMc331 #DroidconUK 8
onView(REGISTER_INPUT_MATCHER).perform(click()) return UserProfileRobot() } // Unable to run negative tests now @Test fun testMissingEmailError() { RegistrationRobot() .register() .assertEmailError("Must enter an email address.") // Undefined Method } @AdamMc331 #DroidconUK 31
But who tests the tests? class UserProfileRobot { fun assertOptInStatus(optedIn: Boolean) = apply { val optInMatcher = if (optedIn) isChecked() else isNotChecked() onView(EMAIL_OPT_IN_DISPLAY_MATCHER).check(matches(optInMatcher)) } } @AdamMc331 #DroidconUK 32
@Before fun setUp() { // Robot should be specific to each test testRobot = UserViewModelRobot() } @Test fun successfulFetch() { val sampleUser = User("Adam") testRobot .mockUserResponse(sampleUser) .fetchUser() .assertState(NetworkState.Loaded(sampleUser)) } } @AdamMc331 #DroidconUK 38
tests • Take advantage of this pattern to introduce better test reporting • Don't code yourself into a corner with additional complexity @AdamMc331 #DroidconUK 44
tests • Take advantage of this pattern to introduce better test reporting • Don't code yourself into a corner with additional complexity • Don't chain robots @AdamMc331 #DroidconUK 44
tests • Take advantage of this pattern to introduce better test reporting • Don't code yourself into a corner with additional complexity • Don't chain robots • Don't include any logic in the robot methods @AdamMc331 #DroidconUK 44
tests • Take advantage of this pattern to introduce better test reporting • Don't code yourself into a corner with additional complexity • Don't chain robots • Don't include any logic in the robot methods • This concept is not specific to Espresso, or UI testing @AdamMc331 #DroidconUK 44