http://www.developer.com/ws/android/development-tools/getting-started-with-junit-on-android.html

Back to article

Getting Started with JUnit on Android


August 16, 2011

Automated unit testing saves time by performing many tests for you. It can also be used as a quick way to validate new builds-in the form of build acceptance or smoke tests. Finally, unit testing can be an effective way to verify each area of functionality within your application performs as expected across a wide range of devices in a systematic and reproducible fashion. The Android SDK supports JUnit for automated unit tests. This tutorial assumes that you're familiar with Android and JUnit and are using Eclipse.

Creating a JUnit Project for Android

If you already have an Eclipse project for your Android application, that's a good place to start. If you don't already have an Eclipse project, you can create the JUnit project at the same time as you create your Android project.

For an existing Android project, right-click on the project in Eclipse, choose "Android Tools", then "New Testing Project…", as highlighted below:

Creating Android JUnit Project for Existing Project

For a new Android project in Eclipse, on the "New Android Project" dialog, press the "Next" button, highlighted below:

Adding an Android JUnit Test project while creating a new Android project

Regardless of which method you follow, you'll be able to create a new test project for your Android project at this time. The test project creation dialog, shown below, will usually fill in the appropriate details with some standard naming conventions. If not, fill them in yourself and create the project.

Editing the New Android JUnit Test Project Settings

Creating a JUnit Test Case in Android

Android applications are normally comprised of a number of Activity classes. In fact, an activity is a largely independent entity and can be tested and exercised as a cohesive unit. The Android SDK includes several classes to test your Activity classes. We'll use one now.

Right-click on your test project. Choose New, JUnit Test Case:

Creating a New Android JUnit Test Case

Now fill out the New JUnit Test Case dialog with appropriate values. The superclass to use is android.test.ActivityInstrumentTestCase2, where T is the Activity we're going to test.

Creating a New Android JUnit Test Case

Click the Finish button and this new class will be created for you. The default constructor that the wizard creates isn't right just yet. Change it so that it takes no parameters, but calls a different super() method, like so:

public ScreenValidation() { 
   super("com.mamlambo.testingproject.TestingProjectActivity", 
     TestingProjectActivity.class); 
 }

The setUp() method should be used to configure anything needed to run all of the associated tests in this test case. The Activity instance is available at any time by calling the getActivity() method. So, for instance, if we wanted to acquire a handle to a TextView that appears within this Activity class to use in all of our tests, we could implement the setUp() method as follows:

TextView helloText; 
 protected void setUp() throws Exception { 
   super.setUp(); 
   helloText = (TextView) getActivity(). 
      findViewById(R.id.hello_textview); 
 }

Adding a Unit Test to Android

You can craft tests for all sorts of reasons. You have access to all the screen controls on the Activity's layout as well as any code in your app. Since we're using an activity test case, we're probably interested in something to do with the user interface, the Activity's layout, or its functionality. Let's find out if the TextView control fits on the screen.

public void testHelloTextVisibility() { 
   View container = getActivity().findViewById(R.id.container_layout); 
   int boundaryWidth = container.getWidth(); 
   int boundaryHeight = container.getHeight(); 

   int[] location = new int[2]; 
   container.getLocationOnScreen(location); 

   int[] helloTextLocation = new int[2]; 
   helloText.getLocationOnScreen(helloTextLocation); 

   Rect textRect = new Rect(); 
   helloText.getDrawingRect(textRect); 

   boolean widerThanBoundary = (textRect.width() > boundaryWidth); 
   boolean tallerThanBoundary = (textRect.height() > boundaryHeight); 
   boolean extendsOffRight = location[0] + boundaryWidth 
     > helloTextLocation[0] + textRect.width(); 
   assertTrue("Text wider than boundary", widerThanBoundary); 
   assertTrue("Text taller than boundary", tallerThanBoundary); 
   assertTrue("Text goes off right side", extendsOffRight); 

   // ... and so on 
 }

All test methods must start with "test" followed by a descriptive test name. In this case, we've created a test named "Hello Text Visibility." The assertFalse() calls are what determine if the test ultimately passes or fails. (The assertTrue() method can be used as well, for values that must be true to pass.)

Running Android Test Cases with JUnit

To run tests and tests cases you've created, click on the Debug drop down from within Eclipse, choose Debug As, then Android JUnit Test. You can also create an Android JUnit Test configuration to customize these settings, if you prefer.

Our little app passes the "Hello Text Visibility" test with flying colors… when our device is in landscape mode:

Eclipse showing Android JUnit test case pass

...But when in portrait mode, our Activity fails the test:

Eclipse showing Android JUnit Test case failure

Apparently our layout isn't designed to display correctly in portrait mode. (Hint: Perhaps this has something to do with setting the width to more pixels than the phone has rather than using a more appropriate unit like dp or just match_parent.)

You should run your tests on all target devices and configurations you expect to support. Our simple unit test example has more overhead per test than you'd normally find. If your test takes a long time to run, you may want to set up several to run in parallel.

Android App Quality Only As Good As the Unit Tests

Care must be taken when creating unit tests. If a test passes but isn't testing for the correct values and behaviors, that won't produce any sort of useful results. In fact, it can be dangerous as it might mask problems. The development of test cases is just as important as the development of the code itself. The primary way to test the test cases is by doing careful code reviews and make sure they're testing what you think they are.

It's also not particularly useful to your app to test Android (or Java) framework functionality. For example, performing a test where you set the text value on a field and then read it back to see if it's the same. If the test is being performed on a regular TextView, the test won't be particularly meaningful (unless you're implementing the SDK on a new device). However, if you've creating your own implementation of TextView, by all means--test it. In other words, testing tautologies isn't a very good use of time and resources.

That's not to say that any code base is bug free, but testing things that are equivalent to testing if one equals one isn't worth the effort to write the test to begin with. If that fails, you've got bigger problems than your app. There's also a subtle difference between testing the SDK and testing that we're using the SDK correctly (in the above example, we weren't).

Therefore, if you're new to automated unit testing in general, we recommend you do some research into the subject. A good place to start is JUnit.org.

Conclusion

In this tutorial, you've learned how to quickly add a new test project to your Android project in Eclipse in order to perform automated tests on your application using JUnit. Unit testing allows for logical testing, functional testing, and even user interface testing and validation. No longer are you forced to manually test your mobile applications exclusively. Including automated unit testing suites as part of your test plan has several big benefits: it can save time, money and resources as well as provide a set of reliable, reproducible tests that can be run across many different device configurations.

About the Authors

Shane Conder Shane Conder and Lauren Darcey--Contributing Editors, Mobile Development--have coauthored two books on Android development: an in-depth programming book entitled Android Wireless Application Development (ISBN-13: 978-0-321-62709-4) and Sams Teach Yourself Android Application Development in 24 Hours (ISBN-13: 978-0-321-67335-0). When not writing, they spend their time developing mobile software at their company and providing consulting services.

Email        |        Blog        |        Twitter

Lauren Darcey

Sitemap | Contact Us