blob: 7c8ff1d7bdd7c96892d4f2d0095069b93279d13a [file] [log] [blame]
page.title=Creating Functional Tests
<!-- This is the training bar -->
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you to</h2>
<li><a href="#test_methods">Add Test Method to Validate Functional Behavior</a>
<li><a href="#activitymonitor">Set Up an ActivityMonitor</a></li>
<li><a href="#keyinput">Send Keyboard Input Using Instrumentation</a></li>
<h2>Try it out</h2>
<div class="download-box">
<a href=""
class="button">Download the demo</a>
<p class="filename"></p>
<p>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 {@link} correctly
launches a target {@link} when the user performs a UI
<p>To create a functional test for your {@link}, your test
class should extend {@link android.test.ActivityInstrumentationTestCase2}.
Unlike {@link android.test.ActivityUnitTestCase},
tests in {@link android.test.ActivityInstrumentationTestCase2} can
communicate with the Android system and send keyboard input and click events to
the UI.</p>
<p>For a complete test case example, take a look at
{@code} in the sample app.</p>
<h2 id="test_methods">Add Test Method to Validate Functional Behavior</h2>
<p id="test_goals">Your functional testing goals might include:</p>
<li>Verifying that a target {@link} is started when a
UI control is pushed in the sender {@link}.</li>
<li>Verifying that the target {@link} displays the
correct data based on the user's input in the sender
<p>You might implement your test method like this:</p>
public void testSendMessageToReceiverActivity() {
final Button sendToReceiverButton = (Button)
final EditText senderMessageEditText = (EditText)
// Set up an ActivityMonitor
// Send string input value
// Validate that ReceiverActivity is started
// Validate that ReceiverActivity has the correct data
// Remove the ActivityMonitor
<p>The test waits for an {@link} that matches this monitor,
otherwise returns null after a timeout elapses. If {@code ReceiverActivity} was
started, the {@link ActivityMonitor}
that you set
up earlier receives a hit. You can use the assertion methods to verify that
the {@code ReceiverActivity} is indeed started, and that the hit count on the
{@link ActivityMonitor} incremented
as expected.</p>
<h2 id="activitymonitor">Set up an ActivityMonitor</h2>
<p>To monitor a single {@link} in your application, you
can register an {@link ActivityMonitor}.
The {@link ActivityMonitor} is
notified by the system whenever an {@link} that matches your criteria is started.
If a match is found, the monitor’s hit count is updated.</p>
<p>Generally, to use an
{@link ActivityMonitor}, you should:</p>
<li>Retrieve the {@link} instance for your test
case by using the
{@link android.test.InstrumentationTestCase#getInstrumentation()} method.</li>
<li>Add an instance of {@link} to
the current instrumentation using one of the {@link}
{@code addMonitor()} methods. The match criteria can be specified as an
{@link android.content.IntentFilter} or a class name string.</li>
<li>Wait for the {@link} to start.</li>
<li>Verify that the monitor hits were incremented.</li>
<li>Remove the monitor.</li>
<p>For example:</p>
// Set up an ActivityMonitor
ActivityMonitor receiverActivityMonitor =
null, false);
// Validate that ReceiverActivity is started
TouchUtils.clickView(this, sendToReceiverButton);
ReceiverActivity receiverActivity = (ReceiverActivity)
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
<h2 id="keyinput">Send Keyboard Input Using Instrumentation</h2>
<p>If your {@link} has an {@link android.widget.EditText}
field, you might want to test that users can enter values into the
{@link android.widget.EditText} object.</p>
<p>Generally, to send a string input value to an {@link android.widget.EditText}
object in {@link android.test.ActivityInstrumentationTestCase2}, you should:</p>
<li>Use the {@link runOnMainSync()}
method to run the {@link android.view.View#requestFocus()} call synchronously
in a loop. This way, the UI thread is blocked until focus is received.</li>
<li>Call {@link} method to wait
for the main thread to become idle (that is, have no more events to process).</li>
<li>Send a text string to the {@link android.widget.EditText} by calling
sendStringSync()} and pass your input string as the parameter.</p>
<p>For example:</p>
// Send string input value
getInstrumentation().runOnMainSync(new Runnable() {
public void run() {
getInstrumentation().sendStringSync("Hello Android!");