This lesson teaches you to
Try it out
AndroidTestingFun.zip
Functional testing involves verifying that individual application
components work together as expected by the user. For example, you can create a
functional test to verify that an
Activity
correctly
launches a target
Activity
when the user performs a UI
interaction.
To create a functional test for your
Activity
, your test
class should extend
ActivityInstrumentationTestCase2
.
Unlike
ActivityUnitTestCase
,
tests in
ActivityInstrumentationTestCase2
can
communicate with the Android system and send keyboard input and click events to
the UI.
For a complete test case example, take a look at
SenderActivityTest.java
in the sample app.
Add Test Method to Validate Functional Behavior
Your functional testing goals might include:
-
Verifying that a target
Activity
is started when a UI control is pushed in the senderActivity
. -
Verifying that the target
Activity
displays the correct data based on the user's input in the senderActivity
.
You might implement your test method like this:
@MediumTest public void testSendMessageToReceiverActivity() { final Button sendToReceiverButton = (Button) mSenderActivity.findViewById(R.id.send_message_button); final EditText senderMessageEditText = (EditText) mSenderActivity.findViewById(R.id.message_input_edit_text); // Set up an ActivityMonitor ... // Send string input value ... // Validate that ReceiverActivity is started ... // Validate that ReceiverActivity has the correct data ... // Remove the ActivityMonitor ... }
The test waits for an
Activity
that matches this monitor,
otherwise returns null after a timeout elapses. If
ReceiverActivity
was
started, the
ActivityMonitor
that you set
up earlier receives a hit. You can use the assertion methods to verify that
the
ReceiverActivity
is indeed started, and that the hit count on the
ActivityMonitor
incremented
as expected.
Set up an ActivityMonitor
To monitor a single
Activity
in your application, you
can register an
ActivityMonitor
.
The
ActivityMonitor
is
notified by the system whenever an
Activity
that matches your criteria is started.
If a match is found, the monitor’s hit count is updated.
Generally, to use an
ActivityMonitor
, you should:
-
Retrieve the
Instrumentation
instance for your test case by using thegetInstrumentation()
method. -
Add an instance of
Instrumentation.ActivityMonitor
to the current instrumentation using one of theInstrumentation
addMonitor()
methods. The match criteria can be specified as anIntentFilter
or a class name string. -
Wait for the
Activity
to start. - Verify that the monitor hits were incremented.
- Remove the monitor.
For example:
// Set up an ActivityMonitor ActivityMonitor receiverActivityMonitor = getInstrumentation().addMonitor(ReceiverActivity.class.getName(), null, false); // Validate that ReceiverActivity is started TouchUtils.clickView(this, sendToReceiverButton); ReceiverActivity receiverActivity = (ReceiverActivity) receiverActivityMonitor.waitForActivityWithTimeout(TIMEOUT_IN_MS); assertNotNull("ReceiverActivity is null", receiverActivity); assertEquals("Monitor for ReceiverActivity has not been called", 1, receiverActivityMonitor.getHits()); assertEquals("Activity is of wrong type", ReceiverActivity.class, receiverActivity.getClass()); // Remove the ActivityMonitor getInstrumentation().removeMonitor(receiverActivityMonitor);
Send Keyboard Input Using Instrumentation
If your
Activity
has an
EditText
field, you might want to test that users can enter values into the
EditText
object.
Generally, to send a string input value to an
EditText
object in
ActivityInstrumentationTestCase2
, you should:
-
Use the
runOnMainSync()
method to run therequestFocus()
call synchronously in a loop. This way, the UI thread is blocked until focus is received. -
Call
waitForIdleSync()
method to wait for the main thread to become idle (that is, have no more events to process). -
Send a text string to the
EditText
by callingsendStringSync()
and pass your input string as the parameter.
For example:
// Send string input value getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() { senderMessageEditText.requestFocus(); } }); getInstrumentation().waitForIdleSync(); getInstrumentation().sendStringSync("Hello Android!"); getInstrumentation().waitForIdleSync();