Introducing Native Driver
June 22nd, 2011 | Published in Google Open Source, Uncategorized
NativeDriver is an implementation of the WebDriver API which drives the UI of a native application rather than a web application. I am happy to announce that the Android version is available for download and we are welcoming all users and contributors. We are hosting on Google Code (http://nativedriver.googlecode.com/). An iPhone (iOS) version is under development and will be available soon.
WebDriver exposes browser functionality as a clean, object-oriented API, and Google uses WebDriver to test web applications on many platforms. (For an introduction to WebDriver, see this blog post.)
You are probably wondering why anyone would use the WebDriver API to test native applications. Our reasoning is:
- user interactions with a native application and a web application are essentially the same: click, type, switch window, read text
- test writers will have to write the same test for each platform they want to support
- no one wants to learn yet another API
- WebDriver already has a user base and a tool ecosystem that can migrate easily to a new API if it is WebDriver-like
- therefore: let’s re-use our favorite UI testing API
NativeDriver is our attempt to apply WebDriver’s simplicity and success to native applications. It extends the WebDriver API in a few key places, and re-interprets the existing API for native applications.
Here is some code from a NativeDriver test against the Google Maps Android app (the test can be seen in action in this video):
AndroidNativeDriver driver = new AndroidNativeDriverBuilder()
.withDefaultServer()
.build();
driver.startActivity("com.google.android.maps.MapsActivity");
// Open the Places activity by clicking the places button
// (to the right of the search box)
AndroidNativeDriver btn
= driver.findElement(By.id("btn_header_places"));
btn.click();
// Dismiss the Places window
// Equivalent to pressing the Android Back button
driver.navigate().back();
// Rotate the device to show the UI in landscape mode
driver.rotate(ScreenOrientation.LANDSCAPE);
.withDefaultServer()
.build();
driver.startActivity("com.google.android.maps.MapsActivity");
// Open the Places activity by clicking the places button
// (to the right of the search box)
AndroidNativeDriver btn
= driver.findElement(By.id("btn_header_places"));
btn.click();
// Dismiss the Places window
// Equivalent to pressing the Android Back button
driver.navigate().back();
// Rotate the device to show the UI in landscape mode
driver.rotate(ScreenOrientation.LANDSCAPE);
Except for the startActivity method, and the use of a builder object to create the driver, all the API calls made are standard WebDriver API calls. Creating the driver with a builder is necessary because the driver can also be set up with an Android Debug Bridge (ADB) connection.
Android NativeDriver uses Instrumentation to monitor and manipulate the application under test. Instrumentation is a standard feature of Android but it has some limitations. For instance, it cannot drive UI which is part of another process. (If it could a malicious application could hijack the device.) This is where ADB saves the day. The ADB is a connection from outside the device and is not tied to a particular application, so with it we can inject events across applications. ADB also made it possible to add screenshot support, and we plan to utilize it in new ways as NativeDriver matures. This is one way Android NativeDriver tests are more powerful than standard Instrumentation tests.
You can try out Android NativeDriver right away with the tutorials for running a sample test or instrumenting your own application. You may also want to join the users or developers mailing list.
Good luck and happy native testing!
By Matt DeVore, Engineering Productivity Team