am 40765a4a: am 2ef3952d: cherrypick from jb-mr2-docs docs: Android training for Activity testing. Change-Id: I7167732c849d5a4a36c808cc852ddfcdc8e60bd7
* commit '40765a4a5300914e8c7ce7ed6397cec7ab8d78a1': cherrypick from jb-mr2-docs docs: Android training for Activity testing. Change-Id: I7167732c849d5a4a36c808cc852ddfcdc8e60bd7
This commit is contained in:
BIN
docs/downloads/training/AndroidTestingFun.zip
Normal file
BIN
docs/downloads/training/AndroidTestingFun.zip
Normal file
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
227
docs/html/training/activity-testing/activity-basic-testing.jd
Normal file
227
docs/html/training/activity-testing/activity-basic-testing.jd
Normal file
@@ -0,0 +1,227 @@
|
||||
page.title=Creating and Running a Test Case
|
||||
trainingnavtop=true
|
||||
|
||||
@jd:body
|
||||
|
||||
<!-- This is the training bar -->
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<h2>This lesson teaches you to</h2>
|
||||
<ol>
|
||||
<li><a href="#testcase">Create a Test Case for Activity Testing</a>
|
||||
<ol>
|
||||
<li><a href="#fixture">Set Up Your Test Fixture</a></li>
|
||||
<li><a href="#preconditions">Add Test Preconditions</a></li>
|
||||
<li><a href="#test_method">Add Test Methods to Verify Your Activity</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#build_run">Build and Run Your Test</a></li>
|
||||
</ol>
|
||||
|
||||
<h2>You should also read</h2>
|
||||
<ul>
|
||||
<li><a href="{@docRoot}tools/testing/testing_android.html">Testing
|
||||
Fundamentals</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<p>In order to verify that there are no regressions in the layout design and
|
||||
functional behavior in your application, it's important to
|
||||
create a test for each {@link android.app.Activity} in your application. For
|
||||
each test, you need to create the individual parts of a test case, including
|
||||
the test fixture, preconditions test method, and {@link android.app.Activity}
|
||||
test methods. You can then run your test to get a test report. If any test
|
||||
method fails, this might indicate a potential defect in your code.</p>
|
||||
<p class="note"><strong>Note:</strong> In the Test-Driven Development (TDD)
|
||||
approach, instead of writing most or all of your app code up-front and then
|
||||
running tests later in the development cycle, you would progressively write
|
||||
just enough production code to satisfy your test dependencies, update your
|
||||
test cases to reflect new functional requirements, and iterate repeatedly this
|
||||
way.</p>
|
||||
|
||||
<h2 id="testcase">Create a Test Case</h2>
|
||||
<p>{@link android.app.Activity} tests are written in a structured way.
|
||||
Make sure to put your tests in a separate package, distinct from the code under
|
||||
test.</p>
|
||||
<p>By convention, your test package name should follow the same name as the
|
||||
application package, suffixed with <strong>".tests"</strong>. In the test package
|
||||
you created, add the Java class for your test case. By convention, your test case
|
||||
name should also follow the same name as the Java or Android class that you
|
||||
want to test, but suffixed with <strong>“Test”</strong>.</p>
|
||||
<p>To create a new test case in Eclipse:</p>
|
||||
<ol type="a">
|
||||
<li>In the Package Explorer, right-click on the {@code /src} directory for
|
||||
your test project and select <strong>New > Package</strong>.</li>
|
||||
<li>Set the <strong>Name</strong> field to
|
||||
{@code <your_app_package_name>.tests} (for example,
|
||||
{@code com.example.android.testingfun.tests}) and click
|
||||
<strong>Finish</strong>.</li>
|
||||
<li>Right-click on the test package you created, and select
|
||||
<strong>New > Class</strong>.</li>
|
||||
<li>Set the <strong>Name</strong> field to
|
||||
{@code <your_app_activity_name>Test} (for example,
|
||||
{@code MyFirstTestActivityTest}) and click <strong>Finish</strong>.</li>
|
||||
</ol>
|
||||
|
||||
<h3 id="fixture">Set Up Your Test Fixture</h3>
|
||||
<p>A <em>test fixture</em> consists of objects that must be initialized for
|
||||
running one or more tests. To set up the test fixture, you can override the
|
||||
{@link junit.framework.TestCase#setUp()} and
|
||||
{@link junit.framework.TestCase#tearDown()} methods in your test. The
|
||||
test runner automatically runs {@link junit.framework.TestCase#setUp()} before
|
||||
running any other test methods, and {@link junit.framework.TestCase#tearDown()}
|
||||
at the end of each test method execution. You can use these methods to keep
|
||||
the code for test initialization and clean up separate from the tests methods.
|
||||
</p>
|
||||
<p>To set up your test fixture in Eclipse:</p>
|
||||
<ol>
|
||||
<li>In the Package Explorer, double-click on the test case that you created
|
||||
earlier to bring up the Eclipse Java editor, then modify your test case class
|
||||
to extend one of the sub-classes of {@link android.test.ActivityTestCase}.
|
||||
<p>For example:</p>
|
||||
<pre>
|
||||
public class MyFirstTestActivityTest
|
||||
extends ActivityInstrumentationTestCase2<MyFirstTestActivity> {
|
||||
</pre>
|
||||
</li>
|
||||
<li>Next, add the constructor and {@link junit.framework.TestCase#setUp()}
|
||||
methods to your test case, and add variable declarations for the
|
||||
{@link android.app.Activity} that you want to test.</p>
|
||||
<p>For example:</p>
|
||||
<pre>
|
||||
public class MyFirstTestActivityTest
|
||||
extends ActivityInstrumentationTestCase2<MyFirstTestActivity> {
|
||||
|
||||
private MyFirstTestActivity mFirstTestActivity;
|
||||
private TextView mFirstTestText;
|
||||
|
||||
public MyFirstTestActivityTest() {
|
||||
super(MyFirstTestActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mFirstTestActivity = getActivity();
|
||||
mFirstTestText =
|
||||
(TextView) mFirstTestActivity
|
||||
.findViewById(R.id.my_first_test_text_view);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
<p>The constructor is invoked by the test runner to instantiate the test
|
||||
class, while the {@link junit.framework.TestCase#setUp()} method is invoked by
|
||||
the test runner before it runs any tests in the test class.</p>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>Typically, in the {@link junit.framework.TestCase#setUp()} method, you
|
||||
should:</p>
|
||||
<ul>
|
||||
<li>Invoke the superclass constructor for
|
||||
{@link junit.framework.TestCase#setUp()}, which is required by JUnit.</li>
|
||||
<li>Initialize your test fixture state by:
|
||||
<ul>
|
||||
<li>Defining the instance variables that store the state of the fixture.</li>
|
||||
<li>Creating and storing a reference to an instance of the
|
||||
{@link android.app.Activity} under test.</li>
|
||||
<li>Obtaining a reference to any UI components in the
|
||||
{@link android.app.Activity} that you want to test.</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<p>You can use the
|
||||
{@link android.test.ActivityInstrumentationTestCase2#getActivity()} method to
|
||||
get a reference to the {@link android.app.Activity} under test.</p>
|
||||
|
||||
<h3 id="preconditions">Add Test Preconditions</h3>
|
||||
<p>As a sanity check, it is good practice to verify that the test fixture has
|
||||
been set up correctly, and the objects that you want to test have been correctly
|
||||
instantiated or initialized. That way, you won’t have to see
|
||||
tests failing because something was wrong with the setup of your test fixture.
|
||||
By convention, the method for verifying your test fixture is called
|
||||
{@code testPreconditions()}.</p>
|
||||
|
||||
<p>For example, you might want to add a {@code testPreconditons()} method like
|
||||
this to your test case:</p>
|
||||
|
||||
<pre>
|
||||
public void testPreconditions() {
|
||||
assertNotNull(“mFirstTestActivity is null”, mFirstTestActivity);
|
||||
assertNotNull(“mFirstTestText is null”, mFirstTestText);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>The assertion methods are from the JUnit {@link junit.framework.Assert}
|
||||
class. Generally, you can use assertions to
|
||||
verify if a specific condition that you want to test is true.
|
||||
<ul>
|
||||
<li>If the condition is false, the assertion method throws an
|
||||
{@link android.test.AssertionFailedError} exception, which is then typically
|
||||
reported by the test runner. You can provide a string in the first argument of
|
||||
your assertion method to give some contextual details if the assertion fails.</li>
|
||||
<li>If the condition is true, the test passes.</li>
|
||||
</ul>
|
||||
<p>In both cases, the test runner proceeds to run the other test methods in the
|
||||
test case.</p>
|
||||
|
||||
<h3 id="test_method">Add Test Methods to Verify Your Activity</h3>
|
||||
<p>Next, add one or more test methods to verify the layout and functional
|
||||
behavior of your {@link android.app.Activity}.</p>
|
||||
<p>For example, if your {@link android.app.Activity} includes a
|
||||
{@link android.widget.TextView}, you can add a test method like this to check
|
||||
that it has the correct label text:</p>
|
||||
<pre>
|
||||
public void testMyFirstTestTextView_labelText() {
|
||||
final String expected =
|
||||
mFirstTestActivity.getString(R.string.my_first_test);
|
||||
final String actual = mFirstTestText.getText().toString();
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>The {@code testMyFirstTestTextView_labelText()} method simply checks that the
|
||||
default text of the {@link android.widget.TextView} that is set by the layout
|
||||
is the same as the expected text defined in the {@code strings.xml} resource.</p>
|
||||
<p class="note"><strong>Note:</strong> When naming test methods, you can use
|
||||
an underscore to separate what is being tested from the specific case being
|
||||
tested. This style makes it easier to see exactly what cases are being tested.</p>
|
||||
<p>When doing this type of string value comparison, it’s good practice to read
|
||||
the expected string from your resources, instead of hardcoding the string in
|
||||
your comparison code. This prevents your test from easily breaking whenever the
|
||||
string definitions are modified in the resource file.</p>
|
||||
<p>To perform the comparison, pass both the expected and actual strings as
|
||||
arguments to the
|
||||
{@link junit.framework.Assert#assertEquals(java.lang.String, java.lang.String) assertEquals()}
|
||||
method. If the values are not the same, the assertion will throw an
|
||||
{@link junit.framework.AssertionFailedError} exception.</p>
|
||||
<p>If you added a {@code testPreconditions()} method, put your test methods
|
||||
after the {@code testPreconditions()} definition in your Java class.</p>
|
||||
<p>For a complete test case example, take a look at
|
||||
{@code MyFirstTestActivityTest.java} in the sample app.</p>
|
||||
|
||||
<h2 id="build_run">Build and Run Your Test</h2>
|
||||
<p>You can build and run your test easily from the Package Explorer in
|
||||
Eclipse.</p>
|
||||
<p>To build and run your test:</p>
|
||||
<ol>
|
||||
<li>Connect an Android device to your machine. On the device or emulator, open
|
||||
the <strong>Settings</strong> menu, select <strong>Developer options</strong>
|
||||
and make sure that USB debugging is enabled.</li>
|
||||
<li>In the Project Explorer, right-click on the test class that you created
|
||||
earlier and select <strong>Run As > Android Junit Test</strong>.</li>
|
||||
<li>In the Android Device Chooser dialog, select the device that you just
|
||||
connected, then click <strong>OK</strong>.</li>
|
||||
<li>In the JUnit view, verify that the test passes with no errors or failures.</li>
|
||||
</ol>
|
||||
<p>For example, if the test case passes with no errors, the result should look
|
||||
like this:</p>
|
||||
<img src="{@docRoot}images/training/activity-testing_lesson2_MyFirstTestActivityTest_result.png" alt="" />
|
||||
<p class="img-caption">
|
||||
<strong>Figure 1.</strong> Result of a test with no errors.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
page.title=Creating Functional Tests
|
||||
trainingnavtop=true
|
||||
@jd:body
|
||||
|
||||
<!-- This is the training bar -->
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<h2>This lesson teaches you to</h2>
|
||||
<ol>
|
||||
<li><a href="#test_methods">Add Test Method to Validate Functional Behavior</a>
|
||||
<ol>
|
||||
<li><a href="#activitymonitor">Set Up an ActivityMonitor</a></li>
|
||||
<li><a href="#keyinput">Send Keyboard Input Using Instrumentation</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<h2>Try it out</h2>
|
||||
<div class="download-box">
|
||||
<a href="http://developer.android.com/shareables/training/AndroidTestingFun.zip"
|
||||
class="button">Download the demo</a>
|
||||
<p class="filename">AndroidTestingFun.zip</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<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 android.app.Activity} correctly
|
||||
launches a target {@link android.app.Activity} when the user performs a UI
|
||||
interaction.</p>
|
||||
|
||||
<p>To create a functional test for your {@link android.app.Activity}, 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 SenderActivityTest.java} 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>
|
||||
<ul>
|
||||
<li>Verifying that a target {@link android.app.Activity} is started when a
|
||||
UI control is pushed in the sender {@link android.app.Activity}.</li>
|
||||
<li>Verifying that the target {@link android.app.Activity} displays the
|
||||
correct data based on the user's input in the sender
|
||||
{@link android.app.Activity}.</li>
|
||||
</ul>
|
||||
<p>You might implement your test method like this:</p>
|
||||
|
||||
<pre>
|
||||
@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
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
<p>The test waits for an {@link android.app.Activity} that matches this monitor,
|
||||
otherwise returns null after a timeout elapses. If {@code ReceiverActivity} was
|
||||
started, the {@link android.app.Instrumentation.ActivityMonitor 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 android.app.Instrumentation.ActivityMonitor ActivityMonitor} incremented
|
||||
as expected.</p>
|
||||
|
||||
<h2 id="activitymonitor">Set up an ActivityMonitor</h2>
|
||||
<p>To monitor a single {@link android.app.Activity} in your application, you
|
||||
can register an {@link android.app.Instrumentation.ActivityMonitor ActivityMonitor}.
|
||||
The {@link android.app.Instrumentation.ActivityMonitor ActivityMonitor} is
|
||||
notified by the system whenever an {@link android.app.Activity} 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 android.app.Instrumentation.ActivityMonitor ActivityMonitor}, you should:</p>
|
||||
<ol>
|
||||
<li>Retrieve the {@link android.app.Instrumentation} instance for your test
|
||||
case by using the
|
||||
{@link android.test.InstrumentationTestCase#getInstrumentation()} method.</li>
|
||||
<li>Add an instance of {@link android.app.Instrumentation.ActivityMonitor} to
|
||||
the current instrumentation using one of the {@link android.app.Instrumentation}
|
||||
{@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 android.app.Activity} to start.</li>
|
||||
<li>Verify that the monitor hits were incremented.</li>
|
||||
<li>Remove the monitor.</li>
|
||||
</ol>
|
||||
<p>For example:</p>
|
||||
<pre>
|
||||
// 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);
|
||||
</pre>
|
||||
|
||||
<h2 id="keyinput">Send Keyboard Input Using Instrumentation</h2>
|
||||
<p>If your {@link android.app.Activity} 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>
|
||||
<ol>
|
||||
<li>Use the {@link android.app.Instrumentation#runOnMainSync(java.lang.Runnable) 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 android.app.Instrumentation#waitForIdleSync()} 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
|
||||
{@link android.app.Instrumentation#sendStringSync(java.lang.String)
|
||||
sendStringSync()} and pass your input string as the parameter.</p>
|
||||
</ol>
|
||||
<p>For example:</p>
|
||||
<pre>
|
||||
// Send string input value
|
||||
getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
senderMessageEditText.requestFocus();
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
getInstrumentation().sendStringSync("Hello Android!");
|
||||
getInstrumentation().waitForIdleSync();
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
216
docs/html/training/activity-testing/activity-ui-testing.jd
Normal file
216
docs/html/training/activity-testing/activity-ui-testing.jd
Normal file
@@ -0,0 +1,216 @@
|
||||
page.title=Testing UI Components
|
||||
trainingnavtop=true
|
||||
|
||||
@jd:body
|
||||
|
||||
<!-- This is the training bar -->
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<h2>This lesson teaches you to</h2>
|
||||
<ol>
|
||||
<li><a href="#testcase">Create a Test Case for UI Testing with Instrumentation</a>
|
||||
<li><a href="#test_method">Add Test Methods to Verify UI Behavior</a>
|
||||
<ol>
|
||||
<li><a href="#verify_button_display">Verify Button Layout Parameters</a></li>
|
||||
<li><a href="#verify_TextView">Verify TextView Layout Parameters</a></li>
|
||||
<li><a href="#verify_button_behavior">Verify Button Behavior</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#annotations">Apply Test Annotations</a></li>
|
||||
</ol>
|
||||
|
||||
<h2>Try it out</h2>
|
||||
<div class="download-box">
|
||||
<a href="http://developer.android.com/shareables/training/AndroidTestingFun.zip"
|
||||
class="button">Download the demo</a>
|
||||
<p class="filename">AndroidTestingFun.zip</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>Typically, your {@link android.app.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 {@link android.app.Activity} with a simple push-button UI. You
|
||||
can use the same general steps to test other, more sophisticated types of UI
|
||||
components.</p>
|
||||
|
||||
<p class="note"><strong>Note:</strong> The type of UI testing in this lesson is
|
||||
called <em>white-box testing</em> because you have the
|
||||
source code for the application that you want to test. The Android
|
||||
<a href="{@docRoot}tools/testing/testing_android.html#Instrumentation">Instrumentation</a>
|
||||
framework is suitable for creating white-box tests for UI components within an
|
||||
application. An alternative type of UI testing is <em>black-box testing</em>,
|
||||
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
|
||||
<a href="{@docRoot}tools/testing/testing_ui.html">UI Testing guide</a>.
|
||||
<p>For a complete test case example, take a look at
|
||||
{@code ClickFunActivityTest.java} in the sample app.</p>
|
||||
|
||||
<h2 id="testcase">Create a Test Case for UI Testing with Instrumentation</h2>
|
||||
<p>When testing an {@link android.app.Activity} that has a user interface (UI),
|
||||
the {@link android.app.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 {@code WrongThreadException}
|
||||
error.</p>
|
||||
<p>To safely inject {@link android.content.Intent} objects into your
|
||||
{@link android.app.Activity} or run test methods on the UI thread, you can
|
||||
extend your test class to use {@link android.test.ActivityInstrumentationTestCase2}.
|
||||
To learn more about how to run test methods on the UI thread, see
|
||||
<a href="{@docRoot}tools/testing/activity_testing.html#RunOnUIThread">Testing
|
||||
on the UI thread</a>.</p>
|
||||
|
||||
<h3 id="fixture">Set Up Your Test Fixture</h3>
|
||||
<p>When setting up the test fixture for UI testing, you should specify the
|
||||
<a href="{@docRoot}guide/topics/ui/ui-events.html#TouchMode">touch mode</a>
|
||||
in your {@link junit.framework.TestCase#setUp()} method. Setting the touch mode
|
||||
to {@code 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
|
||||
{@link android.test.ActivityInstrumentationTestCase2#setActivityInitialTouchMode(boolean) setActivityInitialTouchMode()}
|
||||
before calling {@link android.test.ActivityInstrumentationTestCase2#getActivity()}.
|
||||
</p>
|
||||
<p>For example:</ap>
|
||||
<pre>
|
||||
public class ClickFunActivityTest
|
||||
extends ActivityInstrumentationTestCase2<ClickFunActivity> {
|
||||
...
|
||||
@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);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h2 id="test_methods">Add Test Methods to Validate UI Behavior</h2>
|
||||
<p id="test_goals">Your UI testing goals might include:</p>
|
||||
<ul>
|
||||
<li>Verifying that a button is displayed with the correct layout when the
|
||||
{@link android.app.Activity} is launched.</li>
|
||||
<li>Verifying that a {@link android.widget.TextView} is initially hidden.</li>
|
||||
<li>Verifying that a {@link android.widget.TextView} displays the expected string
|
||||
when a button is pushed.</li>
|
||||
</ul>
|
||||
<p>The following section demonstrates how you can implement test methods
|
||||
to perform these verifications.</p>
|
||||
|
||||
<h3 id="verify_button_display">Verify Button Layout Parameters</h3>
|
||||
<p>You might add a test method like this to verify that a button is displayed
|
||||
correctly in your {@link android.app.Activity}:</p>
|
||||
<pre>
|
||||
@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);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>In the {@link android.test.ViewAsserts#assertOnScreen(android.view.View,android.view.View) 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 {@link junit.framework.AssertionFailedError}
|
||||
exception, otherwise the test passes.</p>
|
||||
<p>You can also verify that the layout of a {@link android.widget.Button} is
|
||||
correct by getting a reference to its {@link android.view.ViewGroup.LayoutParams}
|
||||
object, then call assertion methods to verify that the
|
||||
{@link android.widget.Button} object's width and height attributes match the
|
||||
expected values.</p>
|
||||
<p>The {@code @MediumTest} annotation specifies how the test is categorized,
|
||||
relative to its absolute execution time. To learn more about using test size
|
||||
annotations, see <a href="#annotations">Apply Test Annotations</a>.</p>
|
||||
|
||||
<h3 id="verify_TextView">Verify TextView Layout Parameters</h3>
|
||||
<p>You might add a test method like this to verify that a
|
||||
{@link android.widget.TextView} initially appears hidden in
|
||||
your {@link android.app.Activity}:</p>
|
||||
<pre>
|
||||
@MediumTest
|
||||
public void testInfoTextView_layout() {
|
||||
final View decorView = mClickFunActivity.getWindow().getDecorView();
|
||||
ViewAsserts.assertOnScreen(decorView, mInfoTextView);
|
||||
assertTrue(View.GONE == mInfoTextView.getVisibility());
|
||||
}
|
||||
</pre>
|
||||
<p>You can call {@link android.view.Window#getDecorView()} to get a reference
|
||||
to the decor view for the {@link android.app.Activity}. The decor view is the
|
||||
top-level ViewGroup ({@link android.widget.FrameLayout}) view in the layout
|
||||
hierarchy.</p>
|
||||
|
||||
<h3 id="verify_button_behavior">Verify Button Behavior</h3>
|
||||
<p>You can use a test method like this to verify that a
|
||||
{@link android.widget.TextView} becomes visible when a
|
||||
{@link android.widget.Button} is pushed:</p>
|
||||
|
||||
<pre>
|
||||
@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());
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>To programmatically click a {@link android.widget.Button} in your
|
||||
test, call {@link android.test.TouchUtils#clickView(android.test.InstrumentationTestCase,android.view.View) clickView()}.
|
||||
You must pass in a reference to the test case that is being run and a reference
|
||||
to the {@link android.widget.Button} to manipulate.</p>
|
||||
|
||||
<p class="note"><strong>Note: </strong>The {@link android.test.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.</p>
|
||||
<p class="caution"><strong>Caution: </strong>The {@link android.test.TouchUtils}
|
||||
methods are designed to send events to the UI thread safely from the test thread.
|
||||
You should not run {@link android.test.TouchUtils} directly in the UI thread or
|
||||
any test method annotated with {@code @UIThread}. Doing so might
|
||||
raise the {@code WrongThreadException}.</p>
|
||||
|
||||
<h2 id="annotations">Apply Test Annotations</h2>
|
||||
<p>The following annotations can be applied to indicate the size of a test
|
||||
method:</p>
|
||||
<dl>
|
||||
<dt>{@link
|
||||
android.test.suitebuilder.annotation.SmallTest @SmallTest}</dt>
|
||||
<dd>Marks a test that should run as part of the small tests.</dd>
|
||||
<dt>{@link
|
||||
android.test.suitebuilder.annotation.MediumTest @MediumTest}</dt>
|
||||
<dd>Marks a test that should run as part of the medium tests.</dd>
|
||||
<dt>{@link android.test.suitebuilder.annotation.LargeTest @LargeTest}</dt>
|
||||
<dd>Marks a test that should run as part of the large tests.</dd>
|
||||
</dl>
|
||||
<p>Typically, a short running test that take only a few milliseconds should be
|
||||
marked as a {@code @SmallTest}. Longer running tests (100 milliseconds or
|
||||
more) are usually marked as {@code @MediumTest}s or {@code @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 <a href="https://plus.sandbox.google.com/+AndroidDevelopers/posts/TPy1EeSaSg8">Android Tools Protip</a>.</p>
|
||||
<p>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 {@link java.lang.annotation.Annotation} class reference.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
134
docs/html/training/activity-testing/activity-unit-testing.jd
Normal file
134
docs/html/training/activity-testing/activity-unit-testing.jd
Normal file
@@ -0,0 +1,134 @@
|
||||
page.title=Creating Unit Tests
|
||||
trainingnavtop=true
|
||||
@jd:body
|
||||
|
||||
<!-- This is the training bar -->
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<h2>This lesson teaches you to</h2>
|
||||
<ol>
|
||||
<li><a href="#testcase">Create a Test Case for Activity Unit Testing</a>
|
||||
<li><a href="#test_method">Validate Launch of Another Activity</a>
|
||||
</ol>
|
||||
|
||||
<h2>Try it out</h2>
|
||||
<div class="download-box">
|
||||
<a href="http://developer.android.com/shareables/training/AndroidTestingFun.zip"
|
||||
class="button">Download the demo</a>
|
||||
<p class="filename">AndroidTestingFun.zip</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>An {@link android.app.Activity} unit test is an excellent way to quickly
|
||||
verify the state of an {@link android.app.Activity} and its interactions with
|
||||
other components in isolation (that is, disconnected from the rest of the
|
||||
system). A unit test generally tests the smallest possible unit of code
|
||||
(which could be a method, class, or component), without dependencies on system
|
||||
or network resources. For example, you can write a unit test to check
|
||||
that an {@link android.app.Activity} has the correct layout or that it
|
||||
triggers an {@link android.content.Intent} object correctly.</p>
|
||||
<p>Unit tests are generally not suitable for testing complex UI interaction
|
||||
events with the system. Instead, you should use
|
||||
the {@link android.test.ActivityInstrumentationTestCase2} class, as described
|
||||
in <a href="activity-ui-testing.html">Testing UI Components</a>.</p>
|
||||
<p>This lesson shows how you can write a unit test to verify that an
|
||||
{@link android.content.Intent} is triggered to launch another
|
||||
{@link android.app.Activity}.
|
||||
Since the test runs in an isolated environment, the
|
||||
{@link android.content.Intent}
|
||||
is not actually sent to the Android system, but you can inspect that the
|
||||
{@link android.content.Intent} object's payload data is accurate.</p>
|
||||
<p>For a complete test case example, take a look at
|
||||
{@code LaunchActivityTest.java} in the sample app.</p>
|
||||
|
||||
<p class="note"><strong>Note: </strong>To test against system or external
|
||||
dependencies, you can use mock objects from a mocking
|
||||
framework and inject them into your unit tests. To learn more about the mocking
|
||||
framework provided by Android, see
|
||||
<a href="{@docRoot}tools/testing/testing_android.html#MockObjectClasses}">Mock
|
||||
Object Classes</a>.</p>
|
||||
|
||||
<h2 id="testcase">Create a Test Case for Activity Unit Testing</h2>
|
||||
<p>The {@link android.test.ActivityUnitTestCase} class provides support for
|
||||
isolated testing of a single {@link android.app.Activity}. To create a unit
|
||||
test for your {@link android.app.Activity}, your test class should extend
|
||||
{@link android.test.ActivityUnitTestCase}.</p>
|
||||
|
||||
<p>The {@link android.app.Activity} in an {@link android.test.ActivityUnitTestCase}
|
||||
is not automatically started by Android Instrumentation. To start the
|
||||
{@link android.app.Activity} in isolation, you need to explicitly call the
|
||||
{@link android.test.ActivityUnitTestCase#startActivity(android.content.Intent, android.os.Bundle, java.lang.Object) startActivity()}
|
||||
method, and pass in the {@link android.content.Intent} to
|
||||
launch your target {@link android.app.Activity}.</p>
|
||||
|
||||
<p>For example:</p>
|
||||
<pre>
|
||||
public class LaunchActivityTest
|
||||
extends ActivityUnitTestCase<LaunchActivity> {
|
||||
...
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mLaunchIntent = new Intent(getInstrumentation()
|
||||
.getTargetContext(), LaunchActivity.class);
|
||||
startActivity(mLaunchIntent, null, null);
|
||||
final Button launchNextButton =
|
||||
(Button) getActivity()
|
||||
.findViewById(R.id.launch_next_activity_button);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h2 id="test_method">Validate Launch of Another Activity</h2>
|
||||
<p id="test_goals">Your unit testing goals might include:</p>
|
||||
<ul>
|
||||
<li>Verifying that {@code LaunchActivity} fires an
|
||||
{@link android.content.Intent} when a button is pushed clicked.</li>
|
||||
<li>Verifying that the launched {@link android.content.Intent} contains the
|
||||
correct payload data.</li>
|
||||
</ul>
|
||||
|
||||
<p>To verify if an {@link android.content.Intent} was triggered
|
||||
following the {@link android.widget.Button} click, you can use the
|
||||
{@link android.test.ActivityUnitTestCase#getStartedActivityIntent()} method.
|
||||
By using assertion methods, you can verify that the returned
|
||||
{@link android.content.Intent} is not null, and that it contains the expected
|
||||
string value to launch the next {@link android.app.Activity}. If both assertions
|
||||
evaluate to {@code true}, you've successfully verified that the
|
||||
{@link android.content.Intent} was correctly sent by your
|
||||
{@link android.app.Activity}.</p>
|
||||
|
||||
<p>You might implement your test method like this:</p>
|
||||
<pre>
|
||||
@MediumTest
|
||||
public void testNextActivityWasLaunchedWithIntent() {
|
||||
startActivity(mLaunchIntent, null, null);
|
||||
final Button launchNextButton =
|
||||
(Button) getActivity()
|
||||
.findViewById(R.id.launch_next_activity_button);
|
||||
launchNextButton.performClick();
|
||||
|
||||
final Intent launchIntent = getStartedActivityIntent();
|
||||
assertNotNull("Intent was null", launchIntent);
|
||||
assertTrue(isFinishCalled());
|
||||
|
||||
final String payload =
|
||||
launchIntent.getStringExtra(NextActivity.EXTRAS_PAYLOAD_KEY);
|
||||
assertEquals("Payload is empty", LaunchActivity.STRING_PAYLOAD, payload);
|
||||
}
|
||||
</pre>
|
||||
<p>Because {@code LaunchActivity} runs in isolation, you cannot use the
|
||||
{@link android.test.TouchUtils} library to manipulate UI controls. To directly
|
||||
click a {@link android.widget.Button}, you can call the
|
||||
{@link android.view.View#performClick()} method instead.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
68
docs/html/training/activity-testing/index.jd
Normal file
68
docs/html/training/activity-testing/index.jd
Normal file
@@ -0,0 +1,68 @@
|
||||
page.title=Testing Your Android Activity
|
||||
page.tags="testing"
|
||||
|
||||
trainingnavtop=true
|
||||
startpage=true
|
||||
|
||||
@jd:body
|
||||
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
|
||||
<h2>Dependencies and prerequisites</h2>
|
||||
<ul>
|
||||
<li>Android 2.2 (API Level 8) or higher.</li>
|
||||
</ul>
|
||||
|
||||
<h2>You Should Also Read</h2>
|
||||
<ul>
|
||||
<li><a href="{@docRoot}tools/testing/index.html">Testing
|
||||
(Developer's Guide)</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>You should be writing and running tests as part of your Android application
|
||||
development cycle. Well-written tests can help you to catch bugs early in
|
||||
development and give you confidence in your code.</p>
|
||||
|
||||
<p>A <em>test case</em> defines a set of objects and methods to run multiple
|
||||
tests independently from each other. Test cases can be organized into
|
||||
<em>test suites</em> and run programmatically, in a repeatable manner, with
|
||||
a <em>test runner</em> provided by a testing framework.</p>
|
||||
|
||||
<p>The lessons in this class teaches you how to use the Android's custom
|
||||
testing framework that is based on the popular JUnit framework. You can
|
||||
write test cases to verify specific behavior in your application, and check for
|
||||
consistency across different Android devices. Your test cases also serve as a
|
||||
form of internal code documentation by describing the expected behavior of
|
||||
app components.</p>
|
||||
|
||||
<h2>Lessons</h2>
|
||||
|
||||
<!-- Create a list of the lessons in this class along with a short description
|
||||
of each lesson. These should be short and to the point. It should be clear from
|
||||
reading the summary whether someone will want to jump to a lesson or not.-->
|
||||
|
||||
<dl>
|
||||
<dt><b><a href="preparing-activity-testing.html">Setting Up Your Test
|
||||
Environment</a></b></dt>
|
||||
<dd>Learn how to create your test project.</dd>
|
||||
<dt><b><a href="activity-basic-testing.html">Creating and Running a Test
|
||||
Case</a></b></dt>
|
||||
<dd>Learn how to write test cases to verify the
|
||||
expected properties of your {@link android.app.Activity}, and run the test
|
||||
cases with the {@code Instrumentation} test runner provided by the Android
|
||||
framework.</dd>
|
||||
<dt><b><a href="activity-ui-testing.html">Testing UI Components</a></b></dt>
|
||||
<dd>Learn how to test the behavior of specific UI
|
||||
components in your {@link android.app.Activity}.</dd>
|
||||
<dt><b><a href="activity-unit-testing.html">Creating Unit Tests</a></b></dt>
|
||||
<dd>Learn how to how to perform unit testing to
|
||||
verify the behavior of an Activity in isolation.</dd>
|
||||
<dt><b><a href="activity-functional-testing.html">Creating Functional Tests</a></b></dt>
|
||||
<dd>Learn how to perform functional testing to
|
||||
verify the interaction of multiple Activities.</dd>
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
page.title=Setting Up Your Test Environment
|
||||
trainingnavtop=true
|
||||
|
||||
@jd:body
|
||||
|
||||
<!-- This is the training bar -->
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<h2>This lesson teaches you to</h2>
|
||||
<ol>
|
||||
<li><a href="#eclipse">Set Up Eclipse for Testing</a></li>
|
||||
<li><a href="#cmdline">Set Up the Command Line Interface for Testing</a></li>
|
||||
</ol>
|
||||
|
||||
<h2>You should also read</h2>
|
||||
<ul>
|
||||
<li><a href="{@docRoot}sdk/index.html">Getting the SDK Bundle</a></li>
|
||||
<li><a href="{@docRoot}tools/testing/testing_eclipse.html">Testing from Eclipse
|
||||
with ADT</a></li>
|
||||
<li><a href="{@docRoot}tools/testing/testing_otheride.html">Testing from Other
|
||||
IDEs</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>Try it out</h2>
|
||||
<div class="download-box">
|
||||
<a href="http://developer.android.com/shareables/training/AndroidTestingFun.zip"
|
||||
class="button">Download the demo</a>
|
||||
<p class="filename">AndroidTestingFun.zip</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>Before you start writing and running your tests, you should set up your test
|
||||
development environment. This lesson teaches you how to set up the Eclipse
|
||||
IDE to build and run tests, and how to
|
||||
build and run tests with the Gradle framework by using the command line
|
||||
interface.</p>
|
||||
|
||||
<p class="note"><strong>Note:</strong> To help you get started, the lessons are
|
||||
based on Eclipse with the ADT plugin. However, for your own test development, you
|
||||
are free to use the IDE of your choice or the command-line.</p>
|
||||
|
||||
<h2 id="eclipse">Set Up Eclipse for Testing</h2>
|
||||
<p>Eclipse with the Android Developer Tools (ADT) plugin provides an integrated
|
||||
development environment for you to create, build, and run Android application
|
||||
test cases from a graphical user interface (GUI). A convenient feature that
|
||||
Eclipse provides is the ability to auto-generate a new test project that
|
||||
corresponds with your Android application project</a>.
|
||||
|
||||
<p>To set up your test environment in Eclipse:</p>
|
||||
|
||||
<ol>
|
||||
<li><a href="{@docRoot}sdk/installing/bundle.html">Download and install the
|
||||
Eclipse ADT plugin</a>, if you haven’t installed it yet.</li>
|
||||
<li>Import or create the Android application project that you want to test
|
||||
against.</li>
|
||||
<li>Generate a test project that corresponds to the application project under
|
||||
test. To generate a test project for the app project that you imported:</p>
|
||||
<ol type="a">
|
||||
<li>In the Package Explorer, right-click on your app project, then
|
||||
select <strong>Android Tools</strong> > <strong>New Test Project</strong>.</li>
|
||||
<li>In the New Android Test Project wizard, set the property
|
||||
values for your test project then click <strong>Finish</strong>.</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
<p>You should now be able to create, build, and run test
|
||||
cases from your Eclipse environment. To learn how to perform these tasks in
|
||||
Eclipse, proceed to <a href="activity-basic-testing.html">Creating and Running
|
||||
a Test Case</a>.</p>
|
||||
|
||||
<h2 id="cmdline">Set Up the Command Line Interface for Testing</h2>
|
||||
<p>If you are using Gradle version 1.6 or higher as your build environment, you
|
||||
can build and run your Android application tests from the command line by using
|
||||
the Gradle Wrapper. Make sure that in your {@code gradle.build} file, the
|
||||
<a href={@docRoot}guide/topics/manifest/uses-sdk-element.html#min>minSdkVersion</a>
|
||||
attribute in the {@code defaultConfig} section is set to 8 or higher. You can
|
||||
refer to the sample {@code gradle.build} file that is
|
||||
included in the download bundle for this training class.</p>
|
||||
<p>To run your tests with the Gradle Wrapper:</p>
|
||||
<ol>
|
||||
<li>Connect a physical Android device to your machine or launch the Android
|
||||
Emulator.</li>
|
||||
<li>Run the following command from your project directory:
|
||||
<pre>./gradlew build connectedCheck</pre>
|
||||
</li>
|
||||
</ol>
|
||||
<p>To learn more about using Gradle for Android testing, see the
|
||||
<a href="//tools.android.com/tech-docs/new-build-system/user-guide#TOC-Testing">Gradle Plugin User Guide</a>.</p>
|
||||
<p>To learn more about using command line tools other than Gradle for test
|
||||
development, see
|
||||
<a href="{@docRoot}tools/testing/testing_otheride.html">Testing from Other IDEs</a>.</p>
|
||||
|
||||
7
docs/html/training/testing.jd
Normal file
7
docs/html/training/testing.jd
Normal file
@@ -0,0 +1,7 @@
|
||||
page.title=Best Practices for Testing
|
||||
page.trainingcourse=true
|
||||
|
||||
@jd:body
|
||||
|
||||
<p>These classes and articles provide information about how to
|
||||
test your Android application.</p>
|
||||
@@ -1205,6 +1205,45 @@ include the action bar on devices running Android 2.1 or higher."
|
||||
</li>
|
||||
<!-- End security and user info -->
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header">
|
||||
<a href="<?cs var:toroot ?>training/testing.html">
|
||||
<span class="small">Best Practices for</span><br/>
|
||||
Testing
|
||||
</a>
|
||||
</div>
|
||||
<ul>
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header"><a href="<?cs var:toroot ?>training/activity-testing/index.html"
|
||||
description="How to test Activities in your Android applications.">
|
||||
Testing Your Activity
|
||||
</a></div>
|
||||
<ul>
|
||||
<li><a href="<?cs var:toroot ?>training/activity-testing/preparing-activity-testing.html">
|
||||
<span class="en">Setting Up Your Test Environment</span>
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="<?cs var:toroot ?>training/activity-testing/activity-basic-testing.html">
|
||||
<span class="en">Creating and Running a Test Case</span>
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="<?cs var:toroot ?>training/activity-testing/activity-ui-testing.html">
|
||||
<span class="en">Testing UI Components</span>
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="<?cs var:toroot ?>training/activity-testing/activity-unit-testing.html">
|
||||
<span class="en">Creating Unit Tests</span>
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="<?cs var:toroot ?>training/activity-testing/activity-functional-testing.html">
|
||||
<span class="en">Creating Functional Tests</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!-- End best Testing -->
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header">
|
||||
|
||||
Reference in New Issue
Block a user