Android UI Test with WebView
Android UI Test
These days, Espresso covers a lot of UI Test features.
And Espresso covers WebView contents assertion with espresso-web.
It’s nice to test WebView base application.
In this entry, I want to explain
Preparation
Before staring, we add some dependencies for espresso and espresso web
build.gradle
android { defaultConfig { testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } packagingOptions { exclude 'META-INF/maven/com.google.guava/guava/pom.properties' exclude 'META-INF/maven/com.google.guava/guava/pom.xml' }
I added testInstrumentationRunner and packagingOptions.
testInstrumentationRunner is for UnitTest annotation.
packagingOptions is to solve build problem.
dependencies { compile 'com.android.support:support-annotations:23.1.1' androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' androidTestCompile 'com.android.support.test:runner:0.5' androidTestCompile 'com.android.support.test:rules:0.5' androidTestCompile 'com.android.support.test.espresso:espresso-web:2.2.2' }
I added above libraries
Now you can resolve dependencies to start Test.
UI Test
Espresso : Google Developer
There are a lot of test methods
WebView Test
Espresso Web covers WebView based application test. You can detect DOM using API.
Documentation : Espresso Web
We can get WebView controller and verify by DOM.
Sample
This example tests small web service.
Press button and open WebView and check contents (This is virtual test and it doesn’t work as it is).
ButtonIdlingResource
This class is helper to wait until button becomes enables.
In this example, button becomes when the service is ready.
public ButtonIdlingResource implements IdlingResource { private ResourceCallback resourceCallback; private Button button; public PortalButtonIdlingResource(PortalButton button) { this.button = button; } @Override public String getName() { return ButtonIdlingResource.class.getName(); } @Override public boolean isIdleNow() { boolean idle = this.button.isEnabled(); if (idle && resourceCallback != null) { resourceCallback.onTransitionToIdle(); } return idle; } @Override public void registerIdleTransitionCallback(ResourceCallback callback) { this.resourceCallback = callback; } }
Test code(ExpressoTest.java)
Steps of this code.
@RunWith(AndroidJUnit4.class) @LargeTest public class EspressoTest { private Activity activity; @Rule public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule(MainActivity.class); @Before public void setUp(){ this.activity = activityTestRule.getActivity(); } @Test public void serviceTest() { Button button = (Button)activity.findViewById(R.id.button1); // Retrieve Button from layout // Wait until the target button becomes enable IdlingResource idlingResource = new PortalButtonIdlingResource(button); Espresso.registerIdlingResources(idlingResource); // Find button and click(you have several choices to find UI from Activity) Espresso.onView(ViewMatchers.withClassName(Matchers.equalToIgnoringCase("android.widget.Button"))).perform(ViewActions.click()); Espresso.unregisterIdlingResources(idlingResource); // If you can click button, new activity is displayed and webview will start loading. Web.onWebView().check(WebViewAssertions.webContent(DomMatchers.containingTextInBody("Android"))); // Check WebView body } }
Now, ready to start test.
The way of running is same as app.
WebView.onWebView().check waits until page is loaded.