This lesson teaches you to
- Create a Test Case for UI Testing with Instrumentation
- Add Test Methods to Verify UI Behavior
- Apply Test Annotations
Try it out
AndroidTestingFun.zip
Typically, your Activity
includes user interface
components (such as buttons, editable text fields, checkboxes, and pickers) to
allow users to interact with your Android application. This lesson shows how
you can test an Activity
with a simple push-button UI. You
can use the same general steps to test other, more sophisticated types of UI
components.
Note: The type of UI testing in this lesson is called white-box testing because you have the source code for the application that you want to test. The Android Instrumentation framework is suitable for creating white-box tests for UI components within an application. An alternative type of UI testing is black-box testing, where you may not have access to the application source. This type of testing is useful when you want to test how your app interacts with other apps or with the system. Black-box testing is not covered in this training. To learn more about how to perform black-box testing on your Android apps, see the UI Testing guide.
For a complete test case example, take a look at
ClickFunActivityTest.java
in the sample app.
Create a Test Case for UI Testing with Instrumentation
When testing an Activity
that has a user interface (UI),
the Activity
under test runs in the UI thread. However, the
test application itself runs in a separate thread in the same process as the
application under test. This means that your test app can reference objects
from the UI thread, but if it attempts to change properties on those objects or
send events to the UI thread, you will usually get a WrongThreadException
error.
To safely inject Intent
objects into your
Activity
or run test methods on the UI thread, you can
extend your test class to use ActivityInstrumentationTestCase2
.
To learn more about how to run test methods on the UI thread, see
Testing
on the UI thread.
Set Up Your Test Fixture
When setting up the test fixture for UI testing, you should specify the
touch mode
in your setUp()
method. Setting the touch mode
to true
prevents the UI control from taking focus when you click it
programmatically in the test method later (for example, a button UI will just
fire its on-click listener). Make sure that you call
setActivityInitialTouchMode()
before calling getActivity()
.
For example:
public class ClickFunActivityTest extends ActivityInstrumentationTestCase2{ ... @Override protected void setUp() throws Exception { super.setUp(); setActivityInitialTouchMode(true); mClickFunActivity = getActivity(); mClickMeButton = (Button) mClickFunActivity .findViewById(R.id.launch_next_activity_button); mInfoTextView = (TextView) mClickFunActivity.findViewById(R.id.info_text_view); } }
Add Test Methods to Validate UI Behavior
Your UI testing goals might include:
- Verifying that a button is displayed with the correct layout when the
Activity
is launched. - Verifying that a
TextView
is initially hidden. - Verifying that a
TextView
displays the expected string when a button is pushed.
The following section demonstrates how you can implement test methods to perform these verifications.
Verify Button Layout Parameters
You might add a test method like this to verify that a button is displayed
correctly in your Activity
:
@MediumTest public void testClickMeButton_layout() { final View decorView = mClickFunActivity.getWindow().getDecorView(); ViewAsserts.assertOnScreen(decorView, mClickMeButton); final ViewGroup.LayoutParams layoutParams = mClickMeButton.getLayoutParams(); assertNotNull(layoutParams); assertEquals(layoutParams.width, WindowManager.LayoutParams.MATCH_PARENT); assertEquals(layoutParams.height, WindowManager.LayoutParams.WRAP_CONTENT); }
In the assertOnScreen()
method call, you should pass in the root view and the view that you are
expecting to be present on the screen. If the expected view is not found in the
root view, the assertion method throws an AssertionFailedError
exception, otherwise the test passes.
You can also verify that the layout of a Button
is
correct by getting a reference to its ViewGroup.LayoutParams
object, then call assertion methods to verify that the
Button
object's width and height attributes match the
expected values.
The @MediumTest
annotation specifies how the test is categorized,
relative to its absolute execution time. To learn more about using test size
annotations, see Apply Test Annotations.
Verify TextView Layout Parameters
You might add a test method like this to verify that a
TextView
initially appears hidden in
your Activity
:
@MediumTest public void testInfoTextView_layout() { final View decorView = mClickFunActivity.getWindow().getDecorView(); ViewAsserts.assertOnScreen(decorView, mInfoTextView); assertTrue(View.GONE == mInfoTextView.getVisibility()); }
You can call getDecorView()
to get a reference
to the decor view for the Activity
. The decor view is the
top-level ViewGroup (FrameLayout
) view in the layout
hierarchy.
Verify Button Behavior
You can use a test method like this to verify that a
TextView
becomes visible when a
Button
is pushed:
@MediumTest public void testClickMeButton_clickButtonAndExpectInfoText() { String expectedInfoText = mClickFunActivity.getString(R.string.info_text); TouchUtils.clickView(this, mClickMeButton); assertTrue(View.VISIBLE == mInfoTextView.getVisibility()); assertEquals(expectedInfoText, mInfoTextView.getText()); }
To programmatically click a Button
in your
test, call clickView()
.
You must pass in a reference to the test case that is being run and a reference
to the Button
to manipulate.
Note: The TouchUtils
helper class provides convenience methods for simulating touch interactions
with your application. You can use these methods to simulate clicking, tapping,
and dragging of Views or the application screen.
Caution: The TouchUtils
methods are designed to send events to the UI thread safely from the test thread.
You should not run TouchUtils
directly in the UI thread or
any test method annotated with @UIThread
. Doing so might
raise the WrongThreadException
.
Apply Test Annotations
The following annotations can be applied to indicate the size of a test method:
@SmallTest
- Marks a test that should run as part of the small tests.
@MediumTest
- Marks a test that should run as part of the medium tests.
@LargeTest
- Marks a test that should run as part of the large tests.
Typically, a short running test that take only a few milliseconds should be
marked as a @SmallTest
. Longer running tests (100 milliseconds or
more) are usually marked as @MediumTest
s or @LargeTest
s,
depending on whether the test accesses resources on the local system only or
remote resources over a network. For guidance on using test size annotations,
see this Android Tools Protip.
You can mark up your test methods with other test annotations to control
how the tests are organized and run. For more information on other annotations,
see the Annotation
class reference.