Using Screen Robots with Android Espresso Tests
package <your_package>; | |
import android.support.test.espresso.intent.rule.IntentsTestRule; | |
import android.support.test.runner.AndroidJUnit4; | |
import android.test.suitebuilder.annotation.LargeTest; | |
import org.junit.After; | |
import org.junit.Rule; | |
import org.junit.Test; | |
import org.junit.runner.RunWith; | |
import static android.support.test.espresso.intent.Intents.intended; | |
import static android.support.test.espresso.intent.matcher.ComponentNameMatchers.hasShortClassName; | |
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent; | |
import static org.junit.Assert.assertNotNull; | |
@RunWith( AndroidJUnit4.class ) | |
@LargeTest | |
public class BeforeLoginActivityTest { | |
private static final String TEST_EMAIL = "annyce@mycompany.com"; | |
private static final String TEST_PASSWORD = "123456"; | |
private static final String PACKAGE_NAME = "my.package"; | |
@Rule | |
public IntentsTestRule<LoginActivity> activityRule = | |
new IntentsTestRule<>( LoginActivity.class ); | |
@Test | |
public void shouldProceedLoginWhenValid () { | |
onView( withId( R.id.login_username_entry ) ).perform( typeText( TEST_EMAIL ) ); | |
onView( withId( R.id.login_password_entry ) ).perform( typeText( TEST_PASSWORD ) ); | |
onView( withId( R.id.login_button ) ).perform( click() ); | |
intended( hasComponent( hasShortClassName( PACKAGE_NAME ) ) ); | |
} | |
} |
package <your_package>; | |
import android.support.test.espresso.intent.rule.IntentsTestRule; | |
import android.support.test.runner.AndroidJUnit4; | |
import android.test.suitebuilder.annotation.LargeTest; | |
import org.junit.After; | |
import org.junit.Rule; | |
import org.junit.Test; | |
import org.junit.runner.RunWith; | |
import static android.support.test.espresso.intent.Intents.intended; | |
import static android.support.test.espresso.intent.matcher.ComponentNameMatchers.hasShortClassName; | |
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent; | |
import static <your_package>.ScreenRobot.withRobot; | |
import static org.junit.Assert.assertNotNull; | |
@RunWith( AndroidJUnit4.class ) | |
@LargeTest | |
public class LoginActivityTest { | |
private static final String TEST_EMAIL = "annyce@mycompany.com"; | |
private static final String TEST_PASSWORD = "123456"; | |
private static final String PACKAGE_NAME = "my.package"; | |
@Rule | |
public IntentsTestRule<LoginActivity> activityRule = | |
new IntentsTestRule<>( LoginActivity.class ); | |
@Test | |
public void shouldHaveUsernameAndPasswordHeader () { | |
withRobot( LoginScreenRobot.class ) | |
.checkAreHeadersDisplayed(); | |
} | |
@Test | |
public void shouldNotAllowLoginWhenInvalid () { | |
withRobot( LoginScreenRobot.class ) | |
.provideActivityContext( activityRule.getActivity() ) | |
.callLogin( "", "" ) | |
.checkIsInErrorState(); | |
} | |
@Test | |
public void shouldProceedLoginWhenValid () { | |
withRobot( LoginScreenRobot.class ) | |
.callLogin( TEST_EMAIL, TEST_PASSWORD ) | |
.checkIsLoggedIn(); | |
} | |
public static class LoginScreenRobot extends ScreenRobot<LoginScreenRobot> { | |
public LoginScreenRobot checkIsLoggedIn () { | |
intended( hasComponent( hasShortClassName( PACKAGE_NAME ) ) ); | |
return this; | |
} | |
public LoginScreenRobot checkIsInErrorState () { | |
return checkDialogWithTextIsDisplayed( R.string.login_error ); | |
} | |
public LoginScreenRobot checkAreHeadersDisplayed () { | |
return checkIsDisplayed( R.id.login_username_header, R.id.login_password_header ); | |
} | |
public LoginScreenRobot callLogin (String username, String password) { | |
return enterTextIntoView ( R.id.login_username_entry, username ) | |
.enterTextIntoView ( R.id.login_password_entry, password ) | |
.clickOkOnView( R.id.login_button ); | |
} | |
} | |
} |
package <your_package>; | |
import android.app.Activity; | |
import android.support.annotation.IdRes; | |
import android.support.annotation.StringRes; | |
import static android.support.test.espresso.Espresso.onView; | |
import static android.support.test.espresso.action.ViewActions.click; | |
import static android.support.test.espresso.action.ViewActions.swipeLeft; | |
import static android.support.test.espresso.action.ViewActions.typeText; | |
import static android.support.test.espresso.assertion.ViewAssertions.matches; | |
import static android.support.test.espresso.matcher.RootMatchers.withDecorView; | |
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; | |
import static android.support.test.espresso.matcher.ViewMatchers.withHint; | |
import static android.support.test.espresso.matcher.ViewMatchers.withId; | |
import static android.support.test.espresso.matcher.ViewMatchers.withText; | |
import static org.hamcrest.Matchers.not; | |
@SuppressWarnings("unchecked") | |
public abstract class ScreenRobot<T extends ScreenRobot> { | |
private Activity activityContext; // Only required for some calls | |
public static <T extends ScreenRobot> T withRobot (Class<T> screenRobotClass) { | |
if ( screenRobotClass == null ) { | |
throw new IllegalArgumentException( "instance class == null" ); | |
} | |
try { | |
return screenRobotClass.newInstance(); | |
} | |
catch ( IllegalAccessException iae ) { | |
throw new RuntimeException( "IllegalAccessException", iae ); | |
} | |
catch ( InstantiationException ie ) { | |
throw new RuntimeException( "InstantiationException", ie ); | |
} | |
} | |
public T checkIsDisplayed (@IdRes int... viewIds) { | |
for ( int viewId : viewIds ) { | |
onView( withId( viewId ) ).check( matches( isDisplayed() ) ); | |
} | |
return (T) this; | |
} | |
public T checkIsHidden (@IdRes int... viewIds) { | |
for ( int viewId : viewIds ) { | |
onView( withId( viewId ) ).check( matches( not( isDisplayed() ) ) ); | |
} | |
return (T) this; | |
} | |
public T checkViewHasText (@IdRes int viewId, String expected) { | |
onView( withId( viewId ) ).check( matches( withText( expected ) ) ); | |
return (T) this; | |
} | |
public T checkViewHasText (@IdRes int viewId, @StringRes int messageResId) { | |
onView( withId( viewId ) ).check( matches( withText( messageResId ) ) ); | |
return (T) this; | |
} | |
public T checkViewHasHint (@IdRes int viewId, @StringRes int messageResId) { | |
onView( withId( viewId ) ).check( matches( withHint( messageResId ) ) ); | |
return (T) this; | |
} | |
public T clickOkOnView (@IdRes int viewId) { | |
onView( withId( viewId ) ).perform( click() ); | |
return (T) this; | |
} | |
public T enterTextIntoView (@IdRes int viewId, String text) { | |
onView( withId( viewId ) ).perform( typeText( text ) ); | |
return (T) this; | |
} | |
public T provideActivityContext (Activity activityContext) { | |
this.activityContext = activityContext; | |
return (T) this; | |
} | |
public T checkDialogWithTextIsDisplayed (@StringRes int messageResId) { | |
onView( withText( messageResId ) ) | |
.inRoot( withDecorView( not( activityContext.getWindow().getDecorView() ) ) ) | |
.check( matches( isDisplayed() ) ); | |
return (T) this; | |
} | |
public T swipeLeftOnView (@IdRes int viewId) { | |
onView( withId( viewId ) ).perform( swipeLeft() ); | |
return (T) this; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment