Nov
27
2012

Introduction to Android App Testing

Testing is the indispensable part of software development so is Android app development. However, it may take some time and it may be tiring to build a software testing infrastructure. Fortunately, Android provides a testing framework infrastructure to test the app in every aspects so we don’t need to deal with testing infrastructure. All we need are to learn the testing framework and to write the test codes.

Most of guys have known the famous JUnit. Yeah, Android test suites are based on JUnit so it is familiar to most of developers who write test codes. In addition, testin framework provides instrumentation. In other words, there is a set control methods in Android system so that you can call lifecycle methods (onCreate, onResume, onPause, etc.) of components explicitly and it gives you to understand how app behaves for certain situations. By the way, SDK provides some other test tools for instance monkeyrunner to send randrom events keystrokes to app for stress testing of the app.

I don’t think we need to study hard the infrastructure literature and let’s move the hands on part.

Creating a Testing Project

First we need to create a testing project which is available in Eclipse File > New > Other… dialog.

Click “Next” and give a name(HelloAndroidTest) to your testing project. After that, we need to choose the project which we write test codes for. Next screenshot shows the available Android projects we can choose in workspace.

Assume that our project, HelloAndroid, we write test codes for a class with a name HelloAndroidActivity and it just sets the content view below. (Basically, this is a traditional HelloAndroid App)

Writing Test Codes 1

We will just write a test code to test if “Hello World, HelloAndroidActivity!” is set correctly to textview. So create a class with name “HelloAndroidTest” whose superclass is ActivityInstrumentationTestCase2 in Android test project we have just created.

There is another important issue that I spent some time in my first try is the constructor. When I use the constructor as told in developer.android.com testing tutorial. It didn’t work for me. The working constructor is like below.

public HelloAndroidTest() {

               super(“com.android.helloAndroid”, HelloAndroidActivity.class);

}

Second parameter is the class we write test codes for in Hello Android project and first parameter is the package where HelloAndroidActivity exists.

Eventually here is the test function…

public void testText() {

mActivity = this.getActivity();

// assume that id of the TexView is textView

mView = (TextView) mActivity.findViewById(com.android.helloAndroid.R.id.textView);

resourceString = mActivity.getString(com.android.helloAndroid.R.string.hello);

              assertEquals(resourceString,(String)mView.getText());

}

Then run the HelloAndroidTest by clicking Run button in Eclipse and run as Android JUnit Test. Now, let me explain the code. As known, all test functions should start with “test” like that. All testing conventions are same as JUnit. The testing function above we first create the activity by calling getActivity() then gettting mView and resourceString by using mActivity and lastly we assert if resourceString and mView.getText() are equal. mActivity’s type is HelloAndroidActivity, mView’s type is TextView

The code above is actually useless but if you know the general convention in testing you can find lots of things to test in your app.

Writing Test Codes 2

Now let’s get our hands a little dirty. Suppose that our simple Android app have a content like below. We just added an EditText.

This EditText has a property which saves its content and restores when app resumes. So let’s test this functionality. Here is the code…

publicvoid testTextRestore () {

// create activity by calling getActivity

mActivity = this.getActivity();

// Changing edit text value

// Changing user interface elements should be in UI Thread.

mActivity.runOnUiThread(new Runnable() {

@Override

                            publicvoid run() {

mActivity.setText(“restore this”);

}

});
// wait to be certain that above code has run

                             try {

Thread.sleep(300);

} catch (InterruptedException e) {

e.printStackTrace();

}

minst = this.getInstrumentation();

// calling activit onPause method by instrumentation

minst.callActivityOnPause(mActivity);

// doing user interface stuff.

mActivity.runOnUiThread(new Runnable() {

@Override

publicvoid run() {

mActivity.setText(“another thing”);

// this should be in UI thread because changes UI elements

minst.callActivityOnResume(mActivity);

}

});

//wait a little

                        try {

Thread.sleep(300);

} catch (InterruptedException e) {

e.printStackTrace();

}

//check “restore this” is equal to edit text value

                     assertEquals(“restore this”, mActivity.getText());

}

I tried to explain the code by writing some comments. If everything goes well, you can see the JUnit view in Eclipse after running codes.

Let me finish by giving a simple tip. When you get “CalledFromWrongThreadException” it means that you try to access UI elements in another thread other than UI Thread so use runOnUIThread function as we did above.

About the Author:

3 Comments + Add Comment

  • Emeğinize sağlık. Bu aralar özellikle ilgilenmeye başladığım bir konuda çok güzel bir başlangıç oldu. Devamı da gelir umarım.

  • How come your UI component is the activity itself instead of the EditText? (from the second example)

    • There is a function with name setText in activity class that changes the EditText’s text. Also you can directly access the edittext. Like below…
      mActivity.mEditText.setText(“….”);

Leave a comment

Partners