Related articles: ►Take Me Home – Project Overview ►CI/CD infrastructure: Choosing and setting up a server with Jenkins as Docker image ►Android SDK and emulator in Docker for testing ►Testing a MongoDB with NodeJS, Mocha and Mongoose
In this article we would like to describe, how to write unit- and gui-tests for an Android-Application in Android Studio and how-to automat these tests on Jenkins.
Tools and frameworks
We used the following tools and frameworks to write and automate our tests:
- Android Studio
To test the basic functionality of your app, the best way is to run a unit-test.
Writing unit-tests with JUnit
We used JUnit to write unit-tests for our application. Tests with JUnit work in Android the same way as in all other Java-applications. In this article, we won´t go to deep into in the details of writing a unit-test in Junit, there are a lot of sources in the internet to consult.
It is very important to place all the test-code in the “test”-folder of your Android Studio-Project, not in the “androidTest”-folder (this folder is later required).
Executing unit-tests in Android Studio
You can start your Unit-Test in Android Studio by selecting the file with the test-code and clicking on the “Run”-button in the menu-bar. As an alternative you can also start all your tests or just one test by clicking on the little triangle next to the beginning of your test(s).
Automating unit-tests in Jenkins
After a successful local test, you can add your tests to your Jenkins-build to run them automatically with every build. To add it to a Jenkins-job you have to add the command “gulp test” to the pipeline-script, which defines your Jenkins job. Further information to automate your tests in Android you can find in the following block-article: Android SDK and emulator in Docker for testing
From now on, the tests will always be executed, when starting the Jenkins-job. You can see the result of the tests in the “testresults”-tab in the job-overview in the Jenkins-AdminUI. Be aware of that the build will fail, if the tests aren´t executed successfully.
Gui-test are a bit more complicated than unit-tests. They test the functionality of the graphical-user interface of an Android-application, but not the exact design of the interface. So, if you want to test for example the exact position of a single element like a button, gui-tests are not the right way to do it. For our test we used the test-framework espresso, which especially build to write gui-tests in Android.
Writing gui-tests with Espresso
To use espresso in your application you first have to add the following imports to your “build.gradle”-file in the “dependencies”-tab:
androidTestCompile 'com.android.support.test.espresso:espresso-core:3.0.1' androidTestCompile 'com.android.support.test:runner:1.0.1'
Then you have to add the next line to the “android.defaultConfig”-tab:
Then you can start writing a gui-test. In this block, we don’t want to go into detail, how to write such a test. Place your tests in the “androidTest”-folder of your project.
So here are the basics:
Defining a test-rule
First you need to instance a @Rule to interact with the Android-activity you want to test. In this example we define a rule for the “MainActivity”:
@Rule public ActivityTestRule<MainActivity> activityRule = new ActivityTestRule<>(MainActivity.class);
To write a gui-test in espresso you can always follow the same way:
Select a gui-element
There are two ways to select an gui-element: onView() or onData().
This function uses ViewMatchers to select a gui-element. Examples for a withId() or withText(). But there is also the possibility to create more complex expressions with allOf() and not().
// element with specific id, here “buttonLogin” onView(withId(R.id.buttonLogin)); // element with specific text, in this case “logout” onView(withText("logout")); // all views with a specific id (“buttonLogin”), but without a specific text (logout) onView(allOf(withId(R.id. buttonLogin), not(withText("logout"))))
This function you can use to get data from an gui-element like a ListView.
// Looking for a specific string (“reading”) in a ListView onData(allOf(is(instanceOf(String.class)), is("reading")));
After selecting an gui-element you can use the function perform() to do something on the selected gui-element. There several actions, you can do like click(), doubleClick(), longClick(). But also interactions like scrollTo() or swipeLeft() are possible. It is also possible to string several commands together, only separated by a “,”.
// Click on an element with a specific id (“buttonLogin”) several times onView(withId(R.id.buttonLogin)).perform(click(), doubleClick(), longClick());
You can also define complete-text input with typeText(“String”) and clear this text later clearText().
// enter text into an element with a specific id (“text_view”) onView(withId(R.id.text_view)).perform(typeText("Hello World"));
Check the results
To verify if your activity works like expected, you can use the function check().For this check you can use classic JUnit-Assertions, or you can use special ViewAssertions like matches or isAbove().
// checks if the element with the specific id (“errorMessage”) is visible onView(withId(R.id.errorMessage)).check((matches(isDisplayed()));
All this information is just a small overview over gui-tests with espresso. You can find more information under the following link: https://developer.android.com/training/testing/espresso/index.html
Executing gui-tests in Android Studio
In contrast to unit-tests with junit, it is a little bit more complicated to execute gui-test for android with espresso. Because gui-tests needs a gui you also need a running gui, on which you can execute your tests. There are two possibilities to achieve this: First you can use your smartphone to run the test. Or you can start an emulator in Android Studio to run the tests. To run a gui-test, you just have to start it by clicking on the “Run”-button in Android Studio. In the next window you could select a device (smartphone or emulator) to run your tests on it.
Automated gui-test in Jenkins
To run the gui-tests in the Jenkins-server automatically you have to ensure, that there is an emulator running a (virtual) gui, which you can test. To get this emulator running, we have a hole blog-post, because it is not that easy. Link to the block-post: Android SDK and emulator in Docker for testing