Merge "docs: Updated existing auto app images due to updated UI." into mnc-docs
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 87d52e4..77a7c69 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -186,7 +186,7 @@
*
* <p>There are a variety of standard Intent action and category constants
* defined in the Intent class, but applications can also define their own.
- * These strings use java style scoping, to ensure they are unique -- for
+ * These strings use Java-style scoping, to ensure they are unique -- for
* example, the standard {@link #ACTION_VIEW} is called
* "android.intent.action.VIEW".</p>
*
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index e0a61f5..e9b1f01 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1359,7 +1359,7 @@
/**
* Feature for {@link #getSystemAvailableFeatures} and
- * {@link #hasSystemFeature}: The heart rate sensor on this device is an Electrocargiogram.
+ * {@link #hasSystemFeature}: The heart rate sensor on this device is an Electrocardiogram.
*/
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_SENSOR_HEART_RATE_ECG =
diff --git a/docs/html/distribute/essentials/quality/core.jd b/docs/html/distribute/essentials/quality/core.jd
index d7eedf3..860d880 100644
--- a/docs/html/distribute/essentials/quality/core.jd
+++ b/docs/html/distribute/essentials/quality/core.jd
@@ -238,7 +238,7 @@
<div class="resource-widget resource-flow-layout col-13" data-query=
"collection:distribute/essentials/corequalityguidelines/visualdesign"
-data-sortorder="-timestamp" data-cardsizes="9x3,9x3,6x3,6x3,6x3"
+data-sortorder="-timestamp" data-cardsizes="6x3"
data-maxresults="6">
</div>
@@ -746,11 +746,6 @@
"http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&answer=188189">
Content Rating Guidelines</a>.
</p>
-
- <p style="margin-bottom:.25em;">
- Especially, note that apps that request permission to use the device
- location cannot be given the maturity level "Everyone".
- </p>
</td>
<td>
<a href="#gp">GP-1</a>
@@ -1140,7 +1135,7 @@
Pay close attention to alarms, timers, notifications, syncs, and so on.
See <a
href="{@docRoot}training/monitoring-device-state/doze-standby.html#testing_doze_and_app_standby">Testing
- with Doze and App Standby</a>.
+ with Doze and App Standby</a> for requirements and guidelines.
</p>
</td>
</tr>
diff --git a/docs/html/google/google_toc.cs b/docs/html/google/google_toc.cs
index f3e1f3c..8151b10 100644
--- a/docs/html/google/google_toc.cs
+++ b/docs/html/google/google_toc.cs
@@ -21,6 +21,9 @@
<li><a href="<?cs var:toroot?>google/play/billing/billing_subscriptions.html">
<span class="en">Subscriptions</span></a>
</li>
+ <li><a href="<?cs var:toroot?>google/play/billing/billing_promotions.html">
+ <span class="en">Promotions</span></a>
+ </li>
<li><a href="<?cs var:toroot?>google/play/billing/billing_best_practices.html" zh-cn-lang="安全性和设计">
<span class="en">Security and Design</span></a>
</li>
diff --git a/docs/html/google/play/billing/billing_integrate.jd b/docs/html/google/play/billing/billing_integrate.jd
old mode 100644
new mode 100755
index 4249885..c658f70
--- a/docs/html/google/play/billing/billing_integrate.jd
+++ b/docs/html/google/play/billing/billing_integrate.jd
@@ -95,34 +95,38 @@
<p>To add the AIDL to your project:</p>
<ol>
- <li>Copy the {@code IInAppBillingService.aidl} file to your Android project.
+ <li>First, download the Google Play Billing Library to your Android project:
+ <ol type="a">
+ <li>Select <strong>Tools > Android > SDK Manager</strong>.</li>
+ <li>Under <strong>Appearance & Behavior > System Settings > Android SDK</strong>,
+ select the <em>SDK Tools</em> tab to select and download <em>Google Play Billing
+ Library</em>.</li></ol>
+
+ <li>Next, copy the {@code IInAppBillingService.aidl} file to your project.
<ul>
- <li>If you are using Eclipse:
+ <li>If you are using Android Studio:
<ol type="a">
- <li>If you are starting from an existing Android project, open the
- project in Eclipse. If you are creating a new Android project from
- scratch, click <strong>File</strong> > <strong>New</strong> >
- <strong>Android Application Project</strong>, then follow the
- instructions in the <strong>New Android Application</strong> wizard
- to create a new project in your workspace.
- </li>
+ <li>Navigate to {@code src/main} in the Project tool window.</li>
- <li>In the {@code /src} directory, click <strong>File</strong> >
- <strong>New</strong> > <strong>Package</strong>, then create a
- package named {@code com.android.vending.billing}.
- </li>
+ <li>Select <strong>File > New > Directory</strong> and enter {@code aidl} in the
+ <em>New Directory</em> window, then select <strong>OK</strong>.
- <li>Copy the {@code IInAppBillingService.aidl} file from {@code
- <sdk>/extras/google/play_billing/} and paste it into the {@code
- src/com.android.vending.billing/} folder in your workspace.
+ <li>Select <strong>File > New > Package</strong> and enter
+ {@code com.android.vending.billing} in the <em>New Package</em> window, then select
+ <strong>OK</strong>.</li>
+
+ <li>Using your operating system file explorer, navigate to
+ {@code <sdk>/extras/google/play_billing/}, copy the
+ {@code IInAppBillingService.aidl} file, and paste it into the
+ {@code com.android.vending.billing} package in your project.
</li>
</ol>
</li>
- <li>If you are developing in a non-Eclipse environment: Create the
+ <li>If you are developing in a non-Android Studio environment: Create the
following directory {@code /src/com/android/vending/billing} and copy the
{@code IInAppBillingService.aidl} file into this directory. Put the AIDL
- file into your project and use the Ant tool to build your project so that
+ file into your project and use the Gradle tool to build your project so that
the <code>IInAppBillingService.java</code> file gets generated.
</li>
</ul>
diff --git a/docs/html/google/play/billing/billing_promotions.jd b/docs/html/google/play/billing/billing_promotions.jd
new file mode 100644
index 0000000..ccf50fc
--- /dev/null
+++ b/docs/html/google/play/billing/billing_promotions.jd
@@ -0,0 +1,301 @@
+page.title=In-app Promotions
+parent.title=In-app Billing
+parent.link=index.html
+page.metaDescription=Support promo codes in your app, which let you give content or features away to a limited number of users free of charge.
+page.image=/images/play_dev.jpg
+page.tags="promotions, billing, promo codes"
+meta.tags="monetization, inappbilling, promotions"
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>Quickview</h2>
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#workflow">Creating and Redeeming Promo Codes</a></li>
+ <li><a href="#supporting">Supporting Promo Codes In Your App</a></li>
+ <li><a href="#testing">Testing In-app Promotions</a></li>
+ </ol>
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}google/play/billing/billing_integrate.html">Implementing
+ In-app Billing</a></li>
+ <!-- TODO: link to blog post when available -->
+ </ol>
+</div>
+</div>
+
+<p>
+ Promo codes let you give content or features away to a limited number of
+ users free of charge. Once you create a promo code, you can distribute it
+ subject to the
+ <!--TODO: Link to TOS when/if they're available as a web page --> terms of
+ service. The user enters the promo code in your app or in the Play Store app,
+ and gets the item at no cost. You can use promo codes in many ways to
+ creatively engage with users. For example:
+</p>
+
+<ul>
+ <li>A game could have a special item, such as a character or decoration,
+ that's only available to players who attend an event. The developer could
+ distribute cards with promo codes at the event, and users would enter their
+ promo code to unlock the item.
+ </li>
+
+ <li>An app developer might distribute promo codes at local businesses, to
+ encourage potential users to try the app.
+ </li>
+
+ <li>An app developer might give out "friends and family" codes to its employees to
+ share with their friends.
+ </li>
+</ul>
+
+<p>
+ Every promo code is associated with a particular <em>product ID</em> (also
+ known as a <em>SKU</em>). You can create promo codes for your existing in-app
+ products. You can also keep a SKU off the Play Store, so the only way to get
+ that item is by entering that SKU's promo code. When a user enters the promo
+ code in the Play Store or in their app, the user gets the item, just as if
+ they paid full price for it. If your app already uses <a href=
+ "{@docRoot}google/play/billing/api.html">In-app Billing version 3</a> to
+ support in-app purchases, it's easy to add support for promo codes.
+</p>
+
+<h2 id="workflow">Creating and Redeeming Promo Codes</h2>
+
+<p>
+ You create promo codes through the <a href=
+ "https://play.google.com/apps/publish/" class="external-link">Google Play
+ Developer Console</a>. Each promo code is associated with a single product item
+ registered in the developer console.
+</p>
+
+<p>
+ When a user gets a promo code, they redeem it in one of two ways:
+</p>
+
+<ul>
+ <li>The user can enter the promo code as part of the app's ordinary purchase flow, as
+ described in <a href="{@docRoot}google/play/billing/billing_integrate.html">
+ Implementing In-app Billing</a>. As far as the app is concerned, this is
+ just like an ordinary purchase, except that the user makes payment with a
+ promo code instead of with money.
+ </li>
+
+ <li>The user can redeem the code in the Google Play Store app. Once the user
+ enters the code, the Play Store prompts the user to open the app (if they have
+ the latest version installed) or to download or update it. (We do not
+ currently support redeeming promo codes from the Google Play web store.)
+ </li>
+</ul>
+
+<p>
+ If the promo code is for a <a href=
+ "{@docRoot}google/play/billing/api.html#consumetypes">consumable product</a>,
+ the user can apply an additional code for the same product <em>after</em> the first
+ product is consumed. For example, a game might offer promo codes for a bundle
+ of extra lives. Betty has two different promo codes for that bundle. She
+ redeems a single promo code, then launches the game. When the game launches,
+ the her character receives the lives, consuming the item. She can now redeem
+ the second promo code for another bundle of lives. (She cannot redeem the
+ second promo code until after she consumes the item she purchased with the
+ first promo code.)
+</p>
+
+<h2 id="supporting">Supporting Promo Codes In Your App</h2>
+
+<p>
+ To support promotion codes, your app should call the <a href=
+ "{@docRoot}google/play/billing/billing_reference.html#getPurchases"
+ ><code>getPurchases()</code></a>
+ method whenever the app starts or resumes. This method returns a bundle of all
+ current, unconsumed purchases, including purchases the user made by redeeming
+ a promo code. This simplest approach is to call <a href=
+ "{@docRoot}google/play/billing/billing_reference.html#getPurchases"
+ ><code>getPurchases()</code></a>
+ in your activity's {@link android.app.Activity#onResume onResume()} method,
+ since that callback fires when the activity is created, as well as when the
+ activity is unpaused. Calling <a href=
+ "{@docRoot}google/play/billing/billing_reference.html#getPurchases"
+ ><code>getPurchases()</code></a>
+ on startup and resume guarantees that your app will find out about all
+ purchases and redemptions the user may have made while the app wasn't
+ running. Furthermore, if a user makes a purchase while the app is running and
+ your app misses it for any reason, your app will still find out about the
+ purchase the next time the activity resumes and calls <a href=
+ "{@docRoot}google/play/billing/billing_reference.html#getPurchases"
+ ><code>getPurchases()</code></a>.
+</p>
+
+<p>
+ In addition, your app should allow users to redeem promo codes inside the app
+ itself. If your app supports the in-app purchase workflow (described in
+ <a href=
+ "{@docRoot}google/play/billing/billing_integrate.html#billing-requests">Making
+ In-app Billing Requests</a>), your app automatically supports in-app
+ redemption of promo codes. When you launch the in-app purchase UI,
+ the user has the option to pay for the purchase with
+ a promo code. Your activity's {@link android.app.Activity#onActivityResult
+ onActivityResult()} method receives a response intent telling the app whether the
+ purchase was completed. However, your app should still call <a href=
+ "{@docRoot}google/play/billing/billing_reference.html#getPurchases"
+ ><code>getPurchases()</code></a>
+ on startup and resume, just in case the purchase and consumption workflow
+ didn't complete. For example, if the user successfully redeems a promo code,
+ and then your app crashes before the item is consumed, your app still gets
+ information about the purchase when the app calls <a href=
+ "{@docRoot}google/play/billing/billing_reference.html#getPurchases"
+ ><code>getPurchases()</code></a> on its next startup.
+</p>
+
+<p>
+ Your app should also support the scenario where a user redeems a promo code
+ in the Play Store app while the app is running. Your app can find out right
+ away when the user redeems a code by registering a listener for the
+ <code>PURCHASES_UPDATED</code> intent. The Play Store fires this intent
+ whenever a user redeems a promo code.
+</p>
+
+<p>
+ To listen for the <code>PURCHASES_UPDATED</code> intent, dynamically create a
+ {@link android.content.BroadcastReceiver} object and register it to listen
+ for <code>"com.android.vending.billing.PURCHASES_UPDATED"</code>. Register
+ the receiver by putting code like this in your activity's {@link
+ android.app.Activity#onResume onResume()} method:
+</p>
+
+<pre>IntentFilter promoFilter =
+ new IntentFilter("com.android.vending.billing.PURCHASES_UPDATED");
+registerReceiver(myPromoReceiver, promoFilter);</pre>
+
+<p>
+ When the user makes a purchase, the system invokes your broadcast receiver's
+ {@link android.content.BroadcastReceiver#onReceive onReceive()} method. That
+ method should call <a href=
+ "{@docRoot}google/play/billing/billing_reference.html#getPurchases"
+ ><code>getPurchases()</code></a>
+ to see what purchases the user has made.
+</p>
+
+<p>
+ Your activity's {@link android.app.Activity#onPause onPause()} method should
+ unregister the broadcast receiver, to reduce system overhead when your app
+ isn't running:
+</p>
+
+<pre>unRegisterReceiver(myPromoReceiver);</pre>
+
+<p class="note">
+ <strong>Note:</strong> You should not register this broadcast receiver in the
+ app manifest. Declaring the receiver in the manifest can cause the system to
+ launch the app to handle the intent if the user makes a purchase while the app
+ isn't running. This behavior is not necessary, and may be annoying to the
+ user. Instead, your app should call <a href=
+ "{@docRoot}google/play/billing/billing_reference.html#getPurchases"
+ ><code>getPurchases()</code></a>
+ when the user launches it, to find out about any purchases the user made
+ while the app wasn't running.
+</p>
+
+<h2 id="testing">Testing In-app Promotions</h2>
+
+<p>
+ If your app supports in-app promotions, you should test the following use
+ cases.
+</p>
+
+<h3 id="test-inapp">User redeems promo code in the app</h3>
+
+<p>
+ If the user redeems a promo code within the app's purchase flow, as described
+ in <a href=
+ "{@docRoot}google/play/billing/billing_integrate.html#billing-requests">Making
+ In-app Billing Requests</a>, the system invokes your activity's {@link
+ android.app.Activity#onActivityResult onActivityResult()} method to handle
+ the purchase. Verify that {@link android.app.Activity#onActivityResult
+ onActivityResult()} handles the purchase properly, whether the user uses cash
+ or a promo code.
+</p>
+
+<h3 id="test-playstore">User redeems promo code in the Play Store</h3>
+
+<p>
+ If the user redeems a promo code in the Play Store, there are several
+ possible workflows. You should verify each one of these.
+</p>
+
+<h4 id="test-app-uninstalled">App is not installed</h4>
+
+<p>
+ If the user redeems a promo code for an app that is not installed on the
+ device, the Play Store prompts the user to install the app. (If the app is
+ installed but not up-to-date, the Play Store prompts the user to update the
+ app.) You should test the following sequence on a device that does not
+ have your app installed.
+</p>
+
+<ol>
+ <li>User redeems a promo code for the app in the Play Store. The Play Store
+ prompts the user to install your app.
+ </li>
+
+ <li>User installs and launches your app. Verify that on startup, the app
+ calls <a href=
+ "{@docRoot}google/play/billing/billing_reference.html#getPurchases"
+ ><code>getPurchases()</code></a>
+ and correctly detects the purchase the user made with the promo code.
+ </li>
+</ol>
+
+<h4 id="test-app-not-running">App is installed, but not running</h4>
+
+<p>
+ If the user redeems a promo code for an app that is installed on the device,
+ the Play Store prompts the user to switch to the app. You should test the
+ following sequence on a device that has your app installed but not running:
+</p>
+
+<ol>
+ <li>User redeems a promo code for the app in the Play Store. The Play Store
+ prompts the user to switch to your app.
+ </li>
+
+ <li>User launches your app. Verify that on startup, the app calls <a href=
+ "{@docRoot}google/play/billing/billing_reference.html#getPurchases"
+ ><code>getPurchases()</code></a>
+ and correctly detects the purchase the user made with the promo code.
+ </li>
+</ol>
+
+<h4 id="test-app-running">App is installed and running
+</h4>
+
+<p>
+ If the user redeems a promo code for an app that is currently running on the
+ device, the Play Store notifies the app via a <code>PURCHASES_UPDATED</code>
+ intent. You should test the following sequence:
+</p>
+
+<ol>
+ <li>User launches the app. Verify that the app has properly registered itself to
+ receive the <code>PURCHASES_UPDATED</code> intent.
+ </li>
+
+ <li>User launches the Play Store app and redeems a promo code for the app. The Play
+ Store fires a <code>PURCHASES_UPDATED</code> intent. Verify that your app's
+ {@link android.content.BroadcastReceiver#onReceive
+ BroadcastReceiver.onReceive()} callback fires to handle the intent.
+ </li>
+
+ <li>Your {@link android.content.BroadcastReceiver#onReceive onReceive()}
+ method should respond to the intent by calling <a href=
+ "{@docRoot}google/play/billing/billing_reference.html#getPurchases"
+ ><code>getPurchases()</code></a>. Verify that it calls this method, and that
+ it correctly detects the purchase the user made with the promo code.
+ </li>
+
+ <li>User switches back to your app. Verify that the user has the purchased
+ item.
+ </li>
+</ol>
diff --git a/docs/html/google/play/billing/billing_reference.jd b/docs/html/google/play/billing/billing_reference.jd
index 6f2978ce..45ec785 100644
--- a/docs/html/google/play/billing/billing_reference.jd
+++ b/docs/html/google/play/billing/billing_reference.jd
@@ -328,7 +328,11 @@
</p>
<h3 id="getPurchases">The getPurchases() method</h3>
-<p>This method returns the current un-consumed products owned by the user. Table 5 lists the response data that is returned in the {@code Bundle}.</p>
+<p>This method returns the current un-consumed products owned by the user,
+ including both purchased items and items acquired by redeeming a promo code.
+ Table 5 lists the response data that is returned in the
+ {@link android.os.Bundle}.</p>
+
<p class="table-caption" id="getpurchases-response-table">
<strong>Table 6.</strong> Response data from a {@code getPurchases} request.</p>
<table>
diff --git a/docs/html/google/play/billing/index.jd b/docs/html/google/play/billing/index.jd
index b20262f..b2e9fe4 100644
--- a/docs/html/google/play/billing/index.jd
+++ b/docs/html/google/play/billing/index.jd
@@ -14,6 +14,8 @@
<div class="sidebox">
<h2><strong>New in In-App Billing</strong></h2>
<ul>
+ <li><strong>In-app Promotions</strong>—Developers can create promo codes
+ which users can redeem for content or features.</li>
<li><strong>Prorated Subscription Prices</strong>—Content providers can
lower the price of seasonal subscriptions for users who sign up late in the
season. For example, a sports-related service might lower the subscription
diff --git a/docs/html/google/play/licensing/setting-up.jd b/docs/html/google/play/licensing/setting-up.jd
old mode 100644
new mode 100755
index f43e4aba..ef9de43
--- a/docs/html/google/play/licensing/setting-up.jd
+++ b/docs/html/google/play/licensing/setting-up.jd
@@ -6,7 +6,7 @@
<div id="qv-wrapper">
<div id="qv">
-
+
<h2>In this document</h2>
<ol>
<li><a href="#account">Setting Up a Publisher Account</a></li>
@@ -179,21 +179,24 @@
these steps: </p>
<ol>
- <li>Launch the Android SDK Manager (available under the Eclipse <strong>Window</strong>
-menu or by executing {@code <sdk>/tools/android sdk}).</li>
+ <li>Launch the Android SDK Manager, available under the Android Studio Tools menu
+(<strong>Tools > Android > SDK Manager</strong>) or by executing
+{@code <sdk>/tools/android sdk}.</li>
<li>Select and download <strong>Google APIs</strong> for the Android version you'd like to target
(must be Android 2.2 or higher).</li>
- <li>When the download is complete, open the AVD Manager (available under the Eclipse
-<strong>Window</strong>
-menu or by executing {@code <sdk>/tools/android avd}).</li>
- <li>Click
-<strong>New</strong> and set the configuration details for the new AVD. </li>
- <li>In the dialog that appears, assign a descriptive name to the AVD and then
-use the Target menu to choose the <strong>Google APIs</strong> as
-the system image to run on the new AVD. Set the other configuration details as
-needed and then click <strong>Create AVD</strong> to finish. The SDK tools
-create the new AVD configuration, which then appears in the list of available
-Android Virtual Devices.</li>
+ <li>When the download is complete, open the AVD Manager, available under the Android Studio
+Tools menu (<strong>Tools > Android > AVD Manager</strong>) or by executing
+{@code <sdk>/tools/android avd}.</li>
+ <li>In the <em>Android Virtual Device Manager</em> window, select
+<strong>+ Create Virtual Device</strong> to set the configuration details for the new AVD. </li>
+ <li>In the <em>Virtual Device Configuration</em> window, select device hardware, then
+select <strong>Next</strong>.</li>
+<li>Select a <strong>Google API</strong> as the system image to run on the new AVD, then
+select <strong>Next</strong>.</li>
+<li>Assign a descriptive name to the AVD and then set the other configuration details as
+needed.</li>
+<li>Select <strong>Finish</strong> to create the new AVD configuration, which will appear in the
+list of available Android Virtual Devices.</li>
</ol>
<p>If you are not familiar with AVDs or how to use them, see <a
@@ -205,7 +208,7 @@
above — either on an actual device or on an emulator — make sure to
update your application project or build scripts as needed, so that your compiled
<code>.apk</code> files that use licensing are deployed into that environment.
-In particular, if you are developing in Eclipse, make sure that you set up a
+In particular, if you are developing in Android Studio, make sure that you set up a
Run/Debug Configuration that targets the appropriate device or AVD. </p>
<p>You do not need to make any changes to your application's
@@ -323,28 +326,22 @@
<p>The LVL is provided as a configured library project — once you have
downloaded it, you can start using it right away. </p>
-<p>If you are working in Eclipse with ADT, you need to add the LVL to your
-workspace as a new development project, in the same way as you would a new
-application project. </p>
+<p>If you are working in Android Studio, you need to add the LVL to your
+project as a new module.</p>
<ol>
-<li>Use the New Project Wizard to create a new
-project from existing sources. Select the LVL's <code>library</code> directory
-(the directory containing the library's AndroidManifest.xml file) as the project
-root.</li>
-<li>When you are creating the library project, you can select any application
-name, package, and set other fields as needed. </li>
-<li>For the library's build target, select Android 1.5 (API level 3) or higher.</li>
+<li>Use the New Module Wizard to import a library module by selecting
+<strong>File > New > Import Module</strong>.</li>
+<li>In the <em>New Module</em> window, in <em>Source directory</em>, enter the LVL's
+<code>library</code> directory (the directory containing the library's AndroidManifest.xml file)
+as the project root ({@code <sdk>/extras/google/play_licensing/library/AndroidManifest.xml}),
+then select <strong>Next</strong>.</li>
+<li>Select <strong>Finish</strong> to import the library module.</li>
</ol>
-<p> When created, the project is
-predefined as a library project in its <code>project.properties</code> file, so
-no further configuration is needed. </p>
-
-<p>For more information about how to create an application project or work with
-library projects in Eclipse, see <a
-href="{@docRoot}tools/projects/projects-eclipse.html">Managing Projects from
-Eclipse with ADT</a>.</p>
+<p>For more information about how to work with library modules in Android Studio, see
+<a href="{@docRoot}sdk/installing/create-project.html#SettingUpLibraryModule">Managing Projects from
+Android Studio</a>.</p>
<h4>Copying the LVL sources to your application</h4>
@@ -369,24 +366,10 @@
compile time. The process for adding a reference to a library project depends
on your development environment, as described below.</p>
-<p> If you are developing in Eclipse with ADT, you should already have added the
-library project to your workspace, as described in the previous section. If you
+<p> If you are developing in Android Studio, you should already have added the
+library module to your project, as described in the previous section. If you
haven't done that already, do it now before continuing. </p>
-<p>Next, open the application's project properties window, as shown below.
-Select the "Android" properties group and click <strong>Add</strong>, then
-choose the LVL library project (com_android_vending_licensing) and click
-<strong>OK</strong>. For more information, see
-<a href="{@docRoot}tools/projects/projects-eclipse.html#SettingUpLibraryProject">
-Managing Projects from Eclipse with ADT</a></p>.
-
-
-<img src="{@docRoot}images/licensing_add_library.png" alt=""/>
-<p class="img-caption"><strong>Figure 3.</strong> If you are
-working in Eclipse with ADT, you can add the LVL library project to your
-application from the application's project properties.</p>
-
-
<p>If you are developing using the SDK command-line tools, navigate to the
directory containing your application project and open the
<code>project.properties</code> file. Add a line to the file that specifies the
diff --git a/docs/html/guide/components/activities.jd b/docs/html/guide/components/activities.jd
index 5e6917b..b5f7c98 100644
--- a/docs/html/guide/components/activities.jd
+++ b/docs/html/guide/components/activities.jd
@@ -115,7 +115,7 @@
button that initiates an action when the user touches it.</p>
<p>Android provides a number of ready-made views that you can use to design and organize your
-layout. "Widgets" are views that provide a visual (and interactive) elements for the screen, such
+layout. "Widgets" are views that provide visual (and interactive) elements for the screen, such
as a button, text field, checkbox, or just an image. "Layouts" are views derived from {@link
android.view.ViewGroup} that provide a unique layout model for its child views, such as a linear
layout, a grid layout, or relative layout. You can also subclass the {@link android.view.View} and
@@ -661,7 +661,7 @@
appropriate, such that any visible changes to the UI are automatically saved and restored when your
activity is recreated. For example, the {@link android.widget.EditText} widget saves any text
entered by the user and the {@link android.widget.CheckBox} widget saves whether it's checked or
-not. The only work required by you is to provide a unique ID (with the <a
+not. The only work required of you is to provide a unique ID (with the <a
href="{@docRoot}guide/topics/resources/layout-resource.html#idvalue">{@code android:id}</a>
attribute) for each widget you want to save its state. If a widget does not have an ID, then the
system cannot save its state.</p>
diff --git a/docs/html/guide/components/aidl.jd b/docs/html/guide/components/aidl.jd
old mode 100644
new mode 100755
index 0be6e6f..78fa996
--- a/docs/html/guide/components/aidl.jd
+++ b/docs/html/guide/components/aidl.jd
@@ -190,11 +190,11 @@
with a {@code .java} extension (for example, {@code IRemoteService.aidl} results in {@code
IRemoteService.java}).</p>
-<p>If you use Eclipse, the incremental build generates the binder class almost immediately. If you
-do not use Eclipse, then the Ant tool generates the binder class next time you build your
-application—you should build your project with <code>ant debug</code> (or <code>ant
-release</code>) as soon as you're finished writing the {@code .aidl} file, so that your code can
-link against the generated class.</p>
+<p>If you use Android Studio, the incremental build generates the binder class almost immediately.
+If you do not use Android Studio, then the Gradle tool generates the binder class next time you
+build your application—you should build your project with <code>gradle assembleDebug</code>
+(or <code>gradle assembleRelease</code>) as soon as you're finished writing the {@code .aidl} file,
+so that your code can link against the generated class.</p>
<h3 id="Implement">2. Implement the interface</h3>
@@ -217,7 +217,7 @@
<p>Here is an example implementation of an interface called {@code IRemoteService} (defined by the
{@code IRemoteService.aidl} example, above) using an anonymous instance:</p>
-
+
<pre>
private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
public int getPid(){
@@ -324,7 +324,7 @@
-
+
<h2 id="PassingObjects">Passing Objects over IPC</h2>
diff --git a/docs/html/guide/components/fundamentals.jd b/docs/html/guide/components/fundamentals.jd
index ca11196..80125ba 100644
--- a/docs/html/guide/components/fundamentals.jd
+++ b/docs/html/guide/components/fundamentals.jd
@@ -369,7 +369,7 @@
</pre>
<p>Then, if another app creates an intent with the {@link
-android.content.Intent#ACTION_SEND} action and pass it to {@link android.app.Activity#startActivity
+android.content.Intent#ACTION_SEND} action and passes it to {@link android.app.Activity#startActivity
startActivity()}, the system may start your activity so the user can draft and send an
email.</p>
diff --git a/docs/html/guide/topics/providers/content-provider-basics.jd b/docs/html/guide/topics/providers/content-provider-basics.jd
index 16e68d1..b7ae3d2 100644
--- a/docs/html/guide/topics/providers/content-provider-basics.jd
+++ b/docs/html/guide/topics/providers/content-provider-basics.jd
@@ -328,7 +328,7 @@
</pre>
<p>
where the <code>user_dictionary</code> string is the provider's authority, and
- <code>words</code> string is the table's path. The string
+ the <code>words</code> string is the table's path. The string
<code>content://</code> (the <strong>scheme</strong>) is always present,
and identifies this as a content URI.
</p>
@@ -346,8 +346,8 @@
</p>
<p class="note">
<strong>Note:</strong> The {@link android.net.Uri} and {@link android.net.Uri.Builder} classes
- contain convenience methods for constructing well-formed Uri objects from strings. The
- {@link android.content.ContentUris} contains convenience methods for appending id values to
+ contain convenience methods for constructing well-formed URI objects from strings. The
+ {@link android.content.ContentUris} class contains convenience methods for appending id values to
a URI. The previous snippet uses {@link android.content.ContentUris#withAppendedId
withAppendedId()} to append an id to the UserDictionary content URI.
</p>
@@ -407,7 +407,7 @@
<!-- Constructing the query -->
<h3 id="Query">Constructing the query</h3>
<p>
- The next step in retrieving data a provider is to construct a query. This first snippet
+ The next step in retrieving data from a provider is to construct a query. This first snippet
defines some variables for accessing the User Dictionary Provider:
</p>
<pre class="prettyprint">
diff --git a/docs/html/guide/topics/security/normal-permissions.jd b/docs/html/guide/topics/security/normal-permissions.jd
index 9f7a3c6..afdddf2 100644
--- a/docs/html/guide/topics/security/normal-permissions.jd
+++ b/docs/html/guide/topics/security/normal-permissions.jd
@@ -99,9 +99,6 @@
<li>{@link android.Manifest.permission#EXPAND_STATUS_BAR EXPAND_STATUS_BAR}
</li>
- <li>{@link android.Manifest.permission#FLASHLIGHT FLASHLIGHT}
- </li>
-
<li>{@link android.Manifest.permission#GET_PACKAGE_SIZE GET_PACKAGE_SIZE}
</li>
diff --git a/docs/html/guide/topics/security/permissions.jd b/docs/html/guide/topics/security/permissions.jd
index 1091a09..ecbe33a 100644
--- a/docs/html/guide/topics/security/permissions.jd
+++ b/docs/html/guide/topics/security/permissions.jd
@@ -334,7 +334,7 @@
If the device is running Android 6.0 (API level 23) and the app's <a href=
"{@docRoot}guide/topics/manifest/uses-sdk-element.html#target"
><code>targetSdkVersion</code></a> is 23 or higher, the following system
- behavior applies when you app requests a dangerous permission:
+ behavior applies when your app requests a dangerous permission:
</p>
<ul>
diff --git a/docs/html/guide/topics/ui/index.jd b/docs/html/guide/topics/ui/index.jd
index f342b06..0725eb7 100644
--- a/docs/html/guide/topics/ui/index.jd
+++ b/docs/html/guide/topics/ui/index.jd
@@ -1,6 +1,6 @@
page.title=User Interface
page.landing=true
-page.landing.intro=Your app's user interface is everything that the user can see and interact with. Android provides a variety of pre-build UI components such as structured layout objects and UI controls that allow you to build the graphical user interface for your app. Android also provides other UI modules for special interfaces such as dialogs, notifications, and menus.
+page.landing.intro=Your app's user interface is everything that the user can see and interact with. Android provides a variety of pre-built UI components such as structured layout objects and UI controls that allow you to build the graphical user interface for your app. Android also provides other UI modules for special interfaces such as dialogs, notifications, and menus.
page.landing.image=images/ui/ui_index.png
page.landing.next=overview.html
@@ -10,7 +10,7 @@
<div class="col-6">
<h3>Blog Articles</h3>
-
+
<a href="http://android-developers.blogspot.com/2012/01/say-goodbye-to-menu-button.html">
<h4>Say Goodbye to the Menu Button</h4>
<p>As Ice Cream Sandwich rolls out to more devices, it’s important that you begin to migrate
@@ -35,7 +35,7 @@
<div class="col-6">
<h3>Training</h3>
-
+
<a href="http://developer.android.com/training/implementing-navigation/index.html">
<h4>Implementing Effective Navigation</h4>
<p>This class shows you how to plan out the high-level screen hierarchy for your application
diff --git a/docs/html/images/cards/card-user-ids_2x.png b/docs/html/images/cards/card-user-ids_2x.png
new file mode 100644
index 0000000..4db4f3c
--- /dev/null
+++ b/docs/html/images/cards/card-user-ids_2x.png
Binary files differ
diff --git a/docs/html/images/cards/card-user-permissions_2x.png b/docs/html/images/cards/card-user-permissions_2x.png
new file mode 100644
index 0000000..6abac48
--- /dev/null
+++ b/docs/html/images/cards/card-user-permissions_2x.png
Binary files differ
diff --git a/docs/html/images/cards/card-user_2x.png b/docs/html/images/cards/card-user_2x.png
new file mode 100644
index 0000000..e4ef23d
--- /dev/null
+++ b/docs/html/images/cards/card-user_2x.png
Binary files differ
diff --git a/docs/html/images/testing/testing-icon.png b/docs/html/images/testing/testing-icon.png
new file mode 100644
index 0000000..41a783b
--- /dev/null
+++ b/docs/html/images/testing/testing-icon.png
Binary files differ
diff --git a/docs/html/images/training/articles/user-data-overview-permissions-flow01.jpg b/docs/html/images/training/articles/user-data-overview-permissions-flow01.jpg
new file mode 100644
index 0000000..e3b192b
--- /dev/null
+++ b/docs/html/images/training/articles/user-data-overview-permissions-flow01.jpg
Binary files differ
diff --git a/docs/html/images/training/articles/user-data-overview-permissions-flow02.jpg b/docs/html/images/training/articles/user-data-overview-permissions-flow02.jpg
new file mode 100644
index 0000000..c2275eb
--- /dev/null
+++ b/docs/html/images/training/articles/user-data-overview-permissions-flow02.jpg
Binary files differ
diff --git a/docs/html/images/training/articles/user-data-overview-permissions-groups.png b/docs/html/images/training/articles/user-data-overview-permissions-groups.png
new file mode 100644
index 0000000..5996489
--- /dev/null
+++ b/docs/html/images/training/articles/user-data-overview-permissions-groups.png
Binary files differ
diff --git a/docs/html/images/training/articles/user-data-overview-permissions-usage.jpg b/docs/html/images/training/articles/user-data-overview-permissions-usage.jpg
new file mode 100644
index 0000000..0732369
--- /dev/null
+++ b/docs/html/images/training/articles/user-data-overview-permissions-usage.jpg
Binary files differ
diff --git a/docs/html/images/training/tv/playback/now-playing-screen.png b/docs/html/images/training/tv/playback/now-playing-screen.png
new file mode 100644
index 0000000..3f6e252
--- /dev/null
+++ b/docs/html/images/training/tv/playback/now-playing-screen.png
Binary files differ
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index 0f2ba3e..81b6d70 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -1522,6 +1522,42 @@
"distribute/googleplay/auto.html"
]
},
+ "training/testing/overview": {
+ "title": "",
+ "resources": [
+ "training/testing/start/index.html",
+ "tools/testing/testing_android.html",
+ "https://www.youtube.com/watch?v=vdasFFfXKOY"
+ ]
+ },
+ "training/testing/tools": {
+ "title": "",
+ "resources": [
+ "tools/testing-support-library/index.html",
+ "tools/help/monkey.html",
+ "tools/help/monkeyrunner_concepts.html",
+ "tools/testing/testing_otheride.html",
+ "https://source.android.com/devices/tech/debug/dumpsys.html"
+ ]
+ },
+ "training/testing/techniques": {
+ "title": "",
+ "resources": [
+ "training/testing/ui-testing/index.html",
+ "training/testing/unit-testing/index.html",
+ "training/testing/performance.html"
+ ]
+ },
+ "training/testing/resources": {
+ "title": "",
+ "resources": [
+ "https://github.com/googlesamples/android-testing",
+ "https://www.youtube.com/watch?v=2I6fuD20qlY",
+ "https://codelabs.developers.google.com/codelabs/android-testing/index.html",
+ "https://github.com/googlesamples/android-testing-templates",
+ "https://google.github.io/android-testing-support-library"
+ ]
+ },
"distribute/stories/games": {
"title": "",
"resources": [
diff --git a/docs/html/jd_extras.js b/docs/html/jd_extras.js
index 8e2f040..40b35a2 100644
--- a/docs/html/jd_extras.js
+++ b/docs/html/jd_extras.js
@@ -482,6 +482,90 @@
"type":"video"
},
{
+ "title":"Debugging and testing in Android Studio",
+ "titleFriendly":"",
+ "summary":"This video introduces the state of unit testing support in Studio and Google’s new Android Testing Support Library for functional UI testing and running instrumented tests on a device.",
+ "url":"https://www.youtube.com/watch?v=2I6fuD20qlY",
+ "group":"",
+ "keywords": ["testing"],
+ "tags": [
+ ],
+ "image":"http://i1.ytimg.com/vi/2I6fuD20qlY/maxresdefault.jpg",
+ "type":"video"
+ },
+ {
+ "title":"Android Testing (Android Dev Summit 2015)",
+ "titleFriendly":"",
+ "summary":"Overview of the testing tools and frameworks provided by Google and how they can help you to iterate more quickly and maintain a more healthy codebase.",
+ "url":"https://www.youtube.com/watch?v=vdasFFfXKOY",
+ "group":"",
+ "keywords": ["testing"],
+ "tags": [
+ ],
+ "image":"http://i1.ytimg.com/vi/vdasFFfXKOY/maxresdefault.jpg",
+ "type":"video"
+ },
+ {
+ "title":"dumpsys",
+ "titleFriendly":"",
+ "summary":"A tool that runs on the device and provides information about the status of system services.",
+ "url":"https://source.android.com/devices/tech/debug/dumpsys.html",
+ "group":"",
+ "keywords": ["testing"],
+ "tags": [
+ ],
+ "image":"",
+ "type":"google"
+ },
+ {
+ "title":"Android Testing Samples",
+ "titleFriendly":"",
+ "summary":"A collection of samples demonstrating different frameworks and techniques for automated testing.",
+ "url":"https://github.com/googlesamples/android-testing",
+ "group":"",
+ "keywords": ["testing"],
+ "tags": [
+ ],
+ "image":"images/testing/testing-icon.png",
+ "type":"Samples"
+ },
+ {
+ "title":"Android Testing Templates",
+ "titleFriendly":"",
+ "summary":"A collection of Google's Android testing tools and frameworks, all integrated in a single application project.",
+ "url":"https://github.com/googlesamples/android-testing-templates",
+ "group":"",
+ "keywords": ["testing"],
+ "tags": [
+ ],
+ "image":"images/testing/testing-icon.png",
+ "type":"Samples"
+ },
+ {
+ "title":"Android Testing Support Library (GitHub)",
+ "titleFriendly":"",
+ "summary":"A resource page on GitHub for the Android Testing Support Library.",
+ "url":"https://google.github.io/android-testing-support-library",
+ "group":"",
+ "keywords": ["testing"],
+ "tags": [
+ ],
+ "image":"images/testing/testing-icon.png",
+ "type":"Samples"
+ },
+ {
+ "title":"Android Testing Codelab",
+ "titleFriendly":"",
+ "summary":"This codelab shows how to build an Android app from the ground up in Android Studio, using a Model View Presenter architecture, Unit Tests and Instrumentation Tests.",
+ "url":"https://codelabs.developers.google.com/codelabs/android-testing/index.html",
+ "group":"",
+ "keywords": ["testing"],
+ "tags": [
+ ],
+ "image":"images/testing/testing-icon.png",
+ "type":"google"
+ },
+ {
"title":"Developer Registration",
"titleFriendly":"",
"summary":"Additional information about the registration process.",
diff --git a/docs/html/legal.jd b/docs/html/legal.jd
old mode 100644
new mode 100755
index 5ee6b5c..0a68508
--- a/docs/html/legal.jd
+++ b/docs/html/legal.jd
@@ -70,12 +70,10 @@
restrictions. Such services include:</p>
<dl>
- <dt>Eclipse Android Developer Tools Plugin</dt>
- <dd>If you're developing apps with the Eclipse IDE, we offer a free plugin called the
-<a href="{@docRoot}tools/sdk/eclipse-adt.html">Android Developer Tools</a> (ADT) to speed up your
-development and debugging. Certain code within the ADT plugin and other packages available
-from the SDK Manager require that you agree to terms and conditions for use, reproduction and
-distribution upon installation.</dd>
+ <dt>Android Studio</dt>
+ <dd>Android Studio and other packages available from the SDK manager require that you agree
+to terms and conditions
+for use, reproduction and distribution upon installation.</dd>
<dt>Google Play</dt>
<dd>Google Play is a publicly available service through which you can distribute your apps for
diff --git a/docs/html/tools/debugging/debugging-memory.jd b/docs/html/tools/debugging/debugging-memory.jd
old mode 100644
new mode 100755
index 261df93..71c009d
--- a/docs/html/tools/debugging/debugging-memory.jd
+++ b/docs/html/tools/debugging/debugging-memory.jd
@@ -42,7 +42,7 @@
<p>The simplest place to begin investigating your app’s memory usage is the runtime log messages.
Sometimes when a GC occurs, a message is printed to
<a href="{@docRoot}tools/help/logcat.html">logcat</a>. The logcat output is also available in the
-Device Monitor or directly in IDEs such as Eclipse and Android Studio.</p>
+Device Monitor or directly in an IDE such as Android Studio.</p>
<h3 id="DalvikLogMessages">Dalvik Log Messages</h3>
@@ -240,7 +240,7 @@
<h3>Memory Monitor in Android Studio</h3>
<p>Use Android Studio to view your app's memory use: </p>
-<ul>
+<ol>
<li>Start your app on a connected device or emulator.</li>
<li>Open the Android run-time window, and view the free and allocated memory in the Memory
Monitor. </li>
@@ -260,7 +260,7 @@
</li>
<li>Identify which actions in your app are likely causing too much allocation and determine where
in your app you should try to reduce allocations and release resources.
-</ul>
+</ol>
<h3>Device Monitor </h3>
<ol>
@@ -628,7 +628,7 @@
<p>To retrieve your heap dump from within Android Studio, use the
-<a href="{@docRoot}tools/studio/index.html#me-cpu">Memory Monitor</a> and
+<a href="{@docRoot}tools/studio/index.html#mem-cpu">Memory Monitor</a> and
<a href="{@docRoot}tools/studio/index.html#heap-dump">HPROF viewer</a>.
<p>You can also still perform these procedures in the Android monitor:</p>
@@ -655,10 +655,12 @@
number of allocations in the Zygote process. But because the Zygote allocations are shared across
all app processes, they don’t matter very much to your own heap analysis.</p>
-<p>To analyze your heap dump, you can use a standard tool like jhat or the <a href=
-"http://www.eclipse.org/mat/downloads.php">Eclipse Memory Analyzer Tool</a> (MAT). However, first
+<p>To analyze your heap dump, you can use <a href=
+"{@docRoot}tools/help/am-memory.html">Memory Monitor</a> in Android Studio.
+You can also use a standard tool like jhat. However, first
you'll need to convert the HPROF file from Android's format to the J2SE HPROF format. You can do
-this using the <code>hprof-conv</code> tool provided in the <code><sdk>/platform-tools/</code>
+this using the <code>hprof-conv</code> tool provided in the
+<code><sdk>/platform-tools/</code>
directory. Simply run the <code>hprof-conv</code> command with two arguments: the original HPROF
file and the location to write the converted HPROF file. For example:</p>
@@ -666,11 +668,9 @@
hprof-conv heap-original.hprof heap-converted.hprof
</pre>
-<p class="note"><strong>Note:</strong> If you're using the version of DDMS that's integrated into
-Eclipse, you do not need to perform the HPROF conversation—it performs the conversion by
-default.</p>
-<p>You can now load the converted file in MAT or another heap analysis tool that understands
+
+<p>You can now load the converted file into a heap analysis tool that understands
the J2SE HPROF format.</p>
<p>When analyzing your heap, you should look for memory leaks caused by:</p>
@@ -682,77 +682,6 @@
</ul>
-<h3 id="EclipseMat">Using the Eclipse Memory Analyzer Tool</h3>
-
-<p>The <a href=
-"http://www.eclipse.org/mat/downloads.php">Eclipse Memory Analyzer Tool</a> (MAT) is just one
-tool that you can use to analyze your heap dump. It's also quite powerful so most of its
-capabilities are beyond the scope of this document, but here are a few tips to get you started.
-
-<p>Once you open your converted HPROF file in MAT, you'll see a pie chart in the Overview,
-showing what your largest objects are. Below this chart, are links to couple of useful features:</p>
-
-<ul>
- <li>The <strong>Histogram view</strong> shows a list of all classes and how many instances
- there are of each.
- <p>You might want to use this view to find extra instances of classes for which you know there
- should be only a certain number. For example, a common source of leaks is additional instance of
- your {@link android.app.Activity} class, for which you should usually have only one instance
- at a time. To find a specific class instance, type the class name into the <em><Regex></em>
- field at the top of the list.
- <p>When you find a class with too many instances, right-click it and select
- <strong>List objects</strong> > <strong>with incoming references</strong>. In the list that
- appears, you can determine where an instance is retained by right-clicking it and selecting
- <strong>Path To GC Roots</strong> > <strong>exclude weak references</strong>.</p>
- </li>
-
- <li>The <strong>Dominator tree</strong> shows a list of objects organized by the amount
- of retained heap.
- <p>What you should look for is anything that's retaining a portion of heap that's roughly
- equivalent to the memory size you observed leaking from the <a href="#LogMessages">GC logs</a>,
- <a href="#ViewHeap">heap updates</a>, or <a href="#TrackAllocations">allocation
- tracker</a>.
- <p>When you see something suspicious, right-click on the item and select
- <strong>Path To GC Roots</strong> > <strong>exclude weak references</strong>. This opens a
- new tab that traces the references to that object which is causing the alleged leak.</p>
-
- <p class="note"><strong>Note:</strong> Most apps will show an instance of
- {@link android.content.res.Resources} near the top with a good chunk of heap, but this is
- usually expected when your app uses lots of resources from your {@code res/} directory.</p>
- </li>
-</ul>
-
-
-<img src="{@docRoot}images/tools/mat-histogram@2x.png" width="760" alt="" />
-<p class="img-caption"><strong>Figure 4.</strong> The Eclipse Memory Analyzer Tool (MAT),
-showing the Histogram view and a search for "MainActivity".</p>
-
-<p>For more information about MAT, watch the Google I/O 2011 presentation,
-<a href="http://www.youtube.com/watch?v=_CruQY55HOk">Memory management for Android apps</a>,
-which includes a walkthrough using MAT beginning at about <a href=
-"http://www.youtube.com/watch?v=_CruQY55HOk&feature=player_detailpage#t=1270">21:10</a>.
-Also refer to the <a href="http://wiki.eclipse.org/index.php/MemoryAnalyzer">Eclipse Memory
-Analyzer documentation</a>.</p>
-
-<h4 id="MatCompare">Comparing heap dumps</h4>
-
-<p>You may find it useful to compare your app's heap state at two different points in time in order
-to inspect the changes in memory allocation. To compare two heap dumps using MAT:</p>
-
-<ol>
- <li>Create two HPROF files as described above, in <a href="#HeapDump">Capturing a Heap Dump</a>.
- <li>Open the first HPROF file in MAT (<strong>File</strong> > <strong>Open Heap Dump</strong>).
- <li>In the Navigation History view (if not visible, select <strong>Window</strong> >
- <strong>Navigation History</strong>), right-click on <strong>Histogram</strong> and select
- <strong>Add to Compare Basket</strong>.
- <li>Open the second HPROF file and repeat steps 2 and 3.
- <li>Switch to the <em>Compare Basket</em> view and click <strong>Compare the Results</strong>
- (the red "!" icon in the top-right corner of the view).
-</ol>
-
-
-
-
<h2 id="TriggerLeaks">Triggering Memory Leaks</h2>
diff --git a/docs/html/tools/help/adb.jd b/docs/html/tools/help/adb.jd
old mode 100644
new mode 100755
index 2faff4f..06e0099
--- a/docs/html/tools/help/adb.jd
+++ b/docs/html/tools/help/adb.jd
@@ -29,7 +29,7 @@
<ul>
<li>A client, which runs on your development machine. You can invoke a client from a shell
-by issuing an adb command. Other Android tools such as the ADT plugin and DDMS also create
+by issuing an adb command. Other Android tools such as DDMS also create
adb clients. </li>
<li>A server, which runs as a background process on your development machine. The server
manages communication between the client and the adb daemon running on an emulator or device. </li>
@@ -361,7 +361,7 @@
<p>For more information about how to create an .apk file that you can install on an emulator/device
instance, see <a href="{@docRoot}tools/building/index.html">Building and Running</a></p>
-<p>Note that, if you are using the Eclipse IDE and have the ADT plugin installed, you do not need to use adb (or aapt) directly to install your application on the emulator/device. Instead, the ADT plugin handles the packaging and installation of the application for you. </p>
+<p>Note that, if you are using Android Studio, you do not need to use adb (or aapt) directly to install your application on the emulator/device. Instead, Android Studio handles the packaging and installation of the application for you. </p>
diff --git a/docs/html/tools/help/sdk-manager.jd b/docs/html/tools/help/sdk-manager.jd
old mode 100644
new mode 100755
index cc95edf..c8493dc
--- a/docs/html/tools/help/sdk-manager.jd
+++ b/docs/html/tools/help/sdk-manager.jd
@@ -34,7 +34,7 @@
</ul>
<p class="note"><strong>Tip:</strong> The standalone SDK Manager is still available from the
-command line, but we recommend it only for use with Eclipse ADT and standalone SDK installations.</p>
+command line, but we recommend it only for use with standalone SDK installations.</p>
<p>By default, the SDK Manager installs the latest packages and tools. Click the checkbox next to
each additional SDK platform and tool that you want to install. Clear the
@@ -99,7 +99,7 @@
Android APIs (such as <a href="{@docRoot}guide/components/fragments.html">fragments</a>,
plus others not included in the framework at all) on devices running
a platform version as old as Android 1.6. All of the activity templates available when creating
-a new project with the <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a>
+a new project with Android Studio
require this. For more information, read <a
href="{@docRoot}tools/support-library/index.html">Support Library</a>.</dd>
diff --git a/docs/html/tools/help/zipalign.jd b/docs/html/tools/help/zipalign.jd
old mode 100644
new mode 100755
index 184cdcb..c70810c
--- a/docs/html/tools/help/zipalign.jd
+++ b/docs/html/tools/help/zipalign.jd
@@ -16,12 +16,12 @@
<p>This tool should always be used to align your .apk file before
distributing it to end-users. The Android build tools can handle
-this for you. When using Eclipse with the ADT plugin, the Export Wizard
-will automatically zipalign your .apk after it signs it with your private key.
+this for you. Android Studio automatically aligns your .apk after it signs it with your
+private key.
The build scripts used
-when compiling your application with Ant will also zipalign your .apk,
+when compiling your application with Gradle also align your .apk,
as long as you have provided the path to your keystore and the key alias in
-your project {@code ant.properties} file, so that the build tools
+your project {@code gradle.properties} file, so that the build tools
can sign the package first.</p>
<p class="caution"><strong>Caution:</strong> zipalign must only be performed
diff --git a/docs/html/tools/publishing/app-signing.jd b/docs/html/tools/publishing/app-signing.jd
index af5b771..8f68ff7 100644
--- a/docs/html/tools/publishing/app-signing.jd
+++ b/docs/html/tools/publishing/app-signing.jd
@@ -16,7 +16,7 @@
</li>
<li><a href="#studio">Signing Your App in Android Studio</a>
<ol>
- <li><a href="sign-auto">Automatically Signing Your App</a></li>
+ <li><a href="#sign-auto">Automatically Signing Your App</a></li>
</ol>
</li>
<li><a href="#studio">Signing Your App with Android Studio</a></li>
@@ -65,9 +65,9 @@
<p>By default, the <em>debug</em> configuration uses a debug keystore, with a known
password and a default key with a known password.
-The debug keystore is located in $HOME/.android/debug.keystore, and is created if not present.
-
-The debug build type is set to use this debug <code>SigningConfig</code> automatically. </p>
+The debug keystore is located in <code>$HOME/.android/debug.keystore</code>, and
+is created if not present.
+The debug build type is set to use this debug <code>SigningConfig</code> automatically.</p>
<p>For more information about how to build and run apps in debug mode, see
<a href="{@docRoot}tools/building/index.html">Building and Running</a>.</p>
@@ -82,7 +82,8 @@
<li><em>Create a private key.</em> A <strong>private key</strong> represents the entity to
be identified with the app, such as a person or a company.</li>
<li><p>Add the signing configuration to the build file for the <code>app</code> module:</p>
- <p><pre>
+
+<pre>
...
android {
...
@@ -103,12 +104,13 @@
}
}
...
-</pre></p>
+</pre>
</li>
<li>Invoke the <code>assembleRelease</code> build task from Android Studio.</li>
</ol>
-<p>The package in <code>app/build/apk/app-release.apk</code> is now signed with your release key.</p>
+<p>The package in <code>app/build/apk/app-release.apk</code> is now signed with your release
+key.</p>
<p class="note"><strong>Note:</strong> Including the passwords for your release key and keystore
inside the build file is not a good security practice. Alternatively, you can configure the build
@@ -156,17 +158,19 @@
<ol>
<li>On the menu bar, click <strong>Build</strong> > <strong>Generate Signed APK</strong>.</li>
-<li><p>On the <em>Generate Signed APK Wizard</em> window, click <strong>Create new</strong> to create
-a new keystore.</p><p>If you already have a keystore, go to step 4.</p></li>
+<li><p>On the <em>Generate Signed APK Wizard</em> window, click <strong>Create new</strong> to
+create a new keystore.</p>
+<p>If you already have a keystore, go to step 4.</p></li>
<li><p>On the <em>New Key Store</em> window, provide the required information as shown
-in figure 1.</p><p>Your key should be valid for at least 25 years, so you can sign app updates
+in figure 1.</p>
+<p>Your key should be valid for at least 25 years, so you can sign app updates
with the same key through the lifespan of your app.</p>
<img src="{@docRoot}images/tools/signstudio2.png" alt=""
width="416" height="364" style="margin-top:15px"/>
<p class="img-caption"><strong>Figure 1</strong>. Create a new keystore in Android Studio.</p>
</li>
-<li><p>On the <em>Generate Signed APK Wizard</em> window, select a keystore, a private key, and enter
-the passwords for both. Then click <strong>Next</strong>.</p>
+<li><p>On the <em>Generate Signed APK Wizard</em> window, select a keystore, a private key, and
+enter the passwords for both. Then click <strong>Next</strong>.</p>
<img src="{@docRoot}images/tools/signstudio1.png" alt=""
width="349" height="232" style="margin-top:15px"/>
<p class="img-caption"><strong>Figure 2</strong>. Select a private key in Android Studio.</p>
@@ -193,14 +197,16 @@
more than one), and enter the required information.</p>
<img src="{@docRoot}images/tools/signstudio10.png" alt=""
width="623" height="372" style="margin-top:15px"/>
-<p class="img-caption"><strong>Figure 4</strong>. Create a signing configuration in Android Studio.</p>
+<p class="img-caption"><strong>Figure 4</strong>. Create a signing configuration in Android
+Studio.</p>
</li>
<li>Click on the <strong>Build Types</strong> tab.</li>
<li>Select the <strong>release</strong> build.</li>
<li><p>Under <em>Signing Config</em>, select the signing configuration you just created.</p>
<img src="{@docRoot}images/tools/signstudio11.png" alt=""
width="623" height="372" style="margin-top:15px"/>
-<p class="img-caption"><strong>Figure 5</strong>. Select a signing configuration in Android Studio.</p>
+<p class="img-caption"><strong>Figure 5</strong>. Select a signing configuration in Android
+Studio.</p>
</li>
<li>Click <strong>OK</strong>.</li>
</ol>
@@ -299,9 +305,10 @@
<ol>
<li>
<p>Generate a private key using
- <code><a href="http://docs.oracle.com/javase/6/docs/technotes/tools/solaris/keytool.html">keytool</a></code>.
+ <code><a href="http://docs.oracle.com/javase/6/docs/technotes/tools/solaris/keytool.html"
+ >keytool</a></code>.
For example:</p>
-<pre>
+<pre class="no-pretty-print">
$ keytool -genkey -v -keystore my-release-key.keystore
-alias alias_name -keyalg RSA -keysize 2048 -validity 10000
</pre>
@@ -317,7 +324,7 @@
<p>Sign your app with your private key using
<code><a href="http://docs.oracle.com/javase/6/docs/technotes/tools/windows/jarsigner.html">jarsigner</a></code>:
</p>
-<pre>
+<pre class="no-pretty-print">
$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1
-keystore my-release-key.keystore my_application.apk alias_name
</pre>
@@ -326,14 +333,14 @@
</li>
<li style="margin-top:18px">
<p>Verify that your APK is signed. For example:</p>
-<pre>
+<pre class="no-pretty-print">
$ jarsigner -verify -verbose -certs my_application.apk
</pre>
</li>
<li style="margin-top:18px">
<p>Align the final APK package using
<code><a href="{@docRoot}tools/help/zipalign.html">zipalign</a></code>.</p>
-<pre>
+<pre class="no-pretty-print">
$ zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk
</pre>
<p><code>zipalign</code> ensures that all uncompressed data starts with a particular byte
diff --git a/docs/html/tools/testing-support-library/index.jd b/docs/html/tools/testing-support-library/index.jd
index b29d301..ac21e3a 100644
--- a/docs/html/tools/testing-support-library/index.jd
+++ b/docs/html/tools/testing-support-library/index.jd
@@ -1,4 +1,5 @@
page.title=Testing Support Library
+page.image=images/tools/studio-test-module.png
@jd:body
diff --git a/docs/html/tools/testing/activity_test.jd b/docs/html/tools/testing/activity_test.jd
deleted file mode 100644
index 036407a..0000000
--- a/docs/html/tools/testing/activity_test.jd
+++ /dev/null
@@ -1,1321 +0,0 @@
-page.title=Activity Testing Tutorial
-parent.title=Testing
-parent.link=index.html
-@jd:body
- <div id="qv-wrapper">
- <div id="qv">
- <h2>In this document</h2>
- <ol>
- <li>
- <a href="#Prerequisites">Prerequisites</a>
- </li>
- <li>
- <a href="#DownloadCode">Installing the Tutorial Sample Code</a>
- </li>
- <li>
- <a href="#SetupEmulator">Setting Up the Emulator</a>
- </li>
- <li>
- <a href="#SetupProjects">Setting Up the Projects</a>
- </li>
- <li>
- <a href="#CreateTestCaseClass">Creating the Test Case Class</a>
- <ol>
- <li>
- <a href="#AddTestCaseClass">Adding the test case class file</a>
- </li>
- <li>
- <a href="#AddConstructor">Adding the test case constructor</a>
- </li>
- <li>
- <a href="#AddSetupMethod">Adding the setup method</a>
- </li>
- <li>
- <a href="#AddPreConditionsTest">Adding an initial conditions test</a>
- </li>
- <li>
- <a href="#AddUITest">Adding a UI test</a>
- </li>
- <li>
- <a href="#StateManagementTests">Adding state management tests</a>
- </li>
- </ol>
- </li>
- <li>
- <a href="#RunTests">Running the Tests and Seeing the Results</a>
- </li>
- <li>
- <a href="#TestFailure">Forcing Some Tests to Fail</a>
- </li>
- <li>
- <a href="#NextSteps">Next Steps</a>
- </li>
-</ol>
-<h2 id="#Appendix">Appendix</h2>
-<ol>
- <li>
- <a href="#InstallCompletedTestApp">Installing the Completed Test Application File</a>
- </li>
- <li>
- <a href="#EditorCommandLine">For Users Not Developing In Eclipse</a>
- </li>
-</ol>
-<h2>See Also</h2>
-<ol>
- <li>
- <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>
- </li>
- <li>
- {@link android.test.ActivityInstrumentationTestCase2}
- </li>
- <li>
- {@link junit.framework.Assert}
- </li>
- <li>
- {@link android.test.InstrumentationTestRunner}
- </li>
-</ol>
-</div>
-</div>
-<p>
- Android includes powerful tools for testing applications. The tools extend JUnit with additional features, provide convenience classes for mock Android system objects, and use
- instrumentation to give you control over your main application while you are testing it. The entire Android testing environment is discussed in the document
- <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>.
-</p>
-<p>
- This tutorial demonstrates the Android testing tools by presenting a simple Android application and then leading you step-by-step through the creation of a test application for it.
- The test application demonstrates these key points:
-</p>
- <ul>
- <li>
- An Android test is itself an Android application that is linked to the application under test by entries in its <code>AndroidManifest.xml</code> file.
- </li>
- <li>
- Instead of Android components, an Android test application contains one or more test cases. Each of these is a separate class definition.
- </li>
- <li>
- Android test case classes extend the JUnit {@link junit.framework.TestCase} class.
- </li>
- <li>
- Android test case classes for activities extend JUnit and also connect you to the application under test with instrumentation. You can send keystroke or touch events directly to the UI.
- </li>
- <li>
- You choose an Android test case class based on the type of component (application, activity, content provider, or service) you are testing.
- </li>
- <li>
- Additional test tools in Eclipse/ADT provide integrated support for creating test applications, running them, and viewing the results.
- </li>
- </ul>
-<p>
- The test application contains methods that perform the following tests:
-</p>
- <ul>
- <li>
- Initial conditions test. Tests that the application under test initializes correctly. This is also a unit test of the application's
- {@link android.app.Activity#onCreate(android.os.Bundle) onCreate()} method. Testing initial conditions also provides a confidence measure for subsequent tests.
- </li>
- <li>
- UI test. Tests that the main UI operation works correctly. This test demonstrates the instrumentation features available in activity testing.
- It shows that you can automate UI tests by sending key events from the test application to the main application.
- </li>
- <li>
- State management tests. Test the application's code for saving state. This test demonstrates the instrumentation features of the test runner, which
- are available for testing any component.
- </li>
- </ul>
-<h2 id="Prerequisites">Prerequisites</h2>
-<p>
- The instructions and code in this tutorial depend on the following:
-</p>
- <ul>
- <li>
- Basic knowledge of Android programming. If you haven't yet written an Android application,
- do the class
- <a href="{@docRoot}training/basics/firstapp/index.html">Building Your First App</a>.
- If you want to learn more about Spinner, the application under test, then you
- might want to review the "Spinner" sample app.
- </li>
- <li>
- Some familiarity with the Android testing framework and concepts. If you haven't explored
- Android testing yet, start by reading the
- <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>
- guide.
- </li>
- <li>
- Eclipse with ADT. This tutorial describes how to set up and run a test application using
- Eclipse with ADT. If you haven't yet installed Eclipse and the ADT plugin,
- follow the steps in <a href="{@docRoot}sdk/installing/index.html">Installing the SDK</a>
- to install them before continuing. If you are not developing in Eclipse, you will
- find instructions for setting up and running the test application in the
- <a href="#EditorCommandLine">appendix</a> of this document.
- </li>
- </ul>
-<h2 id="DownloadCode">Installing the Tutorial Sample Code</h2>
-<p>
- During this tutorial, you will be working with sample code that is provided as part
- of the downloadable Samples component of the SDK. Specifically, you will be working
- with a pair of related sample applications — an application under test and a test
- application:
-</p>
- <ul>
- <li>
- Spinner is the application under test. This tutorial focuses on the
- common situation of writing tests for an application that already exists, so the main
- application is provided to you.
- </li>
- <li>
- SpinnerTest is the test application. In the tutorial, you create this application
- step-by-step. If you want to run quickly through the tutorial,
- you can install the completed SpinnerTest application first, and then follow the
- text. You may get more from the tutorial, however, if you create the test application
- as you go. The instructions for installing the completed test application are in the
- section
- <a href="#InstallCompletedTestApp">Installing the Completed Test Application File</a>.
- </li>
- </ul>
-<p>
- The sample applications are described in more detail in the
- <a href="{@docRoot}tools/samples/index.html">Samples</a> topic. Follow the instructions to
- download the version of the samples that's appropriate for the platform you're working with.
-</p>
-<h2 id="SetupEmulator">Setting Up the Emulator</h2>
-<p>
- In this tutorial, you will use the Android emulator to run applications. The emulator needs
- an Android Virtual Device (AVD) with an API level equal to or higher than the one you set for the projects in the previous step.
- To find out how to check this and create the right AVD if necessary,
- see <a href="{@docRoot}tools/devices/managing-avds.html">Creating an AVD</a>.
-</p>
-<p>
- As a test of the AVD and emulator, run the SpinnerActivity application in Eclipse with ADT. When it starts,
- click the large downward-pointing arrow to the right of the spinner text. You see the spinner expand and display the title "Select a planet" at the top.
- Click one of the other planets. The spinner closes, and your selection appears below it on the screen.
-</p>
-<h2 id="SetupProjects">Setting Up the Projects</h2>
-<p>
- When you are ready to get started with the tutorial, begin by setting up Eclipse projects for
- both Spinner (the application under test) and SpinnerTest (the test application).
-</p>
-<p>
- You'll be using the Spinner application as-is, without modification, so you'll be loading it
- into Eclipse as a new Android project from existing source. In the process, you'll be
- creating a new test project associated with Spinner that will contain the SpinnerTest
- application. The SpinnerTest application will be completely new and you'll be
- using the code examples in this tutorial to add test classes and tests to it.
-</p>
-<p>
- To install the Spinner app in a new Android project from existing source, following these steps:
-</p>
-<ol>
- <li>
- In Eclipse, select <strong>File</strong> > <strong>New</strong> > <strong>Project</strong> > <strong>Android</strong> > <strong>Android Project</strong>,
- then click Next. The <strong>New Android Project</strong> dialog appears.
- </li>
- <li>
- In the <em>Project name</em> text box, enter "SpinnerActivity". The <em>Properties</em> area is filled in automatically.
- </li>
- <li>
- In the <em>Contents</em> area, set "Create project from existing source".
- </li>
- <li>
- For <em>Location</em>, click <strong>Browse</strong>, navigate to the directory <code><SDK_path>/samples/android-8/Spinner</code>,
- then click Open. The directory name <code><SDK_path>/samples/android-8/Spinner</code> now appears in the <em>Location</em> text box.
- </li>
- <li>
- In the <em>Build Target</em> area, set a API level of 3 or higher. If you are already developing with a particular target, and it is API level 3 or higher, then use that target.
- </li>
- <li>
- In the <em>Properties</em> area, in the <em>Min SDK Version:</em>, enter "3".
- </li>
- <li>
- You should now see these values:
- <ul>
- <li><em>Project Name:</em> "SpinnerActivity"</li>
- <li><em>Create project from existing source:</em> set</li>
- <li><em>Location:</em> "<code><SDK_path>/samples/android-8/Spinner</code>"</li>
- <li><em>Build Target:</em> "API level of 3 or higher" (<em>Target Name</em> "Android 1.5 or higher")</li>
- <li><em>Package name:</em> (disabled, set to "<code>com.android.example.spinner</code>")</li>
- <li><em>Create Activity:</em> (disabled, set to ".SpinnerActivity")</li>
- <li><em>Min SDK Version:</em> "3"</li>
- </ul>
- <p>
- The following screenshot summarizes these values:
- </p>
- <a href="{@docRoot}images/testing/eclipse_new_android_project_complete_callouts.png">
- <img src="{@docRoot}images/testing/eclipse_new_android_project_complete_callouts.png" alt="New Android Project dialog with filled-in values" style="height:230px"/>
- </a>
-
- </li>
-</ol>
-<p>
- To create a new test project for the SpinnerTest application, follow these steps:
-</p>
-<ol>
- <li>
- Click Next. The <strong>New Android Test Project</strong> dialog appears.
- </li>
- <li>
- Set "Create a Test Project".
- </li>
- <li>
- Leave the other values unchanged. The result should be:
- <ul>
- <li><em>Create a Test Project:</em> checked</li>
- <li><em>Test Project Name:</em> "SpinnerActivityTest"</li>
- <li><em>Use default location:</em> checked (this should contain the directory name "<code>workspace/SpinnerActivityTest</code>").</li>
- <li><em>Build Target:</em> Use the same API level you used in the previous step.</li>
- <li><em>Application name:</em> "SpinnerActivityTest"</li>
- <li><em>Package name:</em> "<code>com.android.example.spinner.test</code>"</li>
- <li><em>Min SDK Version:</em> "3"</li>
- </ul>
- <p>
- The following screenshot summarizes these values:
- </p>
- <a href="{@docRoot}images/testing/eclipse_new_android_testproject_complete_callouts.png">
- <img src="{@docRoot}images/testing/eclipse_new_android_testproject_complete_callouts.png" alt="New Android Test Project dialog with filled-in values" style="height:230px"/>
- </a>
- </li>
- <li>
- Click Finish. Entries for SpinnerActivity and SpinnerActivityTest should appear in the
- <strong>Package Explorer</strong>.
- <p class="note">
- <strong>Note:</strong> If you set <em>Build Target</em> to an API level higher than "3", you will see the warning
- "The API level for the selected SDK target does not match the Min SDK version". You do not need to change the API level or the Min SDK version.
- The message tells you that you are building the projects with one particular API level, but specifying that a lower API level is required. This may
- occur if you have chosen not to install the optional earlier API levels.
- </p>
- <p>
- If you see errors listed in the <strong>Problems</strong> pane at the bottom of the Eclipse window, or if a red error marker appears next to
- the entry for SpinnerActivity in the Package Explorer, highlight the SpinnerActivity entry and then select
- <strong>Project</strong> > <strong>Clean</strong>. This should fix any errors.
- </p>
- </li>
-</ol>
-<p>
- You now have the application under test in the SpinnerActivity project,
- and an empty test project in SpinnerActivityTest. You may
- notice that the two projects are in different directories, but Eclipse with
- ADT handles this automatically. You should have no problem in either building or running them.
-</p>
-<p>
- Notice that Eclipse and ADT have already done some initial setup for your test application.
- Expand the SpinnerActivityTest project, and notice that it already has an
- Android manifest file <code>AndroidManifest.xml</code>.
- Eclipse with ADT created this when you added the test project.
- Also, the test application is already set up to use instrumentation. You can see this
- by examining <code>AndroidManifest.xml</code>.
- Open it, then at the bottom of the center pane click <strong>AndroidManifest.xml</strong>
- to display the XML contents:
-</p>
-<pre>
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.example.spinner.test"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="3" />
- <instrumentation
- android:targetPackage="com.android.example.spinner"
- android:name="android.test.InstrumentationTestRunner" />
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <uses-library android:name="android.test.runner" />
- ...
- </application>
-</manifest>
-</pre>
-<p>
- Notice the <code><instrumentation></code> element. The attribute
- <code>android:targetPackage="com.android.example.spinner"</code> tells Android that the
- application under test is defined in the Android package
- <code>com.android.example.spinner</code>. Android now knows to use that
- package's <code>AndroidManifest.xml</code> file to launch the application under test.
- The <code><instrumentation></code> element also contains the attribute
- <code>android:name="android.test.InstrumentationTestRunner"</code>, which tells Android
- instrumentation to run the test application with Android's instrumentation-enabled test runner.
-</p>
-<h2 id="CreateTestCaseClass">Creating the Test Case Class</h2>
-
-<p>
- You now have a test project SpinnerActivityTest, and the basic structure of a test
- application also called SpinnerActivityTest. The basic structure includes all the files and
- directories you need to build and run a test application, except for the class that
- contains your tests (the test case class).
-</p>
-<p>
- The next step is to define the test case class. In this tutorial, you'll be creating a
- test case class that includes:
-</p>
-<ul>
- <li>
- Test setup. This use of the JUnit {@link junit.framework.TestCase#setUp() setUp()}
- method demonstrates some of the tasks you might perform before running an Android test.
- </li>
- <li>
- Testing initial conditions. This test demonstrates a good testing technique.
- It also demonstrates that with Android instrumentation you can look at the application
- under test <em>before</em> the main activity starts. The test checks that the application's
- important objects have been initialized.
- If the test fails, you then know that any other tests against the application are
- unreliable, since the application was running in an incorrect state.
- <p class="note">
- <strong>Note:</strong> The purpose of testing initial conditions is not the same as
- using <code>setUp()</code>. The JUnit {@link junit.framework.TestCase#setUp()} runs once
- before <strong>each test method</strong>, and its purpose is to create a clean test
- environment. The initial conditions test runs once, and its purpose is to verify that the
- application under test is ready to be tested.
- </p>
- </li>
- <li>
- Testing the UI. This test shows how to control the main application's UI
- with instrumentation, a powerful automation feature of Android testing.
- </li>
- <li>
- Testing state management. This test shows some techniques for testing how
- well the application maintains state in the Android environment. Remember that to
- provide a satisfactory user experience, your application must never lose its current state,
- even if it's interrupted by a phone call or destroyed because of memory constraints.
- The Android activity lifecycle provides ways to maintain state, and the
- <code>SpinnerActivity</code> application uses them. The test shows the techniques for
- verifying that they work.
- </li>
-</ul>
-<p>
- Android tests are contained in a special type of Android application that contains one or more test class definitions. Each of these contains
- one or more test methods that do the actual tests. In this tutorial, you will first add a test case class, and then add tests to it.
-</p>
-<p>
- You first choose an Android test case class to extend. You choose from the base test case classes according to the Android component you are testing and the types of tests you are doing.
- In this tutorial, the application under test has a single simple activity, so the test case class will be for an Activity component. Android offers several, but the one that tests in
- the most realistic environment is {@link android.test.ActivityInstrumentationTestCase2}, so you will use it as the base class. Like all activity test case classes,
- <code>ActivityInstrumentationTestCase2</code> offers convenience methods for interacting directly with the UI of the application under test.
-</p>
-<h3 id="AddTestCaseClass">Adding the test case class file</h3>
-<p>
- To add <code>ActivityInstrumentationTestCase2</code> as the base test case class, follow these steps:
-</p>
-<ol>
- <li>
- In the Package Explorer, expand the test project SpinnerActivityTest if it is not open already.
- </li>
- <li>
- Within SpinnerActivityTest, expand the <code>src/</code> folder and then the package marker for
- <code>com.android.example.spinner.test</code>. Right-click on the package name and select <strong>New</strong> > <strong>Class</strong>:<br/>
- <a href="{@docRoot}images/testing/spinner_create_test_class_callouts.png">
- <img alt="Menu for creating a new class in the test application" src="{@docRoot}images/testing/spinner_create_test_class_callouts.png" style="height:230px"/>
- </a>
- <p>
- The <strong>New Java Class</strong> wizard appears:
- </p>
- <a href="{@docRoot}images/testing/spinnertest_new_class_callouts.png">
- <img alt="New Java Class wizard dialog" src="{@docRoot}images/testing/spinnertest_new_class_callouts.png" style="height:230px"/>
- </a>
- </li>
- <li>
- In the wizard, enter the following:
- <ul>
- <li>
- <em>Name:</em> "SpinnerActivityTest". This becomes the name of your test class.
- </li>
- <li>
- <em>Superclass:</em> "<code>android.test.ActivityInstrumentationTestCase2<SpinnerActivity></code>". The superclass is parameterized, so
- you have to provide it your main application's class name.
- </li>
- </ul>
- <p>
- Do not change any of the other settings. Click Finish.
- </p>
- </li>
- <li>
- You now have a new file <code>SpinnerActivityTest.java</code> in the project.
- </li>
- <li>
- To resolve the reference to SpinnerActivity, add the following import:
-<pre>
-import com.android.example.spinner.SpinnerActivity;
-</pre>
- </li>
-</ol>
-<h3 id="AddConstructor">Adding the test case constructor</h3>
- <p>
- To ensure that the test application is instantiated correctly, you must set up a constructor that the test
- runner will call when it instantiates your test class. This constructor has no parameters, and its sole
- purpose is to pass information to the superclass's default constructor. To set up this constructor, enter the
- following code in the class:
- </p>
-<pre>
- public SpinnerActivityTest() {
- super(SpinnerActivity.class);
- } // end of SpinnerActivityTest constructor definition
-</pre>
-<p>
- This calls the superclass constructor with the main activity's class (<code>SpinnerActivity.class</code>) for the application under test. Android uses this information to find the application and activity to test.
-</p>
-<p>
- You are now ready to add tests, by adding test methods to the class.
-</p>
-<h3 id="AddSetupMethod">Adding the setup method</h3>
-<p>
- The <code>setUp()</code> method is invoked before every test. You use it to initialize variables and clean up from previous tests. You can also use
- the JUnit {@link junit.framework.TestCase#tearDown() tearDown()} method, which runs <strong>after</strong> every test method. The tutorial does not use it.
-</p>
-<p>
- The method you are going to add does the following:
-</p>
-<ul>
- <li>
- <code>super.setUp()</code>. Invokes the superclass constructor for <code>setUp()</code>, which is required by JUnit.
- </li>
- <li>
- Calls {@link android.test.ActivityInstrumentationTestCase2#setActivityInitialTouchMode(boolean) setActivityInitialTouchMode(false)}.
- This turns off <strong>touch mode</strong> in the device or emulator. If any of your test methods send key events to the application,
- you must turn off touch mode <em>before</em> you start any activities; otherwise, the call is ignored.
- </li>
- <li>
- Stores references to system objects. Retrieves and stores a reference to the activity under test, the <code>Spinner</code>
- widget used by the activity, the <code>SpinnerAdapter</code> that backs the widget, and the string value of the selection that is
- set when the application is first installed. These objects are used in the state management test. The methods invoked are:
- <ul>
- <li>
- {@link android.test.ActivityInstrumentationTestCase2#getActivity()}. Gets a reference to the activity under test (<code>SpinnerActivity</code>).
- This call also starts the activity if it is not already running.
- </li>
- <li>
- {@link android.app.Activity#findViewById(int)}. Gets a reference to the <code>Spinner</code> widget of the application under test.
- </li>
- <li>
- {@link android.widget.AbsSpinner#getAdapter()}. Gets a reference to the adapter (an array of strings) backing the spinner.
- </li>
- </ul>
- </li>
-</ul>
-<p>
- Add this code to the definition of <code>SpinnerActivityTest</code>, after the constructor definition:
-</p>
-<pre>
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- setActivityInitialTouchMode(false);
-
- mActivity = getActivity();
-
- mSpinner =
- (Spinner) mActivity.findViewById(
- com.android.example.spinner.R.id.Spinner01
- );
-
- mPlanetData = mSpinner.getAdapter();
-
- } // end of setUp() method definition
-</pre>
-<p>
- Add these members to the test case class:
-</p>
-<pre>
- private SpinnerActivity mActivity;
- private Spinner mSpinner;
- private SpinnerAdapter mPlanetData;
-</pre>
-<p>
- Add these imports:
-</p>
-<pre>
-import android.widget.Spinner;
-import android.widget.SpinnerAdapter;
-</pre>
-<p>
- You now have the complete <code>setUp()</code> method.
-</p>
-<h3 id="AddPreConditionsTest">Adding an initial conditions test</h3>
-<p>
- The initial conditions test verifies that the application under test is initialized correctly. It is an illustration of the types of tests you can run, so it is not comprehensive.
- It verifies the following:
-</p>
-<ul>
- <li>
- The item select listener is initialized. This listener is called when a selection is made from the spinner.
- </li>
- <li>
- The adapter that provides values to the spinner is initialized.
- </li>
- <li>
- The adapter contains the right number of entries.
- </li>
-</ul>
-<p>
- The actual initialization of the application under test is done in <code>setUp()</code>, which the test runner calls automatically before every test. The verifications are
- done with JUnit {@link junit.framework.Assert} calls. As a useful convention, the method name is <code>testPreConditions()</code>:
-</p>
-<pre>
- public void testPreConditions() {
- assertTrue(mSpinner.getOnItemSelectedListener() != null);
- assertTrue(mPlanetData != null);
- assertEquals(mPlanetData.getCount(),ADAPTER_COUNT);
- } // end of testPreConditions() method definition
-</pre>
-<p>
- Add this member:
-</p>
-<pre>
- public static final int ADAPTER_COUNT = 9;
-</pre>
-<h3 id="AddUITest">Adding a UI test</h3>
-<p>
- Now create a UI test that selects an item from the <code>Spinner</code> widget. The test sends key events to the UI with key events.
- The test confirms that the selection matches the result you expect.
-</p>
-<p>
- This test demonstrates the power of using instrumentation in Android testing. Only an instrumentation-based test class allows you to send key events (or touch events)
- to the application under test. With instrumentation, you can test your UI without having to take screenshots, record the screen, or do human-controlled testing.
-</p>
-<p>
- To work with the spinner, the test has to request focus for it and then set it to a known position. The test uses {@link android.view.View#requestFocus() requestFocus()} and
- {@link android.widget.AbsSpinner#setSelection(int) setSelection()} to do this. Both of these methods interact with a View in the application under test, so you have to call them
- in a special way.
-</p>
-<p>
- Code in a test application that interacts with a View of the application under test must run in the main application's thread, also
- known as the <em>UI thread</em>. To do this, you use the {@link android.app.Activity#runOnUiThread(java.lang.Runnable) Activity.runOnUiThread()}
- method. You pass the code to <code>runOnUiThread()</code>in an anonymous {@link java.lang.Runnable Runnable} object. To set
- the statements in the <code>Runnable</code> object, you override the object's {@link java.lang.Runnable#run()} method.
-</p>
-<p>
- To send key events to the UI of the application under test, you use the <a href="{@docRoot}reference/android/test/InstrumentationTestCase.html#sendKeys(int...)">sendKeys</a>() method.
- This method does not have to run on the UI thread, since Android uses instrumentation to pass the key events to the application under test.
-</p>
-<p>
- The last part of the test compares the selection made by sending the key events to a pre-determined value. This tests that the spinner is working as intended.
-</p>
-<p>
- The following sections show you how to add the code for this test.
-</p>
-<ol>
- <li>
- Get focus and set selection. Create a new method <code>public void testSpinnerUI()</code>. Add
- code to to request focus for the spinner and set its position to default or initial position, "Earth". This code is run on the UI thread of
- the application under test:
-<pre>
- public void testSpinnerUI() {
-
- mActivity.runOnUiThread(
- new Runnable() {
- public void run() {
- mSpinner.requestFocus();
- mSpinner.setSelection(INITIAL_POSITION);
- } // end of run() method definition
- } // end of anonymous Runnable object instantiation
- ); // end of invocation of runOnUiThread
-</pre>
- <p>
- Add the following member to the test case class.
- </p>
-<pre>
- public static final int INITIAL_POSITION = 0;
-</pre>
- </li>
- <li>
- Make a selection. Send key events to the spinner to select one of the items. To do this, open the spinner by
- "clicking" the center keypad button (sending a DPAD_CENTER key event) and then clicking (sending) the down arrow keypad button five times. Finally,
- click the center keypad button again to highlight the desired item. Add the following code:
-<pre>
- this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
- for (int i = 1; i <= TEST_POSITION; i++) {
- this.sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
- } // end of for loop
-
- this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
-</pre>
- <p>
- Add the following member to the test case class:
- </p>
-<pre>
- public static final int TEST_POSITION = 5;
-</pre>
- <p>
- This sets the final position of the spinner to "Saturn" (the spinner's backing adapter is 0-based).
- </p>
- </li>
- <li>
- Check the result. Query the current state of the spinner, and compare its current selection to the expected value.
- Call the method {@link android.widget.AdapterView#getSelectedItemPosition() getSelectedItemPosition()} to find out the current selection position, and then
- {@link android.widget.AdapterView#getItemAtPosition(int) getItemAtPosition()} to get the object corresponding to that position (casting it to a String). Assert that
- this string value matches the expected value of "Saturn":
-<pre>
- mPos = mSpinner.getSelectedItemPosition();
- mSelection = (String)mSpinner.getItemAtPosition(mPos);
- TextView resultView =
- (TextView) mActivity.findViewById(
- com.android.example.spinner.R.id.SpinnerResult
- );
-
- String resultText = (String) resultView.getText();
-
- assertEquals(resultText,mSelection);
-
- } // end of testSpinnerUI() method definition
-</pre>
-<p>
- Add the following members to the test case class:
-</p>
-<pre>
- private String mSelection;
- private int mPos;
-</pre>
- <p>
- Add the following imports to the test case class:
- </p>
-<pre>
- import android.view.KeyEvent;
- import android.widget.TextView;
-</pre>
- </li>
-</ol>
-<p>
- Pause here to run the tests you have. The procedure for running a test application is different
- from running a regular Android application. You run a test application as an Android JUnit
- application. To see how to do this, see <a href="#RunTests">Running the Tests and Seeing the Results</a>.
-</p>
-<p>
- Eventually, you will see the <code>SpinnerActivity</code> application start, and the test
- application controlling it by sending it key events. You will also see a new
- <strong>JUnit</strong> view in the Explorer pane, showing the results of the
- test. The JUnit view is documented in a following section,
- <a href="#RunTests">Running the Test and Seeing the Results</a>.
-</p>
-<h3 id="StateManagementTests">Adding state management tests</h3>
-<p>
- You now write two tests that verify that SpinnerActivity maintains its state when it is paused or terminated.
- The state, in this case, is the current selection in the spinner. When users make a selection,
- pause or terminate the application, and then resume or restart it, they should see
- the same selection.
-</p>
-<p>
- Maintaining state is an important feature of an application. Users may switch from the current
- application temporarily to answer the phone, and then switch back. Android may decide to
- terminate and restart an activity to change the screen orientation, or terminate an unused
- activity to regain storage. In each case, users are best served by having the UI return to its
- previous state (except where the logic of the application dictates otherwise).
-</p>
-<p>
- SpinnerActivity manages its state in these ways:
-</p>
- <ul>
- <li>
- Activity is hidden. When the spinner screen (the activity) is running but hidden by some other screen, it
- stores the spinner's position and value in a form that persists while the application is running.
- </li>
- <li>
- Application is terminated. When the activity is terminated, it stores the spinner's position and value in
- a permanent form. The activity can read the position and value when it restarts, and restore the spinner to its previous state.
- </li>
- <li>
- Activity re-appears. When the user returns to the spinner screen, the previous selection is restored.
- </li>
- <li>
- Application is restarted. When the user starts the application again, the previous selection is restored.
- </li>
- </ul>
-<p class="note">
- <strong>Note:</strong> An application can manage its state in other ways as well, but these are
- not covered in this tutorial.
-</p>
-<p>
- When an activity is hidden, it is <strong>paused</strong>. When it re-appears, it
- <strong>resumes</strong>. Recognizing that these are key points in an activity's life cycle,
- the Activity class provides two callback methods {@link android.app.Activity#onPause()} and
- {@link android.app.Activity#onResume()} for handling pauses and resumes.
- SpinnerActivity uses them for code that saves and restores state.
-</p>
-<p>
- <strong>Note:</strong> If you would like to learn more about the difference between losing
- focus/pausing and killing an application,
- read about the <a href="{@docRoot}guide/components/activities.html#Lifecycle">activity
-lifecycle</a>.
-</p>
-<p>
- The first test verifies that the spinner selection is maintained after the entire application is shut down and then restarted. The test uses instrumentation to
- set the spinner's variables outside of the UI. It then terminates the activity by calling {@link android.app.Activity#finish() Activity.finish()}, and restarts it
- using the instrumentation method {@link android.test.ActivityInstrumentationTestCase2#getActivity()}. The test then asserts that the current spinner state matches
- the test values.
-</p>
-<p>
- The second test verifies that the spinner selection is maintained after the activity is paused and then resumed. The test uses instrumentation to
- set the spinner's variables outside of the UI and then force calls to the <code>onPause()</code> and <code>onResume()</code> methods. The test then
- asserts that the current spinner state matches the test values.
-</p>
-<p>
- Notice that these tests make limited assumptions about the mechanism by which the activity manages state. The tests use the activity's getters and
- setters to control the spinner. The first test also knows that hiding an activity calls <code>onPause()</code>, and bringing it back to the foreground
- calls <code>onResume()</code>. Other than this, the tests treat the activity as a "black box".
-</p>
-<p>
- To add the code for testing state management across shutdown and restart, follow these steps:
-</p>
- <ol>
- <li>
- Add the test method <code>testStateDestroy()</code>, then
- set the spinner selection to a test value:
-<pre>
- public void testStateDestroy() {
- mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION);
- mActivity.setSpinnerSelection(TEST_STATE_DESTROY_SELECTION);
-</pre>
- </li>
- <li>
- Terminate the activity and restart it:
-<pre>
- mActivity.finish();
- mActivity = this.getActivity();
-</pre>
- </li>
- <li>
- Get the current spinner settings from the activity:
-<pre>
- int currentPosition = mActivity.getSpinnerPosition();
- String currentSelection = mActivity.getSpinnerSelection();
-</pre>
- </li>
- <li>
- Test the current settings against the test values:
-<pre>
- assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition);
- assertEquals(TEST_STATE_DESTROY_SELECTION, currentSelection);
- } // end of testStateDestroy() method definition
-</pre>
-<p>
- Add the following members to the test case class:
-<pre>
- public static final int TEST_STATE_DESTROY_POSITION = 2;
- public static final String TEST_STATE_DESTROY_SELECTION = "Earth";
-</pre>
- </li>
- </ol>
-<p>
- To add the code for testing state management across a pause and resume, follow these steps:
-</p>
-<ol>
- <li>
- Add the test method <code>testStatePause()</code>:
-<pre>
- @UiThreadTest
- public void testStatePause() {
-</pre>
- <p>
- The <code>@UiThreadTest</code> annotation tells Android to build this method so that it runs
- on the UI thread. This allows the method to change the state of the spinner widget in the
- application under test. This use of <code>@UiThreadTest</code> shows that, if necessary, you
- can run an entire method on the UI thread.
- </p>
- </li>
- <li>
- Set up instrumentation. Get the instrumentation object
- that is controlling the application under test. This is used later to
- invoke the <code>onPause()</code> and <code>onResume()</code> methods:
-<pre>
- Instrumentation mInstr = this.getInstrumentation();
-</pre>
- </li>
- <li>
- Set the spinner selection to a test value:
-<pre>
- mActivity.setSpinnerPosition(TEST_STATE_PAUSE_POSITION);
- mActivity.setSpinnerSelection(TEST_STATE_PAUSE_SELECTION);
-</pre>
- </li>
- <li>
- Use instrumentation to call the Activity's <code>onPause()</code>:
-<pre>
- mInstr.callActivityOnPause(mActivity);
-</pre>
- <p>
- Under test, the activity is waiting for input. The invocation of
- {@link android.app.Instrumentation#callActivityOnPause(android.app.Activity)}
- performs a call directly to the activity's <code>onPause()</code> instead
- of manipulating the activity's UI to force it into a paused state.
- </p>
- </li>
- <li>
- Force the spinner to a different selection:
-<pre>
- mActivity.setSpinnerPosition(0);
- mActivity.setSpinnerSelection("");
-</pre>
- <p>
- This ensures that resuming the activity actually restores the
- spinner's state rather than simply leaving it as it was.
- </p>
- </li>
- <li>
- Use instrumentation to call the Activity's <code>onResume()</code>:
-<pre>
- mInstr.callActivityOnResume(mActivity);
-</pre>
- <p>
- Invoking {@link android.app.Instrumentation#callActivityOnResume(android.app.Activity)}
- affects the activity in a way similar to <code>callActivityOnPause</code>. The
- activity's <code>onResume()</code> method is invoked instead of manipulating the
- activity's UI to force it to resume.
- </p>
- </li>
- <li>
- Get the current state of the spinner:
-<pre>
- int currentPosition = mActivity.getSpinnerPosition();
- String currentSelection = mActivity.getSpinnerSelection();
-</pre>
- </li>
- <li>
- Test the current spinner state against the test values:
-<pre>
- assertEquals(TEST_STATE_PAUSE_POSITION,currentPosition);
- assertEquals(TEST_STATE_PAUSE_SELECTION,currentSelection);
- } // end of testStatePause() method definition
-</pre>
- <p>
- Add the following members to the test case class:
- </p>
-<pre>
- public static final int TEST_STATE_PAUSE_POSITION = 4;
- public static final String TEST_STATE_PAUSE_SELECTION = "Jupiter";
-</pre>
- </li>
- <li>
- Add the following imports:
-<pre>
- import android.app.Instrumentation;
- import android.test.UiThreadTest;
-</pre>
- </li>
-</ol>
-<h2 id="RunTests">Running the Tests and Seeing the Results</h2>
- <p>
- The most simple way to run the <code>SpinnerActivityTest</code> test case is to run it directly from the Package Explorer.
- </p>
- <p>
- To run the <code>SpinnerActivityTest</code> test, follow these steps:
-</p>
- <ol>
- <li>
- In the Package Explorer, right-click the project SpinnerActivityTest at the top level, and then
- select <strong>Run As</strong> > <strong>Android JUnit Test</strong>:<br/>
- <a href="{@docRoot}images/testing/spinnertest_runas_menu_callouts.png">
- <img alt="Menu to run a test as an Android JUnit test" src="{@docRoot}images/testing/spinnertest_runas_menu_callouts.png" style="height:230px">
- </a>
- </li>
- <li>
- You will see the emulator start. When the unlock option is displayed (its appearance depends on the API level you specified for the AVD),
- unlock the home screen.
- </li>
- <li>
- The test application starts. You see a new tab for the <strong>JUnit</strong> view, next to the Package Explorer tab:<br/>
- <a href="{@docRoot}images/testing/spinnertest_junit_panel.png">
- <img alt="The JUnit window" src="{@docRoot}images/testing/spinnertest_junit_panel.png" style="height:230px">
- </a>
- </li>
-</ol>
-<p>
- This view contains two sub-panes. The top pane summarizes the tests that were run, and the bottom pane shows failure traces for
- highlighted tests.
-</p>
-<p>
- At the conclusion of a successful test run, this is the view's appearance:<br/>
- <a href="{@docRoot}images/testing/spinnertest_junit_success.png">
- <img src="{@docRoot}images/testing/spinnertest_junit_success.png" alt="JUnit test run success" style="height:230px"/>
- </a>
-</p>
-<p>
- The upper pane summarizes the test:
-</p>
- <ul>
- <li>
- Total time elapsed for the test application(labeled <em>Finished after <x> seconds</em>).
- </li>
- <li>
- Number of runs (<em>Runs:</em>) - the number of tests in the entire test class.
- </li>
- <li>
- Number of errors (<em>Errors:</em>) - the number of program errors and exceptions encountered during
- the test run.
- </li>
- <li>
- Number of failures (<em>Failures:</em>) - the number of test failures encountered during the test
- run. This is the number of assertion failures. A test can fail even if the program does not encounter an error.
- </li>
- <li>
- A progress bar. The progress bar extends from left to right as the tests run.
- <p>
- If all the tests succeed, the bar remains green. If a test fails, the bar turns from green to red.
- </p>
- </li>
- <li>
- A test method summary. Below the bar, you see a line for each class in the test application. To look at the results for the individual
- methods in a test, click the arrow at the left to expand the line. You see the name of each test method. To the
- right of the name, you see the time taken by the test. You can look at the test's code
- by double-clicking its name.
- </li>
- </ul>
-<p>
- The lower pane contains the failure trace. If all the tests are successful, this pane is empty. If some tests fail,
- then if you highlight a failed test in the upper pane, the lower view contains a stack trace for the test. This is
- demonstrated in the next section.
-</p>
-<p class="note">
- <strong>Note:</strong> If you run the test application and nothing seems to happen, look for
- the JUnit view. If you do not see it, you may have run the test application
- as a regular Android application.
- Remember that you need to run it as an Android <strong>JUnit</strong>
- application.
-</p>
-<h2 id="TestFailure">Forcing Some Tests to Fail</h2>
-<p>
- A test is as useful when it fails as when it succeeds. This section shows what happens in Eclipse with ADT when a test fails. You
- can quickly see that a test class has failed, find the method or methods that failed, and then use a failure trace to find
- the exact problem.
-</p>
-<p>
- The example application SpinnerActivity that you downloaded passes all the tests in the test application SpinnerActivityTest.
- To force the test to fail, you must modify the example application. You change a line of setup code in the application under test. This
- causes the <code>testPreConditions()</code> and <code>testTextView()</code> test methods to fail.
-</p>
-<p>
- To force the tests to fail, follow these steps:
-</p>
-<ol>
- <li>
- In Eclipse with ADT, go to the SpinnerActivity project and open the file <code>SpinnerActivity.java</code>.
- </li>
- <li>
- At the top of <code>SpinnerActivity.java</code>, at the end of the <code>onCreate()</code> method, find the following line:
-<pre>
- // mySpinner.setOnItemSelectedListener(null);
-</pre>
- <p>Remove the forward slash characters at the beginning of the line to
- uncomment the line. This sets the listener callback to null:
- </p>
-<pre>
- mySpinner.setOnItemSelectedListener(null);
-</pre>
- </li>
- <li>
- The <code>testPreConditions()</code> method in <code>SpinnerActivityTest</code> contains the following test:
- <code>assertTrue(mSpinner.getOnItemSelectedListener() != null);</code>. This test asserts that the listener callback is <em>not</em> null.
- Since you have modified the application under test, this assertion now fails.
- </li>
- <li>
- Run the test, as described in the previous section <a href="#RunTests">Running the Tests and Seeing the Results</a>.
- </li>
-</ol>
-<p>
- The JUnit view is either created or updated with the results of the test. Now, however, the progress bar is red,
- the number of failures is 2, and small "x" icons appear in the list icons next to the testPreConditions and
- TestSpinnerUI tests. This indicates that the tests have failed. The display is similar to this:<br/>
- <a href="{@docRoot}images/testing/spinnertest_junit_panel_fail_callouts.png">
- <img src="{@docRoot}images/testing/spinnertest_junit_panel_fail_callouts.png" alt="The JUnit Failure window" style="height:230px"/>
- </a>
-</p>
-<p>
- You now want to look at the failures to see exactly where they occurred.
-</p>
-<p>
- To examine the failures, follow these steps:
-</p>
-<ol>
- <li>
- Click the testPreconditions entry. In the lower pane entitled <strong>Failure Trace</strong>,
- you see a stack trace of the calls that led to the failure. This trace is similar to the following screenshot:<br/>
- <a href="{@docRoot}images/testing/spinnertest_junit_panel_failtrace_callouts.png">
- <img src="{@docRoot}images/testing/spinnertest_junit_panel_failtrace_callouts.png" alt="The JUnit failure trace" style="height:230px"/>
- </a>
- </li>
- <li>
- The first line of the trace tells you the error. In this case, a JUnit assertion failed. To look at the
- assertion in the test code, double-click the next line (the first line of the trace). In the center pane
- a new tabbed window opens, containing the code for the test application <code>SpinnerActivityTest</code>. The failed assertion
- is highlighted in the middle of the window.
- </li>
-</ol>
-<p>
- The assertion failed because you modified the main application to set the <code>getOnItemSelectedListener</code> callback to <code>null</code>.
-</p>
-<p>
- You can look at the failure in <code>testTextView</code> if you want. Remember, though, that <code>testPreConditions</code> is meant to verify the
- initial setup of the application under test. If testPreConditions() fails, then succeeding tests can't be trusted. The best strategy to follow is to
- fix the problem and re-run all the tests.
-</p>
-<p>
- Remember to go back to <code>SpinnerActivity.java</code> and re-comment the line you uncommented in an earlier step.
-</p>
-<p>
- You have now completed the tutorial.
-</p>
-<h2 id="NextSteps">Next Steps</h2>
-<p>
- This example test application has shown you how to create a test project and link it to
- the application you want to test, how to choose and add a test case class, how to write
- UI and state management tests, and how to run the tests against the application under
- test. Now that you are familiar with the basics of testing Android applications, here
- are some suggested next steps:
-</p>
-<p>
- <strong>Learn more about testing on Android</strong>
-</p>
-<ul>
- <li>
- If you haven't done so already, read the
- <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>
- document in the <em>Dev Guide</em>. It provides an overview of how testing on Android
- works. If you are just getting started with Android testing, reading that document will
- help you understand the tools available to you, so that you can develop effective
- tests.
- </li>
-</ul>
-<p>
- <strong>Review the main Android test case classes</strong>
-</p>
-<ul>
- <li>
- {@link android.test.ActivityInstrumentationTestCase2}
- </li>
- <li>
- {@link android.test.ActivityUnitTestCase}
- </li>
- <li>
- {@link android.test.ProviderTestCase2}
- </li>
- <li>
- {@link android.test.ServiceTestCase}
- </li>
-</ul>
-<p>
- <strong>Learn more about the assert and utility classes</strong>
-</p>
-<ul>
- <li>
- {@link junit.framework.Assert}, the JUnit Assert class.
- </li>
- <li>
- {@link android.test.MoreAsserts}, additional Android assert methods.
- </li>
- <li>
- {@link android.test.ViewAsserts}, useful assertion methods for testing Views.
- </li>
- <li>
- {@link android.test.TouchUtils}, utility methods for simulating touch events in an Activity.
- </li>
-</ul>
-<p>
- <strong>Learn about instrumentation and the instrumented test runner</strong>
-</p>
-<ul>
- <li>
- {@link android.app.Instrumentation}, the base instrumentation class.
- </li>
- <li>
- {@link android.test.InstrumentationTestCase}, the base instrumentation test case.
- </li>
- <li>
- {@link android.test.InstrumentationTestRunner}, the standard Android test runner.
- </li>
-</ul>
-<h2 id="Appendix">Appendix</h2>
-<h3 id="InstallCompletedTestApp">Installing the Completed Test Application File</h3>
-<p>
- The recommended approach to this tutorial is to follow the instructions step-by-step and
- write the test code as you go. However, if you want to do this tutorial quickly,
- you can install the entire file for the test application into the test project.
-</p>
-<p>
- To do this, you first create a test project with the necessary structure and files by using
- the automated tools in Eclipse. Then you exit Eclipse and copy the test application's file
- from the SpinnerTest sample project into your test project. The SpinnerTest sample project is
- part of the Samples component of the SDK.
-</p>
-<p>
- The result is a complete test application, ready to run against the Spinner sample application.
-</p>
-<p>
- To install the test application file, follow these steps:
-</p>
-<ol>
- <li>
- Set up the projects for the application under test and the test application, as described
- in the section section <a href="#SetupProjects">Setting Up the Projects</a>.
- </li>
- <li>
- Set up the emulator, as described in the section <a href="#SetupEmulator">Setting Up the Emulator</a>.
- </li>
- <li>
- Add the test case class, as described in the section <a href="#AddTestCaseClass">Adding the test case class file</a>.
- </li>
- <li>
- Close Eclipse with ADT.
- </li>
- <li>
- Copy the file <code><SDK_path>/samples/android-8/SpinnerTest/src/com/android/example/spinner/test/SpinnerActivityTest.java</code>
- to the directory <code>workspace/SpinnerActivityTest/src/com/android/example/spinner/test/</code>.
- </li>
- <li>
- Restart Eclipse with ADT.
- </li>
- <li>
- In Eclipse with ADT, re-build the project <code>SpinnerActivityTest</code> by selecting it in the Package Explorer, right-clicking,
- and selecting <em>Project</em> > <em>Clean</em>.
- </li>
- <li>
- The complete, working test application should now be in the <code>SpinnerActivityTest</code> project.
- </li>
-</ol>
-<p>
- You can now continue with the tutorial, starting at the section <a href="#AddConstructor">Adding the test case constructor</a> and
- following along in the text.
-</p>
-<h3 id="EditorCommandLine">For Users Not Developing In Eclipse</h3>
-<p>
- If you are not developing in Eclipse, you can still do this tutorial. Android provides tools for
- creating test applications using a code editor and command-line tools. You use the following tools:
-</p>
-<ul>
- <li>
- <a href="{@docRoot}tools/help/adb.html">adb</a> - Installs and uninstalls applications and test applications to a device or the emulator. You
- also use this tool to run the test application from the command line.
- </li>
- <li>
- <a href="{@docRoot}tools/help/android.html">android</a> - Manages projects and test projects. This tool also manages AVDs and Android platforms.
- </li>
-</ul>
- <p>
- You use the <code>emulator</code> tool to run the emulator from the command line.
- </p>
- <p>
- Here are the general steps for doing this tutorial using an editor and the command line:
- </p>
-<ol>
- <li>
- As described in the section <a href="#DownloadCode">Installing the Tutorial Sample Code</a>, get the sample code. You will then
- have a directory <code><SDK_path>/samples/android-8</code>, containing (among others) the directories <code>Spinner</code>
- and <code>SpinnerTest</code>:
- <ul>
- <li>
- <code>Spinner</code> contains the main application, also known as the <strong>application under test</strong>. This tutorial focuses on the
- common situation of writing tests for an application that already exists, so the main application is provided to you.
- </li>
- <li>
- <code>SpinnerTest</code> contains all the code for the test application. If you want to run quickly through the tutorial, you can
- install the test code and then follow the text. You may get more from the tutorial, however, if you write the code as you go. The instructions
- for installing the test code are in the section <a href="#InstallCompletedTestApp">Appendix: Installing the Completed Test Application File</a>.
- </li>
- </ul>
- </li>
- <li>
- Navigate to the directory <code><SDK_path>/samples/android-8</code>.
- </li>
- <li>
- Create a new Android application project using <code>android create project</code>:
-<pre>
-$ android create project -t <APItarget> -k com.android.example.spinner -a SpinnerActivity -n SpinnerActivity -p Spinner
-</pre>
- <p>
- The value of <code><APItarget></code> should be "3" (API level 3) or higher. If you are already developing with a particular API level, and it is
- higher than 3, then use that API level.
- </p>
- <p>
- This a new Android project <code>SpinnerActivity</code> in the existing <code>Spinner</code> directory. The existing source and
- resource files are not touched, but the <code>android</code> tool adds the necessary build files.
- </p>
- </li>
- <li>
- Create a new Android test project using <code>android create test-project</code>:
-<pre>
-$ android create test-project -m ../Spinner -n SpinnerActivityTest -p SpinnerActivityTest
-</pre>
- <p>
- This will create a new Android test project in the <em>new</em> directory <code>SpinnerActivityTest</code>. You do this
- so that the solution to the tutorial that is in <code>SpinnerTest</code> is left untouched. If you want to use the solution
- code instead of entering it as you read through the tutorial, refer to the section
- <a href="#InstallCompletedTestApp">Appendix: Installing the Completed Test Application File</a>.
- </p>
- <p class="Note">
- <strong>Note:</strong> Running <code>android create test-project</code> will automatically create
- the file <code>AndroidManifest.xml</code> with the correct <code><instrumentation></code> element.
- </p>
- </li>
- <li>
- Build the sample application. If you are building with Ant, then it is easiest to use the command <code>ant debug</code> to build a debug version, since the SDK comes
- with a debug signing key. The result will be the file <code>Spinner/bin/SpinnerActivity-debug.apk</code>.
- You can install this to your device or emulator. Attach your device or start the emulator if you haven't already, and run the command:
-<pre>
-$ adb install Spinner/bin/SpinnerActivity-debug.apk
-</pre>
- </li>
- <li>
- To create the test application, create a file <code>SpinnerActivityTest.java</code> in the directory
- <code>SpinnerActivityTest/src/com/android/example/spinner/test/</code>.
- </li>
- <li>
- Follow the tutorial, starting with the section <a href="#CreateTestCaseClass">Creating the Test Case Class</a>. When you are prompted to
- run the sample application, go to the Launcher screen in your device or emulator and select SpinnerActivity.
- When you are prompted to run the test application, return here to continue with the following instructions.
- </li>
- <li>
- Build the test application. If you are building with Ant, then it is easiest to use the command <code>ant debug</code> to build a
- debug version, since the SDK comes with a debug signing key. The result will be the Android file
- <code>SpinnerActivityTest/bin/SpinnerActivityTest-debug.apk</code>. You can install this to your device or emulator.
- Attach your device or start the emulator if you haven't already, and run the command:
-<pre>
-$ adb install SpinnerActivityTest/bin/SpinnerActivityTest-debug.apk
-</pre>
- </li>
- <li>
- In your device or emulator, check that both the main application <code>SpinnerActivity</code> and the test application
- <code>SpinnerActivityTest</code> are installed.
- </li>
- <li>
- To run the test application, enter the following at the command line:
-<pre>
-$ adb shell am instrument -w com.android.example.spinner.test/android.test.InstrumentationTestRunner
- </pre>
- </li>
-</ol>
-<p>
- The result of a successful test looks like this:
-</p>
-<pre>
-com.android.example.spinner.test.SpinnerActivityTest:....
-Test results for InstrumentationTestRunner=....
-Time: 10.098
-OK (4 tests)
-</pre>
-<p>
- If you force the test to fail, as described in the previous section <a href="#TestFailure">Forcing Some Tests to Fail</a>, then
- the output looks like this:
-</p>
-<pre>
-com.android.example.spinner.test.SpinnerActivityTest:
-Failure in testPreConditions:
-junit.framework.AssertionFailedError
- at com.android.example.spinner.test.SpinnerActivityTest.testPreConditions(SpinnerActivityTest.java:104)
- at java.lang.reflect.Method.invokeNative(Native Method)
- at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:205)
- at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:195)
- at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:175)
- at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
- at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
- at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430)
- at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)
-Failure in testSpinnerUI:
-junit.framework.ComparisonFailure: expected:<Result> but was:<Saturn>
- at com.android.example.spinner.test.SpinnerActivityTest.testSpinnerUI(SpinnerActivityTest.java:153)
- at java.lang.reflect.Method.invokeNative(Native Method)
- at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:205)
- at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:195)
- at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:175)
- at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
- at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
- at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430)
- at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)
-..
-Test results for InstrumentationTestRunner=.F.F..
-Time: 9.377
-FAILURES!!!
-Tests run: 4, Failures: 2, Errors: 0
-</pre>
diff --git a/docs/html/tools/testing/activity_testing.jd b/docs/html/tools/testing/activity_testing.jd
deleted file mode 100755
index 6109c06..0000000
--- a/docs/html/tools/testing/activity_testing.jd
+++ /dev/null
@@ -1,375 +0,0 @@
-page.title=Activity Testing
-parent.title=Testing
-parent.link=index.html
-@jd:body
-
-<div id="qv-wrapper">
- <div id="qv">
- <h2>In this document</h2>
- <ol>
- <li>
- <a href="#ActivityTestAPI">The Activity Testing API</a>
- <ol>
- <li>
- <a href="#ActivityInstrumentationTestCase2">ActivityInstrumentationTestCase2</a>
- </li>
- <li>
- <a href="#ActivityUnitTestCase">ActivityUnitTestCase</a>
- </li>
- <li>
- <a href="#SingleLaunchActivityTestCase">SingleLaunchActivityTestCase</a>
- </li>
- <li>
- <a href="#MockObjectNotes">Mock objects and activity testing</a>
- </li>
- <li>
- <a href="#AssertionNotes">Assertions for activity testing</a>
- </li>
- </ol>
- </li>
- <li>
- <a href="#WhatToTest">What to Test</a>
- </li>
- <li>
- <a href="#NextSteps">Next Steps</a>
- </li>
- <li>
- <a href="#UITesting">Appendix: UI Testing Notes</a>
- <ol>
- <li>
- <a href="#RunOnUIThread">Testing on the UI thread</a>
- </li>
- <li>
- <a href="#NotouchMode">Turning off touch mode</a>
- </li>
- <li>
- <a href="#UnlockDevice">Unlocking the Emulator or Device</a>
- </li>
- <li>
- <a href="#UITestTroubleshooting">Troubleshooting UI tests</a>
- </li>
- </ol>
- </li>
- </ol>
-<h2>Key Classes</h2>
- <ol>
- <li>{@link android.test.InstrumentationTestRunner}</li>
- <li>{@link android.test.ActivityInstrumentationTestCase2}</li>
- <li>{@link android.test.ActivityUnitTestCase}</li>
- </ol>
-<h2>Related Tutorials</h2>
- <ol>
- <li>
- <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a>
- </li>
- </ol>
-<h2>See Also</h2>
- <ol>
- <li>
- <a href="{@docRoot}training/testing/unit-testing/local-unit-tests.html">
- Building Local Unit Tests</a>
- </li>
- <li>
- <a href="{@docRoot}tools/testing/testing_otheride.html">
- Testing from Other IDEs</a>
- </li>
- </ol>
- </div>
-</div>
-<p>
- Activity testing is particularly dependent on the Android instrumentation framework.
- Unlike other components, activities have a complex lifecycle based on callback methods; these
- can't be invoked directly except by instrumentation. Also, the only way to send events to the
- user interface from a program is through instrumentation.
-</p>
-<p>
- This document describes how to test activities using instrumentation and other test
- facilities. The document assumes you have already read
- <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>,
- the introduction to the Android testing and instrumentation framework.
-</p>
-<h2 id="ActivityTestAPI">The Activity Testing API</h2>
-<p>
- The activity testing API base class is {@link android.test.InstrumentationTestCase},
- which provides instrumentation to the test case subclasses you use for Activities.
-</p>
-<p>
- For activity testing, this base class provides these functions:
-</p>
-<ul>
- <li>
- Lifecycle control: With instrumentation, you can start the activity under test, pause it,
- and destroy it, using methods provided by the test case classes.
- </li>
- <li>
- Dependency injection: Instrumentation allows you to create mock system objects such as
- Contexts or Applications and use them to run the activity under test. This
- helps you control the test environment and isolate it from production systems. You can
- also set up customized Intents and start an activity with them.
- </li>
- <li>
- User interface interaction: You use instrumentation to send keystrokes or touch events
- directly to the UI of the activity under test.
- </li>
-</ul>
-<p>
- The activity testing classes also provide the JUnit framework by extending
- {@link junit.framework.TestCase} and {@link junit.framework.Assert}.
-</p>
-<p>
- The two main testing subclasses are {@link android.test.ActivityInstrumentationTestCase2} and
- {@link android.test.ActivityUnitTestCase}. To test an Activity that is launched in a mode
- other than <code>standard</code>, you use {@link android.test.SingleLaunchActivityTestCase}.
-</p>
-<h3 id="ActivityInstrumentationTestCase2">ActivityInstrumentationTestCase2</h3>
-<p>
- The {@link android.test.ActivityInstrumentationTestCase2} test case class is designed to do
- functional testing of one or more Activities in an application, using a normal system
- infrastructure. It runs the Activities in a normal instance of the application under test,
- using a standard system Context. It allows you to send mock Intents to the activity under
- test, so you can use it to test an activity that responds to multiple types of intents, or
- an activity that expects a certain type of data in the intent, or both. Notice, though, that it
- does not allow mock Contexts or Applications, so you can not isolate the test from the rest of
- a production system.
-</p>
-<h3 id="ActivityUnitTestCase">ActivityUnitTestCase</h3>
-<p>
- The {@link android.test.ActivityUnitTestCase} test case class tests a single activity in
- isolation. Before you start the activity, you can inject a mock Context or Application, or both.
- You use it to run activity tests in isolation, and to do unit testing of methods
- that do not interact with Android. You can not send mock Intents to the activity under test,
- although you can call
- {@link android.app.Activity#startActivity(Intent) Activity.startActivity(Intent)} and then
- look at arguments that were received.
-</p>
-<h3 id="SingleLaunchActivityTestCase">SingleLaunchActivityTestCase</h3>
-<p>
- The {@link android.test.SingleLaunchActivityTestCase} class is a convenience class for
- testing a single activity in an environment that doesn't change from test to test.
- It invokes {@link junit.framework.TestCase#setUp() setUp()} and
- {@link junit.framework.TestCase#tearDown() tearDown()} only once, instead of once per
- method call. It does not allow you to inject any mock objects.
-</p>
-<p>
- This test case is useful for testing an activity that runs in a mode other than
- <code>standard</code>. It ensures that the test fixture is not reset between tests. You
- can then test that the activity handles multiple calls correctly.
-</p>
-<h3 id="MockObjectNotes">Mock objects and activity testing</h3>
-<p>
- This section contains notes about the use of the mock objects defined in
- {@link android.test.mock} with activity tests.
-</p>
-<p>
- The mock object {@link android.test.mock.MockApplication} is only available for activity
- testing if you use the {@link android.test.ActivityUnitTestCase} test case class.
- By default, <code>ActivityUnitTestCase</code>, creates a hidden <code>MockApplication</code>
- object that is used as the application under test. You can inject your own object using
- {@link android.test.ActivityUnitTestCase#setApplication(Application) setApplication()}.
-</p>
-<h3 id="AssertionNotes">Assertions for activity testing</h3>
-<p>
- {@link android.test.ViewAsserts} defines assertions for Views. You use it to verify the
- alignment and position of View objects, and to look at the state of ViewGroup objects.
-</p>
-<h2 id="WhatToTest">What To Test</h2>
-<ul>
- <li>
- Input validation: Test that an activity responds correctly to input values in an
- EditText View. Set up a keystroke sequence, send it to the activity, and then
- use {@link android.view.View#findViewById(int)} to examine the state of the View. You can
- verify that a valid keystroke sequence enables an OK button, while an invalid one leaves the
- button disabled. You can also verify that the Activity responds to invalid input by
- setting error messages in the View.
- </li>
- <li>
- Lifecycle events: Test that each of your application's activities handles lifecycle events
- correctly. In general, lifecycle events are actions, either from the system or from the
- user, that trigger a callback method such as <code>onCreate()</code> or
- <code>onClick()</code>. For example, an activity should respond to pause or destroy events
- by saving its state. Remember that even a change in screen orientation causes the current
- activity to be destroyed, so you should test that accidental device movements don't
- accidentally lose the application state.
- </li>
- <li>
- Intents: Test that each activity correctly handles the intents listed in the intent
- filter specified in its manifest. You can use
- {@link android.test.ActivityInstrumentationTestCase2} to send mock Intents to the
- activity under test.
- </li>
- <li>
- Runtime configuration changes: Test that each activity responds correctly to the
- possible changes in the device's configuration while your application is running. These
- include a change to the device's orientation, a change to the current language, and so
- forth. Handling these changes is described in detail in the topic
- <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime
- Changes</a>.
- </li>
- <li>
- Screen sizes and resolutions: Before you publish your application, make sure to test it on
- all of the screen sizes and densities on which you want it to run. You can test the
- application on multiple sizes and densities using AVDs, or you can test your application
- directly on the devices that you are targeting. For more information, see the topic
- <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>.
- </li>
-</ul>
-<h2 id="NextSteps">Next Steps</h2>
-<p>
- To learn how to set up and run tests in Android Studio, please refer to
-<a href="{@docRoot}training/testing/unit-testing/local-unit-tests.html">Building Local Unit Tests</a>.
- If you're not working in Android Studio, refer to
-<a href="{@docRoot}tools/testing/testing_otheride.html">Testing from Other IDEs</a>.
-</p>
-<p>
- If you want a step-by-step introduction to testing activities, try the
- <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a>, which
- guides you through a testing scenario that you develop against an activity-oriented application.
-</p>
-<h2 id="UITesting">Appendix: UI Testing Notes</h2>
-<p>
- The following sections have tips for testing the UI of your Android application, specifically
- to help you handle actions that run in the UI thread, touch screen and keyboard events, and home
- screen unlock during testing.
-</p>
-<h3 id="RunOnUIThread">Testing on the UI thread</h3>
-<p>
- An application's activities run on the application's <strong>UI thread</strong>. Once the
- UI is instantiated, for example in the activity's <code>onCreate()</code> method, then all
- interactions with the UI must run in the UI thread. When you run the application normally, it
- has access to the thread and does not have to do anything special.
-</p>
-<p>
- This changes when you run tests against the application. With instrumentation-based classes,
- you can invoke methods against the UI of the application under test. The other test classes
- don't allow this. To run an entire test method on the UI thread, you can annotate the thread
- with <code>@UiThreadTest</code>. Notice that this will run <em>all</em> of the method statements
- on the UI thread. Methods that do not interact with the UI are not allowed; for example, you
- can't invoke <code>Instrumentation.waitForIdleSync()</code>.
-</p>
-<p>
- To run a subset of a test method on the UI thread, create an anonymous class of type
- <code>Runnable</code>, put the statements you want in the <code>run()</code> method, and
- instantiate a new instance of the class as a parameter to the method
- <code><em>appActivity</em>.runOnUiThread()</code>, where <code><em>appActivity</em></code> is
- the instance of the application you are testing.
-</p>
-<p>
- For example, this code instantiates an activity to test, requests focus (a UI action) for the
- Spinner displayed by the activity, and then sends a key to it. Notice that the calls to
- <code>waitForIdleSync</code> and <code>sendKeys</code> aren't allowed to run on the UI thread:
-</p>
-<pre>
- private MyActivity mActivity; // MyActivity is the class name of the app under test
- private Spinner mSpinner;
-
- ...
-
- protected void setUp() throws Exception {
- super.setUp();
- mInstrumentation = getInstrumentation();
-
- mActivity = getActivity(); // get a references to the app under test
-
- /*
- * Get a reference to the main widget of the app under test, a Spinner
- */
- mSpinner = (Spinner) mActivity.findViewById(com.android.demo.myactivity.R.id.Spinner01);
-
- ...
-
- public void aTest() {
- /*
- * request focus for the Spinner, so that the test can send key events to it
- * This request must be run on the UI thread. To do this, use the runOnUiThread method
- * and pass it a Runnable that contains a call to requestFocus on the Spinner.
- */
- mActivity.runOnUiThread(new Runnable() {
- public void run() {
- mSpinner.requestFocus();
- }
- });
-
- mInstrumentation.waitForIdleSync();
-
- this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
-</pre>
-
-<h3 id="NotouchMode">Turning off touch mode</h3>
-<p>
- To control the emulator or a device with key events you send from your tests, you must turn off
- touch mode. If you do not do this, the key events are ignored.
-</p>
-<p>
- To turn off touch mode, you invoke
- <code>ActivityInstrumentationTestCase2.setActivityTouchMode(false)</code>
- <em>before</em> you call <code>getActivity()</code> to start the activity. You must invoke the
- method in a test method that is <em>not</em> running on the UI thread. For this reason, you
- can't invoke the touch mode method from a test method that is annotated with
- <code>@UIThread</code>. Instead, invoke the touch mode method from <code>setUp()</code>.
-</p>
-<h3 id="UnlockDevice">Unlocking the emulator or device</h3>
-<p>
- You may find that UI tests don't work if the emulator's or device's home screen is disabled with
- the keyguard pattern. This is because the application under test can't receive key events sent
- by <code>sendKeys()</code>. The best way to avoid this is to start your emulator or device
- first and then disable the keyguard for the home screen.
-</p>
-<p>
- You can also explicitly disable the keyguard. To do this,
- you need to add a permission in the manifest file (<code>AndroidManifest.xml</code>) and
- then disable the keyguard in your application under test. Note, though, that you either have to
- remove this before you publish your application, or you have to disable it with code in
- the published application.
-</p>
-<p>
- To add the permission, add the element
- <code><uses-permission android:name="android.permission.DISABLE_KEYGUARD"/></code>
- as a child of the <code><manifest></code> element. To disable the KeyGuard, add the
- following code to the <code>onCreate()</code> method of activities you intend to test:
-</p>
-<pre>
- mKeyGuardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
- mLock = mKeyGuardManager.newKeyguardLock("<em>activity_classname</em>");
- mLock.disableKeyguard();
-</pre>
-<p>where <code><em>activity_classname</em></code> is the class name of the activity.</p>
-<h3 id="UITestTroubleshooting">Troubleshooting UI tests</h3>
-<p>
- This section lists some of the common test failures you may encounter in UI testing, and their
- causes:
-</p>
-<dl>
- <dt><code>WrongThreadException</code></dt>
- <dd>
- <p><strong>Problem:</strong></p>
- For a failed test, the Failure Trace contains the following error message:
- <code>
- android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created
- a view hierarchy can touch its views.
- </code>
- <p><strong>Probable Cause:</strong></p>
- This error is common if you tried to send UI events to the UI thread from outside the UI
- thread. This commonly happens if you send UI events from the test application, but you don't
- use the <code>@UIThread</code> annotation or the <code>runOnUiThread()</code> method. The
- test method tried to interact with the UI outside the UI thread.
- <p><strong>Suggested Resolution:</strong></p>
- Run the interaction on the UI thread. Use a test class that provides instrumentation. See
- the previous section <a href="#RunOnUIThread">Testing on the UI Thread</a>
- for more details.
- </dd>
- <dt><code>java.lang.RuntimeException</code></dt>
- <dd>
- <p><strong>Problem:</strong></p>
- For a failed test, the Failure Trace contains the following error message:
- <code>
- java.lang.RuntimeException: This method can not be called from the main application thread
- </code>
- <p><strong>Probable Cause:</strong></p>
- This error is common if your test method is annotated with <code>@UiThreadTest</code> but
- then tries to do something outside the UI thread or tries to invoke
- <code>runOnUiThread()</code>.
- <p><strong>Suggested Resolution:</strong></p>
- Remove the <code>@UiThreadTest</code> annotation, remove the <code>runOnUiThread()</code>
- call, or re-factor your tests.
- </dd>
-</dl>
diff --git a/docs/html/tools/testing/contentprovider_testing.jd b/docs/html/tools/testing/contentprovider_testing.jd
deleted file mode 100755
index 28aef91..0000000
--- a/docs/html/tools/testing/contentprovider_testing.jd
+++ /dev/null
@@ -1,208 +0,0 @@
-page.title=Content Provider Testing
-parent.title=Testing
-parent.link=index.html
-@jd:body
-
-<div id="qv-wrapper">
- <div id="qv">
- <h2>In this document</h2>
- <ol>
- <li>
- <a href="#DesignAndTest">Content Provider Design and Testing</a>
- </li>
- <li>
- <a href="#ContentProviderTestAPI">The Content Provider Testing API</a>
- <ol>
- <li>
- <a href="#ProviderTestCase2">ProviderTestCase2 </a>
- </li>
- <li>
- <a href="#MockObjects">Mock object classes</a>
- </li>
- </ol>
- </li>
- <li>
- <a href="#WhatToTest">What To Test</a>
- </li>
- <li>
- <a href="#NextSteps">Next Steps</a>
- </li>
- </ol>
- <h2>Key Classes</h2>
- <ol>
- <li>{@link android.test.InstrumentationTestRunner}</li>
- <li>{@link android.test.ProviderTestCase2}</li>
- <li>{@link android.test.IsolatedContext}</li>
- <li>{@link android.test.mock.MockContentResolver}</li>
- </ol>
- <h2>Related Tutorials</h2>
- <ol>
- <li>
- <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a>
- </li>
- </ol>
- <h2>See Also</h2>
- <ol>
- <li>
- <a
- href="{@docRoot}tools/testing/testing_android.html">
- Testing Fundamentals</a>
- </li>
- <li>
- <a href="{@docRoot}tools/testing/testing_otheride.html">
- Testing From Other IDEs</a>
- </li>
- </ol>
- </div>
-</div>
-<p>
- Content providers, which store and retrieve data and make it accessible across applications,
- are a key part of the Android API. As an application developer you're allowed to provide your
- own public providers for use by other applications. If you do, then you should test them
- using the API you publish.
-</p>
-<p>
- This document describes how to test public content providers, although the information is
- also applicable to providers that you keep private to your own application. If you aren't
- familiar with content providers or the Android testing framework, please read
- <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>,
- the guide to developing content providers, and
- <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>,
- the introduction to the Android testing and instrumentation framework.
-</p>
-<h2 id="DesignAndTest">Content Provider Design and Testing</h2>
-<p>
- In Android, content providers are viewed externally as data APIs that provide
- tables of data, with their internals hidden from view. A content provider may have many
- public constants, but it usually has few if any public methods and no public variables.
- This suggests that you should write your tests based only on the provider's public members.
- A content provider that is designed like this is offering a contract between itself and its
- users.
-</p>
-<p>
- The base test case class for content providers,
- {@link android.test.ProviderTestCase2}, allows you to test your content provider in an
- isolated environment. Android mock objects such as {@link android.test.IsolatedContext} and
- {@link android.test.mock.MockContentResolver} also help provide an isolated test environment.
-</p>
-<p>
- As with other Android tests, provider test packages are run under the control of the test
- runner {@link android.test.InstrumentationTestRunner}. The section
- <a href="{@docRoot}tools/testing/testing_android.html#InstrumentationTestRunner">
- Running Tests With InstrumentationTestRunner</a> describes the test runner in
- more detail. The topic <a href="{@docRoot}tools/testing/testing_otheride.html">
- Testing From Other IDEs</a> shows you how to run a test package from the command line.
-</p>
-<h2 id="ContentProviderTestAPI">Content Provider Testing API</h2>
-<p>
- The main focus of the provider testing API is to provide an isolated testing environment. This
- ensures that tests always run against data dependencies set explicitly in the test case. It
- also prevents tests from modifying actual user data. For example, you want to avoid writing
- a test that fails because there was data left over from a previous test, and you want to
- avoid adding or deleting contact information in a actual provider.
-</p>
-<p>
- The test case class and mock object classes for provider testing set up this isolated testing
- environment for you.
-</p>
-<h3 id="ProviderTestCase2">ProviderTestCase2</h3>
-<p>
- You test a provider with a subclass of {@link android.test.ProviderTestCase2}. This base class
- extends {@link android.test.AndroidTestCase}, so it provides the JUnit testing framework as well
- as Android-specific methods for testing application permissions. The most important
- feature of this class is its initialization, which creates the isolated test environment.
-</p>
-<p>
- The initialization is done in the constructor for {@link android.test.ProviderTestCase2}, which
- subclasses call in their own constructors. The {@link android.test.ProviderTestCase2}
- constructor creates an {@link android.test.IsolatedContext} object that allows file and
- database operations but stubs out other interactions with the Android system.
- The file and database operations themselves take place in a directory that is local to the
- device or emulator and has a special prefix.
-</p>
-<p>
- The constructor then creates a {@link android.test.mock.MockContentResolver} to use as the
- resolver for the test. The {@link android.test.mock.MockContentResolver} class is described in
- detail in the section
- <a href="{@docRoot}tools/testing/testing_android.html#MockObjectClasses">Mock object
-classes</a>.
-</p>
-<p>
- Lastly, the constructor creates an instance of the provider under test. This is a normal
- {@link android.content.ContentProvider} object, but it takes all of its environment information
- from the {@link android.test.IsolatedContext}, so it is restricted to
- working in the isolated test environment. All of the tests done in the test case class run
- against this isolated object.
-</p>
-<h3 id="MockObjects">Mock object classes</h3>
-<p>
- {@link android.test.ProviderTestCase2} uses {@link android.test.IsolatedContext} and
- {@link android.test.mock.MockContentResolver}, which are standard mock object classes. To
- learn more about them, please read
- <a href="{@docRoot}tools/testing/testing_android.html#MockObjectClasses">
- Testing Fundamentals</a>.
-</p>
-<h2 id="WhatToTest">What To Test</h2>
-<p>
- The topic <a href="{@docRoot}tools/testing/what_to_test.html">What To Test</a>
- lists general considerations for testing Android components.
- Here are some specific guidelines for testing content providers.
-</p>
-<ul>
- <li>
- Test with resolver methods: Even though you can instantiate a provider object in
- {@link android.test.ProviderTestCase2}, you should always test with a resolver object
- using the appropriate URI. This ensures that you are testing the provider using the same
- interaction that a regular application would use.
- </li>
- <li>
- Test a public provider as a contract: If you intent your provider to be public and
- available to other applications, you should test it as a contract. This includes
- the following ideas:
- <ul>
- <li>
- Test with constants that your provider publicly exposes. For
- example, look for constants that refer to column names in one of the provider's
- data tables. These should always be constants publicly defined by the provider.
- </li>
- <li>
- Test all the URIs offered by your provider. Your provider may offer several URIs,
- each one referring to a different aspect of the data. The
- <a href="{@docRoot}resources/samples/NotePad/index.html">Note Pad</a> sample,
- for example, features a provider that offers one URI for retrieving a list of notes,
- another for retrieving an individual note by it's database ID, and a third for
- displaying notes in a live folder.
- </li>
- <li>
- Test invalid URIs: Your unit tests should deliberately call the provider with an
- invalid URI, and look for errors. Good provider design is to throw an
- IllegalArgumentException for invalid URIs.
-
- </li>
- </ul>
- </li>
- <li>
- Test the standard provider interactions: Most providers offer six access methods:
- query, insert, delete, update, getType, and onCreate(). Your tests should verify that all
- of these methods work. These are described in more detail in the topic
- <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>.
- </li>
- <li>
- Test business logic: Don't forget to test the business logic that your provider should
- enforce. Business logic includes handling of invalid values, financial or arithmetic
- calculations, elimination or combining of duplicates, and so forth. A content provider
- does not have to have business logic, because it may be implemented by activities that
- modify the data. If the provider does implement business logic, you should test it.
- </li>
-</ul>
-<h2 id="NextSteps">Next Steps</h2>
-<p>
- To learn how to set up and run tests from other IDEs, please refer to
-<a href="{@docRoot}tools/testing/testing_otheride.html">Testing From Other IDEs</a>.
-</p>
-<p>
- If you want a step-by-step introduction to testing activities, try the
- <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a>, which
- guides you through a testing scenario that you develop against an activity-oriented application.
-</p>
-
diff --git a/docs/html/tools/testing/index.jd b/docs/html/tools/testing/index.jd
old mode 100755
new mode 100644
index 185727c..a454891
--- a/docs/html/tools/testing/index.jd
+++ b/docs/html/tools/testing/index.jd
@@ -1,40 +1,19 @@
page.title=Testing
@jd:body
-<p> The Android framework includes an integrated testing framework that helps you test all aspects
-of your application and the SDK tools include tools for setting up and running test applications.
-Whether you are working in Android Studio or working from the command line, the SDK tools help you
-set up and run your tests within an emulator or the device you are targeting. </p>
+<p>Android provides an integrated testing framework that helps you test all aspects
+of your app. The Android <a href="{@docRoot}sdk/installing/index.html">SDK</a> and
+<a href="{@docRoot}tools/testing-support-library/index.html">Testing Support Library</a> include
+tools and APIs for setting up and running test apps within an emulator or on the device you are
+targeting. You can build and execute tests whether you are working in Android Studio or working
+from the command line.</p>
-<p>If you aren't yet familiar with the Android testing framework, start by reading <a
-href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>. For a step-by-step
-introduction to Android testing, try the <a
-href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a>. </p>
-
-
-
-<div class="landing-docs">
-
- <div class="col-13" style="margin-left:0">
- <h3>Blog Articles</h3>
-
- <a href="http://android-developers.blogspot.com/2010/12/new-gingerbread-api-strictmode.html">
- <h4>New Gingerbread API: StrictMode</h4>
- <p>StrictMode is a new API in Gingerbread which primarily lets you set a policy on a thread
-declaring what you’re not allowed to do on that thread, and what the penalty is if you violate the
-policy. Implementation-wise, this policy is simply a thread-local integer bitmask.</p>
- </a>
-
- <a href="http://android-developers.blogspot.com/2010/10/traceview-war-story.html">
- <h4>Traceview War Story</h4>
- <p>I recently took my first serious look at Traceview, and it occurred to me, first, that
-there are probably a few other Android developers who haven’t used it and, second, that this is an
-opportunity to lecture sternly on one of my favorite subjects: performance improvement and
-profiling.</p>
- </a>
- </div>
-
-
-</div>
-
-
+<p>To familiarize yourself with mobile app testing in Android, start by reading these resources:</p>
+<ul>
+ <li><a href="{@docRoot}tools/testing/testing_android.html">Testing Concepts</a>: Learn key
+ concepts related to Android app testing and get an overview of the testing tools and APIs
+ that Google provides.</li>
+ <li><a href="{@docRoot}training/testing/start/index.html">Getting Started with Testing</a>: Learn
+ how to build and run your tests, step-by-step, using the testing APIs and tools that
+ Google provides.</li>
+</ul>
diff --git a/docs/html/tools/testing/service_testing.jd b/docs/html/tools/testing/service_testing.jd
deleted file mode 100755
index e0bb351..0000000
--- a/docs/html/tools/testing/service_testing.jd
+++ /dev/null
@@ -1,172 +0,0 @@
-page.title=Service Testing
-parent.title=Testing
-parent.link=index.html
-@jd:body
-
-<div id="qv-wrapper">
- <div id="qv">
- <h2>In this document</h2>
- <ol>
- <li>
- <a href="#DesignAndTest">Service Design and Testing</a>
- </li>
- <li>
- <a href="#ServiceTestCase">ServiceTestCase</a>
- </li>
- <li>
- <a href="#MockObjects">Mock object classes</a>
- </li>
- <li>
- <a href="#TestAreas">What to Test</a>
- </li>
- </ol>
- <h2>Key Classes</h2>
- <ol>
- <li>{@link android.test.InstrumentationTestRunner}</li>
- <li>{@link android.test.ServiceTestCase}</li>
- <li>{@link android.test.mock.MockApplication}</li>
- <li>{@link android.test.RenamingDelegatingContext}</li>
- </ol>
- <h2>Related Tutorials</h2>
- <ol>
- <li>
- <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a>
- </li>
- </ol>
- <h2>See Also</h2>
- <ol>
- <li>
- <a href="{@docRoot}tools/testing/testing_otheride.html">
- Testing From Other IDEs</a>
- </li>
- </ol>
- </div>
-</div>
-<p>
- Android provides a testing framework for Service objects that can run them in
- isolation and provides mock objects. The test case class for Service objects is
- {@link android.test.ServiceTestCase}. Since the Service class assumes that it is separate
- from its clients, you can test a Service object without using instrumentation.
-</p>
-<p>
- This document describes techniques for testing Service objects. If you aren't familiar with the
- Service class, please read the <a href="{@docRoot}guide/components/services.html">
- Services</a> document. If you aren't familiar with Android testing, please read
- <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>,
- the introduction to the Android testing and instrumentation framework.
-</p>
-<h2 id="DesignAndTest">Service Design and Testing</h2>
-<p>
- When you design a Service, you should consider how your tests can examine the various states
- of the Service lifecycle. If the lifecycle methods that start up your Service, such as
- {@link android.app.Service#onCreate() onCreate()} or
- {@link android.app.Service#onStartCommand(Intent, int, int) onStartCommand()} do not normally
- set a global variable to indicate that they were successful, you may want to provide such a
- variable for testing purposes.
-</p>
-<p>
- Most other testing is facilitated by the methods in the {@link android.test.ServiceTestCase}
- test case class. For example, the {@link android.test.ServiceTestCase#getService()} method
- returns a handle to the Service under test, which you can test to confirm that the Service is
- running even at the end of your tests.
-</p>
-<h2 id="ServiceTestCase">ServiceTestCase</h2>
-<p>
- {@link android.test.ServiceTestCase} extends the JUnit {@link junit.framework.TestCase} class
- with methods for testing application permissions and for controlling the application and
- Service under test. It also provides mock application and Context objects that isolate your
- test from the rest of the system.
-</p>
-<p>
- {@link android.test.ServiceTestCase} defers initialization of the test environment until you
- call {@link android.test.ServiceTestCase#startService(Intent) ServiceTestCase.startService()} or
- {@link android.test.ServiceTestCase#bindService(Intent) ServiceTestCase.bindService()}. This
- allows you to set up your test environment, particularly your mock objects, before the Service
- is started.
-</p>
-<p>
- Notice that the parameters to <code>ServiceTestCase.bindService()</code>are different from
- those for <code>Service.bindService()</code>. For the <code>ServiceTestCase</code> version,
- you only provide an Intent. Instead of returning a boolean,
- <code>ServiceTestCase.bindService()</code> returns an object that subclasses
- {@link android.os.IBinder}.
-</p>
-<p>
- The {@link android.test.ServiceTestCase#setUp()} method for {@link android.test.ServiceTestCase}
- is called before each test. It sets up the test fixture by making a copy of the current system
- Context before any test methods touch it. You can retrieve this Context by calling
- {@link android.test.ServiceTestCase#getSystemContext()}. If you override this method, you must
- call <code>super.setUp()</code> as the first statement in the override.
-</p>
-<p>
- The methods {@link android.test.ServiceTestCase#setApplication(Application) setApplication()}
- and {@link android.test.AndroidTestCase#setContext(Context)} setContext()} allow you to set
- a mock Context or mock Application (or both) for the Service, before you start it. These mock
- objects are described in <a href="#MockObjects">Mock object classes</a>.
-</p>
-<p>
- By default, {@link android.test.ServiceTestCase} runs the test method
- {@link android.test.AndroidTestCase#testAndroidTestCaseSetupProperly()}, which asserts that
- the base test case class successfully set up a Context before running.
-</p>
-<h2 id="MockObjects">Mock object classes</h2>
-<p>
- <code>ServiceTestCase</code> assumes that you will use a mock Context or mock Application
- (or both) for the test environment. These objects isolate the test environment from the
- rest of the system. If you don't provide your own instances of these objects before you
- start the Service, then {@link android.test.ServiceTestCase} will create its own internal
- instances and inject them into the Service. You can override this behavior by creating and
- injecting your own instances before starting the Service
-</p>
-<p>
- To inject a mock Application object into the Service under test, first create a subclass of
- {@link android.test.mock.MockApplication}. <code>MockApplication</code> is a subclass of
- {@link android.app.Application} in which all the methods throw an Exception, so to use it
- effectively you subclass it and override the methods you need. You then inject it into the
- Service with the
- {@link android.test.ServiceTestCase#setApplication(Application) setApplication()} method.
- This mock object allows you to control the application values that the Service sees, and
- isolates it from the real system. In addition, any hidden dependencies your Service has on
- its application reveal themselves as exceptions when you run the test.
-</p>
-<p>
- You inject a mock Context into the Service under test with the
- {@link android.test.AndroidTestCase#setContext(Context) setContext()} method. The mock
- Context classes you can use are described in more detail in
- <a href="{@docRoot}tools/testing/testing_android.html#MockObjectClasses">
- Testing Fundamentals</a>.
-</p>
-<h2 id="TestAreas">What to Test</h2>
-<p>
- The topic <a href="{@docRoot}tools/testing/what_to_test.html">What To Test</a>
- lists general considerations for testing Android components.
- Here are some specific guidelines for testing a Service:
-</p>
-<ul>
- <li>
- Ensure that the {@link android.app.Service#onCreate()} is called in response to
- {@link android.content.Context#startService(Intent) Context.startService()} or
- {@link android.content.Context#bindService(Intent,ServiceConnection,int) Context.bindService()}.
- Similarly, you should ensure that {@link android.app.Service#onDestroy()} is called in
- response to {@link android.content.Context#stopService(Intent) Context.stopService()},
- {@link android.content.Context#unbindService(ServiceConnection) Context.unbindService()},
- {@link android.app.Service#stopSelf()}, or
- {@link android.app.Service#stopSelfResult(int) stopSelfResult()}.
- </li>
- <li>
- Test that your Service correctly handles multiple calls from
- <code>Context.startService()</code>. Only the first call triggers
- <code>Service.onCreate()</code>, but all calls trigger a call to
- <code>Service.onStartCommand()</code>.
- <p>
- In addition, remember that <code>startService()</code> calls don't
- nest, so a single call to <code>Context.stopService()</code> or
- <code>Service.stopSelf()</code> (but not <code>stopSelf(int)</code>)
- will stop the Service. You should test that your Service stops at the correct point.
- </p>
- </li>
- <li>
- Test any business logic that your Service implements. Business logic includes checking for
- invalid values, financial and arithmetic calculations, and so forth.
- </li>
-</ul>
diff --git a/docs/html/tools/testing/testing-tools.jd b/docs/html/tools/testing/testing-tools.jd
index 5e0a5bc..c60199f7 100644
--- a/docs/html/tools/testing/testing-tools.jd
+++ b/docs/html/tools/testing/testing-tools.jd
@@ -5,7 +5,7 @@
<div id="qv">
<h2>See also</h2>
<ol>
- <li><a href="{@docRoot}training/testing.html">Best Practices for Testing</a></li>
+ <li><a href="{@docRoot}training/testing/index.html">Best Practices for Testing</a></li>
</ol>
</div>
</div>
diff --git a/docs/html/tools/testing/testing_android.jd b/docs/html/tools/testing/testing_android.jd
index 5b2b549..5adb7e9 100755
--- a/docs/html/tools/testing/testing_android.jd
+++ b/docs/html/tools/testing/testing_android.jd
@@ -1,4 +1,4 @@
-page.title=Testing Fundamentals
+page.title=Testing Concepts
parent.title=Testing
parent.link=index.html
@jd:body
@@ -7,14 +7,8 @@
<div id="qv">
<h2>In this document</h2>
<ol>
- <li>
- <a href="#TestStructure">Test Structure</a>
- </li>
- <li>
- <a href="#TestProjects">Test Projects</a>
- </li>
- <li>
- <a href="#TestAPI">The Testing API</a>
+ <li><a href="#TestStructure">Test Structure</a></li>
+ <li><a href="#TestAPI">Testing APIs</a>
<ol>
<li>
<a href="#JUnit">JUnit</a>
@@ -23,107 +17,192 @@
<a href="#Instrumentation">Instrumentation</a>
</li>
<li>
- <a href="#TestCaseClasses">Test case classes</a>
+ <a href="#TestingSupportLibraryClasses">Android Testing Support Library APIs</a>
</li>
<li>
<a href="#AssertionClasses">Assertion classes</a>
</li>
- <li>
- <a href="#MockObjectClasses">Mock object classes</a>
- </li>
</ol>
</li>
<li>
- <a href="#InstrumentationTestRunner">Running Tests</a>
- </li>
- <li>
- <a href="#TestResults">Seeing Test Results</a>
- </li>
- <li>
- <a href="#Monkeys">monkey and monkeyrunner</a>
- </li>
- <li>
- <a href="#PackageNames">Working With Package Names</a>
- </li>
- <li>
- <a href="#WhatToTest">What To Test</a>
- </li>
- <li>
- <a href="#NextSteps">Next Steps</a>
+ <a href="#Monkeys">Monkey and Monkeyrunner</a>
</li>
</ol>
- <h2>Key classes</h2>
- <ol>
- <li>{@link android.test.InstrumentationTestRunner}</li>
- <li>{@link android.test}</li>
- <li>{@link android.test.mock}</li>
- <li>{@link junit.framework}</li>
- </ol>
- <h2>Related tutorials</h2>
- <ol>
- <li>
- <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a>
- </li>
- </ol>
<h2>See also</h2>
- <ol>
- <li>
- <a href="{@docRoot}tools/testing/testing_otheride.html">
- Testing from Other IDEs</a>
- </li>
- <li>
- <a href="{@docRoot}tools/help/monkeyrunner_concepts.html">
- monkeyrunner</a>
- </li>
- <li>
- <a href="{@docRoot}tools/help/monkey.html">UI/Application Exerciser Monkey</a>
- </li>
- </ol>
+ <ol>
+ <li><a href="{@docRoot}training/testing/start/index.html">Getting Started with Testing</a></li>
+ </ol>
</div>
</div>
+
<p>
- The Android testing framework, an integral part of the development environment,
- provides an architecture and powerful tools that help you test every aspect of your application
- at every level from unit to framework.
-</p>
-<p>
- The testing framework has these key features:
-</p>
+This document describes key concepts related to Android app testing. It assumes you have a basic
+knowledge of the <a href="http://junit.org/" class="external-link">JUnit</a> testing framework.</p>
+
+<h2 id="TestStructure">Test Structure</h2>
+<p>Android testing is based on JUnit. In general, a JUnit test is a method whose statements test a
+part of the application. You organize test methods into classes called
+<em>test cases</em>. You can further organize these classes into <em>test suites</em>.</p>
+<p>In JUnit, you build one or more test classes and use a test runner to
+execute them. In Android, you use <a href="{@docRoot}tools/studio/index.html">
+Android Studio </a>(or the <a href="{@docRoot}tools/building/plugin-for-gradle.html">
+Android Plugin for Gradle</a>) to build one or more test source files into an
+<em>Android test app</em>.</p>
+
+<p>From your testing environment, you can run your test in one of the following ways:</p>
<ul>
- <li>
- Android test suites are based on JUnit. You can use plain JUnit to test a class that doesn't
- call the Android API, or Android's JUnit extensions to test Android components. If you're
- new to Android testing, you can start with general-purpose test case classes such as {@link
- android.test.AndroidTestCase} and then go on to use more sophisticated classes.
- </li>
- <li>
- The Android JUnit extensions provide component-specific test case classes. These classes
- provide helper methods for creating mock objects and methods that help you control the
- lifecycle of a component.
- </li>
- <li>
- Test suites are contained in test packages that are similar to main application packages, so
- you don't need to learn a new set of tools or techniques for designing and building tests.
- </li>
- <li>
- The SDK tools for building and tests are available in Android Studio, and also in
- command-line form for use with other IDEs. These tools get information from the project of
- the application under test and use this information to automatically create the build files,
- manifest file, and directory structure for the test package.
- </li>
- <li>
- The SDK also provides
- <a href="{@docRoot}tools/help/monkeyrunner_concepts.html">monkeyrunner</a>, an API
- for testing devices with Python programs, and <a
- href="{@docRoot}tools/help/monkey.html">UI/Application Exerciser Monkey</a>,
- a command-line tool for stress-testing UIs by sending pseudo-random events to a device.
- </li>
+ <li><strong>On your local machine:</strong> Compile the test classes and
+ execute them locally on the Java Virtual Machine (JVM) using the JUnit test runner.</li>
+ <li><strong>On a device or emulator</strong>: Install the test app and the app
+under test to a physical device or emulator, and then execute your tests using an Android-specific
+test runner (such as <a href="{@docRoot}tools/testing-support-library/index.html#AndroidJUnitRunner">
+{@code AndroidJUnitRunner}</a>).</li>
</ul>
+
+<p>The structure of your test code and the way you build and run the tests in Android Studio depend
+on the type of testing you are performing. The following table summarizes the common testing types
+for Android:</p>
+
+<table>
+<tr><th>Type</th>
+ <th>Subtype</th>
+ <th>Description</th></tr>
+
+<tr><td rowspan="3">Unit tests</td>
+ <tr><td>Local Unit Tests</td>
+ <td>Unit tests that run on your local machine only. These tests are compiled to run locally
+on the JVM to minimize execution time. Use this approach to run unit tests
+that have no dependencies on the Android framework or have dependencies that mock objects can
+satisfy.</td></tr>
+ <tr><td>Instrumented unit tests</td>
+ <td>Unit tests that run on an Android device or emulator. These tests have access to
+{@link android.app.Instrumentation} information, such as the {@link android.content.Context} of the
+app under test. Use this approach to run unit tests that have Android dependencies which mock
+objects cannot easily satisfy.</td></tr>
+
+<tr><td rowspan="3">Integration Tests</td>
+ <tr><td>Components within your app only</td>
+ <td>This type of test verifies that the target app behaves as expected when a user performs
+a specific action or enters a specific input in its activities. For example, it allows you to check
+that the target app returns the correct UI output in response to user interactions in the app’s
+activities. UI testing frameworks like
+<a href="{@docRoot}tools/testing-support-library/index.html#Espresso">Espresso</a> allow you to
+programmatically simulate user actions and test complex intra-app user interactions.</td></tr>
+ <tr><td>Cross-app Components</td>
+ <td>This type of test verifies the correct behavior of interactions between different user
+apps or between user apps and system apps. For example, you might want to test that your app behaves
+correctly when the user performs an action in the Android Settings menu. UI testing frameworks
+that support cross-app interactions, such as UI Automator, allow you to create tests for such
+scenarios.</td></tr>
+</table>
+
+<p>Based on the type of test you want to create, you need to configure the test code source
+location and the project dependencies in Android Studio as described in
+<a href="{@docRoot}training/testing/start/index.html">Getting Started with Testing</a>.</p>
+
+<h2 id="TestAPI">Testing APIs</h2>
+<p>The following list summarizes the common APIs related to app testing for Android.</p>
+
+<h3 id="JUnit">JUnit</h3>
+
+<p>You should write your unit or integration test class as a JUnit 4 test class.
+<a href="http://junit.org/" class="external-link">JUnit</a> is the most popular
+and widely-used unit testing framework for Java. The framework offers a convenient way to perform
+common setup, teardown, and assertion operations in your test.</p>
+
+<p>JUnit 4 allows you to write tests in a cleaner and more
+flexible way than its predecessor versions. Unlike the previous approach to Android unit testing
+based on JUnit 3, with JUnit 4, you do not need to extend the {@code junit.framework.TestCase}
+class. You also do not need to prepend the {@code test} keyword to your test method name, or
+use any classes in the {@code junit.framework} or {@code junit.extensions} package.</p>
+
+<p>A basic JUnit 4 test class is a Java class that contains one or more test methods.
+A test method begins with the {@code @Test} annotation and contains the code to exercise
+and verify a single functionality (that is, a logical <em>unit</em>) in the component that you want
+to test.</p>
+<p>The following snippet shows an example JUnit 4 integration test that uses the Espresso
+APIs to perform a click action on a UI element, then checks to see if an expected string is
+displayed.</p>
+<pre>
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class MainActivityInstrumentationTest {
+
+ @Rule
+ public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(
+ MainActivity.class);
+
+ @Test
+ public void sayHello(){
+ onView(withText("Say hello!")).perform(click());
+
+ onView(withId(R.id.textView)).check(matches(withText("Hello, World!")));
+ }
+}
+</pre>
+<p>In your JUnit 4 test class, you can call out sections in your test code for
+special processing by using the following annotations:</p>
+<ul>
+<li>
+{@code @Before}: Use this annotation to specify a block of code that contains test setup
+operations. The test class invokes this code block before each test. You can have multiple
+{@code @Before} methods but the order in which the test class calls these methods
+is not guaranteed.
+</li>
+<li>
+{@code @After}: This annotation specifies a block of code that contains test
+tear-down operations. The test class calls this code block after every test method. You can define
+multiple {@code @After} operations in your test code. Use this annotation to release any
+resources from memory.
+</li>
+<li>
+{@code @Test}: Use this annotation to mark a test method. A single test class can contain
+multiple test methods, each prefixed with this annotation.
+</li>
+<li>
+{@code @Rule}: Rules allow you to flexibly add or redefine the behavior of each test
+method in a reusable way. In Android testing, use this annotation together with
+one of the test rule classes that the Android Testing Support Library provides, such as
+<a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html">
+{@code ActivityTestRule}</a> or
+<a href="{@docRoot}reference/android/support/test/rule/ServiceTestRule.html">
+{@code ServiceTestRule}</a>.
+</li>
+<li>
+{@code @BeforeClass}: Use this annotation to specify static methods for each test class to
+invoke only once. This testing step is useful for expensive operations such as connecting to a
+database.
+</li>
+<li>
+{@code @AfterClass}: Use this annotation to specify static methods for the test class to invoke
+only after all tests in the class have run. This testing step is useful for releasing any
+resources allocated in the {@code @BeforeClass} block.
+</li>
+<li>
+{@code @Test(timeout=<milliseconds>)}: Some annotations support the ability to pass in
+elements for which you can set values. For example, you can specify a timeout period for the test.
+If the test starts but does not complete within the given timeout period, it automatically fails.
+You must specify the timeout period in milliseconds, for example: {@code @Test(timeout=5000)}.
+</li>
+</ul>
+<p>For more annotations, see the documentation for
+<a href="//junit.sourceforge.net/javadoc/org/junit/package-summary.html" class="external-link">
+JUnit annotations</a> and the
+<a href="{@docRoot}android/support/test/annotation/package-summary.html">
+Android-specific annotations</a>.
<p>
- This document describes the fundamentals of the Android testing framework, including the
- structure of tests, the APIs that you use to develop tests, and the tools that you use to run
- tests and view results. The document assumes you have a basic knowledge of Android application
- programming and JUnit testing methodology.
+ You use the JUnit {@link junit.framework.Assert} class to verify the correctness of an object's
+ state. The assert methods compare values you expect from a test to the actual results and
+ throw an exception if the comparison fails. <a href="#AssertionClasses">
+ Assertion classes</a> describes these methods in more detail.
+</p>
+
+</p>
+<h3 id="Instrumentation">Instrumentation</h3>
+<p>
+ Android instrumentation is a set of control methods or hooks in the Android system. These
+ hooks control an Android component independently of its normal lifecycle. They also control how
+ Android loads applications.
</p>
<p>
The following diagram summarizes the testing framework:
@@ -134,410 +213,60 @@
alt="The Android testing framework"/>
</a>
</div>
-<h2 id="TestStructure">Test Structure</h2>
<p>
- Android's build and test tools assume that test projects are organized into a standard
- structure of tests, test case classes, test packages, and test projects.
+Normally, an Android component runs in a lifecycle that the system determines. For example, an
+{@link android.app.Activity} object's lifecycle starts when an {@link android.content.Intent}
+activates the {@link android.app.Activity}. The system calls the object's <code>onCreate()</code>
+method, on then the <code>onResume()</code> method. When the user starts another application, the
+system calls the <code>onPause()</code> method. If the {@link android.app.Activity} code calls
+the <code>finish()</code> method, the system calls the <code>onDestroy()</code> method. The Android
+framework API does not provide a way for your code to invoke these callback methods directly, but
+you can do so using instrumentation.
</p>
<p>
- Android testing is based on JUnit. In general, a JUnit test is a method whose
- statements test a part of the application under test. You organize test methods into classes
- called test cases (or test suites). Each test is an isolated test of an individual module in
- the application under test. Each class is a container for related test methods, although it
- often provides helper methods as well.
+The system runs all the components of an application in the same process. You can allow some
+components, such as content providers, to run in a separate process,
+but you can't force an application to run in the same process as another application that is
+already running.
</p>
<p>
- In JUnit, you build one or more test source files into a class file. Similarly, in Android you
- use the SDK's build tools to build one or more test source files into class files in an
- Android test package. In JUnit, you use a test runner to execute test classes. In Android, you
- use test tools to load the test package and the application under test, and the tools then
- execute an Android-specific test runner.
+Instrumentation can load both a test package and the app under test into the
+same process. Since the application components and their tests are in the same process, your
+tests can invoke methods in the components, and modify and examine fields in the components.
</p>
-<h2 id="TestProjects">Test Projects</h2>
+<h3 id="TestingSupportLibraryClasses">Android Testing Support Library APIs</h3>
<p>
- Tests, like Android applications, are organized into projects.
-</p>
-<p>
- A test project is a directory in which you create the source code, manifest
- file, and other files for a test package. The Android SDK contains tools for Android Studio
- and for the command line that create and update test projects for you. The tools create the
- directories you use for source code and resources and the manifest file for the test package.
-</p>
-<p>
- You should always use Android tools to create a test project. Among other benefits,
- the tools:
-</p>
- <ul>
- <li>
- Automatically set up your test package to use
- {@link android.test.InstrumentationTestRunner} as the test case runner. You must use
- <code>InstrumentationTestRunner</code> (or a subclass) to run JUnit tests.
- </li>
- <li>
- Create an appropriate name for the test package. If the application
- under test has a package name of <code>com.mydomain.myapp</code>, then the
- Android tools set the test package name to <code>com.mydomain.myapp.test</code>. This
- helps you identify their relationship, while preventing conflicts within the system.
- </li>
- <li>
- Automatically create the proper build files, manifest file, and directory
- structure for the test project. This helps you to build the test package without
- having to modify build files and sets up the linkage between your test package and
- the application under test.
- The
- </li>
- </ul>
-<p>
- You can create a test project anywhere in your file system, but the best approach is to
- add the test project so that its root directory <code>tests/</code> is at the same level
- as the <code>src/</code> directory of the main application's project. This helps you find the
- tests associated with an application. For example, if your application project's root directory
- is <code>MyProject</code>, then you should use the following directory structure:
-</p>
-<pre class="classic no-pretty-print">
- MyProject/
- AndroidManifest.xml
- res/
- ... (resources for main application)
- src/
- ... (source code for main application) ...
- tests/
- AndroidManifest.xml
- res/
- ... (resources for tests)
- src/
- ... (source code for tests)
-</pre>
-<h2 id="TestAPI">The Testing API</h2>
-<p>
- The Android testing API is based on the JUnit API and extended with a instrumentation
- framework and Android-specific testing classes.
-</p>
-<h3 id="JUnit">JUnit</h3>
-<p>
- You can use the JUnit {@link junit.framework.TestCase TestCase} class to do unit testing on
- a class that doesn't call Android APIs. <code>TestCase</code> is also the base class for
- {@link android.test.AndroidTestCase}, which you can use to test Android-dependent objects.
- Besides providing the JUnit framework, AndroidTestCase offers Android-specific setup,
- teardown, and helper methods.
-</p>
-<p>
- You use the JUnit {@link junit.framework.Assert} class to display test results.
- The assert methods compare values you expect from a test to the actual results and
- throw an exception if the comparison fails. Android also provides a class of assertions that
- extend the possible types of comparisons, and another class of assertions for testing the UI.
- These are described in more detail in the section <a href="#AssertionClasses">
- Assertion classes</a>
-</p>
-<p>
- To learn more about JUnit, you can read the documentation on the
- <a href="http://www.junit.org">junit.org</a> home page.
- Note that the Android testing API supports JUnit 3 code style, but not JUnit 4. Also, you must
- use Android's instrumented test runner {@link android.test.InstrumentationTestRunner} to run
- your test case classes. This test runner is described in the
- section <a href="#InstrumentationTestRunner">Running Tests</a>.
-</p>
-<h3 id="Instrumentation">Instrumentation</h3>
-<p>
- Android instrumentation is a set of control methods or "hooks" in the Android system. These hooks
- control an Android component independently of its normal lifecycle. They also control how
- Android loads applications.
-</p>
-<p>
- Normally, an Android component runs in a lifecycle determined by the system. For example, an
- Activity object's lifecycle starts when the Activity is activated by an Intent. The object's
- <code>onCreate()</code> method is called, followed by <code>onResume()</code>. When the user
- starts another application, the <code>onPause()</code> method is called. If the Activity
- code calls the <code>finish()</code> method, the <code>onDestroy()</code> method is called.
- The Android framework API does not provide a way for your code to invoke these callback
- methods directly, but you can do so using instrumentation.
-</p>
-<p>
- Also, the system runs all the components of an application into the same
- process. You can allow some components, such as content providers, to run in a separate process,
- but you can't force an application to run in the same process as another application that is
- already running.
-</p>
-<p>
- With Android instrumentation, though, you can invoke callback methods in your test code.
- This allows you to run through the lifecycle of a component step by step, as if you were
- debugging the component. The following test code snippet demonstrates how to use this to
- test that an Activity saves and restores its state:
-</p>
-<a name="ActivitySnippet"></a>
-<pre>
- // Start the main activity of the application under test
- mActivity = getActivity();
-
- // Get a handle to the Activity object's main UI widget, a Spinner
- mSpinner = (Spinner)mActivity.findViewById(com.android.example.spinner.R.id.Spinner01);
-
- // Set the Spinner to a known position
- mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION);
-
- // Stop the activity - The onDestroy() method should save the state of the Spinner
- mActivity.finish();
-
- // Re-start the Activity - the onResume() method should restore the state of the Spinner
- mActivity = getActivity();
-
- // Get the Spinner's current position
- int currentPosition = mActivity.getSpinnerPosition();
-
- // Assert that the current position is the same as the starting position
- assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition);
-</pre>
-<p>
- The key method used here is
- {@link android.test.ActivityInstrumentationTestCase2#getActivity()}, which is a
- part of the instrumentation API. The Activity under test is not started until you call this
- method. You can set up the test fixture in advance, and then call this method to start the
- Activity.
-</p>
-<p>
- Also, instrumentation can load both a test package and the application under test into the
- same process. Since the application components and their tests are in the same process, the
- tests can invoke methods in the components, and modify and examine fields in the components.
-</p>
-<h3 id="TestCaseClasses">Test case classes</h3>
-<p>
- Android provides several test case classes that extend {@link junit.framework.TestCase} and
- {@link junit.framework.Assert} with Android-specific setup, teardown, and helper methods.
-</p>
-<h4 id="AndroidTestCase">AndroidTestCase</h4>
-<p>
- A useful general test case class, especially if you are
- just starting out with Android testing, is {@link android.test.AndroidTestCase}. It extends
- both {@link junit.framework.TestCase} and {@link junit.framework.Assert}. It provides the
- JUnit-standard <code>setUp()</code> and <code>tearDown()</code> methods, as well as
- all of JUnit's Assert methods. In addition, it provides methods for testing permissions, and a
- method that guards against memory leaks by clearing out certain class references.
-</p>
-<h4 id="ComponentTestCase">Component-specific test cases</h4>
-<p>
- A key feature of the Android testing framework is its component-specific test case classes.
- These address specific component testing needs with methods for fixture setup and
- teardown and component lifecycle control. They also provide methods for setting up mock objects.
- These classes are described in the component-specific testing topics:
-</p>
+The <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>
+provides a set of APIs that allow you to quickly build and run test code for your apps, including
+JUnit 4 and functional user interface (UI) tests. The library includes the following
+instrumentation-based APIs that are useful when you want to automate your tests:</p>
<ul>
- <li>
- <a href="{@docRoot}tools/testing/activity_testing.html">Activity Testing</a>
+ <li><a href="{@docRoot}tools/testing-support-library/index.html#AndroidJUnitRunner">
+ {@code AndroidJUnitRunner}</a>:
+ JUnit 4-compatible test runner for Android
</li>
- <li>
- <a href="{@docRoot}tools/testing/contentprovider_testing.html">
- Content Provider Testing</a>
+
+ <li><a href="{@docRoot}tools/testing-support-library/index.html#Espresso">Espresso</a>:
+ UI testing framework; suitable for functional UI testing within an app
</li>
- <li>
- <a href="{@docRoot}tools/testing/service_testing.html">Service Testing</a>
- </li>
-</ul>
-<p>
- Android does not provide a separate test case class for BroadcastReceiver. Instead, test a
- BroadcastReceiver by testing the component that sends it Intent objects, to verify that the
- BroadcastReceiver responds correctly.
-</p>
-<h4 id="ApplicationTestCase">ApplicationTestCase</h4>
-<p>
- You use the {@link android.test.ApplicationTestCase} test case class to test the setup and
- teardown of {@link android.app.Application} objects. These objects maintain the global state of
- information that applies to all the components in an application package. The test case can
- be useful in verifying that the <application> element in the manifest file is correctly
- set up. Note, however, that this test case does not allow you to control testing of the
- components within your application package.
-</p>
-<h4 id="InstrumentationTestCase">InstrumentationTestCase</h4>
-<p>
- If you want to use instrumentation methods in a test case class, you must use
- {@link android.test.InstrumentationTestCase} or one of its subclasses. The
- {@link android.app.Activity} test cases extend this base class with other functionality that
- assists in Activity testing.
-</p>
+
+ <li><a href="{@docRoot}tools/testing-support-library/index.html#UIAutomator">UI Automator</a>:
+ UI testing framework; suitable for cross-app functional UI testing across system and installed
+ apps</li>
+ </ul>
<h3 id="AssertionClasses">Assertion classes</h3>
-<p>
- Because Android test case classes extend JUnit, you can use assertion methods to display the
- results of tests. An assertion method compares an actual value returned by a test to an
- expected value, and throws an AssertionException if the comparison test fails. Using assertions
- is more convenient than doing logging, and provides better test performance.
+<p>Because Android Testing Support Library APIs extend JUnit, you can use assertion methods to
+display the results of tests. An assertion method compares an actual value returned by a test to an
+expected value, and throws an AssertionException if the comparison test fails. Using assertions
+is more convenient than logging, and provides better test performance.
</p>
-<p>
- Besides the JUnit {@link junit.framework.Assert} class methods, the testing API also provides
- the {@link android.test.MoreAsserts} and {@link android.test.ViewAsserts} classes:
-</p>
-<ul>
- <li>
- {@link android.test.MoreAsserts} contains more powerful assertions such as
- {@link android.test.MoreAsserts#assertContainsRegex}, which does regular expression
- matching.
- </li>
- <li>
- {@link android.test.ViewAsserts} contains useful assertions about Views. For example
- it contains {@link android.test.ViewAsserts#assertHasScreenCoordinates} that tests if a View
- has a particular X and Y position on the visible screen. These asserts simplify testing of
- geometry and alignment in the UI.
- </li>
-</ul>
-<h3 id="MockObjectClasses">Mock object classes</h3>
-<p>
- To facilitate dependency injection in testing, Android provides classes that create mock system
- objects such as {@link android.content.Context} objects,
- {@link android.content.ContentProvider} objects, {@link android.content.ContentResolver}
- objects, and {@link android.app.Service} objects. Some test cases also provide mock
- {@link android.content.Intent} objects. You use these mocks both to isolate tests
- from the rest of the system and to facilitate dependency injection for testing. These classes
- are found in the packages {@link android.test} and {@link android.test.mock}.
-</p>
-<p>
- Mock objects isolate tests from a running system by stubbing out or overriding
- normal operations. For example, a {@link android.test.mock.MockContentResolver}
- replaces the normal resolver framework with its own local framework, which is isolated
- from the rest of the system. MockContentResolver also stubs out the
- {@link android.content.ContentResolver#notifyChange(Uri, ContentObserver, boolean)} method
- so that observer objects outside the test environment are not accidentally triggered.
-</p>
-<p>
- Mock object classes also facilitate dependency injection by providing a subclass of the
- normal object that is non-functional except for overrides you define. For example, the
- {@link android.test.mock.MockResources} object provides a subclass of
- {@link android.content.res.Resources} in which all the methods throw Exceptions when called.
- To use it, you override only those methods that must provide information.
-</p>
-<p>
- These are the mock object classes available in Android:
-</p>
-<h4 id="SimpleMocks">Simple mock object classes</h4>
-<p>
- {@link android.test.mock.MockApplication}, {@link android.test.mock.MockContext},
- {@link android.test.mock.MockContentProvider}, {@link android.test.mock.MockCursor},
- {@link android.test.mock.MockDialogInterface}, {@link android.test.mock.MockPackageManager}, and
- {@link android.test.mock.MockResources} provide a simple and useful mock strategy. They are
- stubbed-out versions of the corresponding system object class, and all of their methods throw an
- {@link java.lang.UnsupportedOperationException} exception if called. To use them, you override
- the methods you need in order to provide mock dependencies.
-</p>
-<p class="Note"><strong>Note:</strong>
- {@link android.test.mock.MockContentProvider}
- and {@link android.test.mock.MockCursor} are new as of API level 8.
-</p>
-<h4 id="ResolverMocks">Resolver mock objects</h4>
-<p>
- {@link android.test.mock.MockContentResolver} provides isolated testing of content providers by
- masking out the normal system resolver framework. Instead of looking in the system to find a
- content provider given an authority string, MockContentResolver uses its own internal table. You
- must explicitly add providers to this table using
- {@link android.test.mock.MockContentResolver#addProvider(String,ContentProvider)}.
-</p>
-<p>
- With this feature, you can associate a mock content provider with an authority. You can create
- an instance of a real provider but use test data in it. You can even set the provider for an
- authority to <code>null</code>. In effect, a MockContentResolver object isolates your test
- from providers that contain real data. You can control the
- function of the provider, and you can prevent your test from affecting real data.
-</p>
-<h3 id="ContextMocks">Contexts for testing</h3>
-<p>
- Android provides two Context classes that are useful for testing:
-</p>
-<ul>
- <li>
- {@link android.test.IsolatedContext} provides an isolated {@link android.content.Context},
- File, directory, and database operations that use this Context take place in a test area.
- Though its functionality is limited, this Context has enough stub code to respond to
- system calls.
- <p>
- This class allows you to test an application's data operations without affecting real
- data that may be present on the device.
- </p>
- </li>
- <li>
- {@link android.test.RenamingDelegatingContext} provides a Context in which
- most functions are handled by an existing {@link android.content.Context}, but
- file and database operations are handled by a {@link android.test.IsolatedContext}.
- The isolated part uses a test directory and creates special file and directory names.
- You can control the naming yourself, or let the constructor determine it automatically.
- <p>
- This object provides a quick way to set up an isolated area for data operations,
- while keeping normal functionality for all other Context operations.
- </p>
- </li>
-</ul>
-<h2 id="InstrumentationTestRunner">Running Tests</h2>
-<p>
- Test cases are run by a test runner class that loads the test case class, set ups,
- runs, and tears down each test. An Android test runner must also be instrumented, so that
- the system utility for starting applications can control how the test package
- loads test cases and the application under test. You tell the Android platform
- which instrumented test runner to use by setting a value in the test package's manifest file.
-</p>
-<p>
- {@link android.test.InstrumentationTestRunner} is the primary Android test runner class. It
- extends the JUnit test runner framework and is also instrumented. It can run any of the test
- case classes provided by Android and supports all possible types of testing.
-</p>
-<p>
- You specify <code>InstrumentationTestRunner</code> or a subclass in your test package's
- manifest file, in the
-<code><a href="{@docRoot}guide/topics/manifest/instrumentation-element.html"><instrumentation></a></code>
- element. Also, <code>InstrumentationTestRunner</code> code resides
- in the shared library <code>android.test.runner</code>, which is not normally linked to
- Android code. To include it, you must specify it in a
-<code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html"><uses-library></a></code>
- element. You do not have to set up these elements yourself. Both Android Studio and the
- <code>android</code> command-line tool construct them automatically and add them to your
- test package's manifest file.
-</p>
-<p class="Note">
- <strong>Note:</strong> If you use a test runner other than
- <code>InstrumentationTestRunner</code>, you must change the <instrumentation>
- element to point to the class you want to use.
-</p>
-<p>
- To run {@link android.test.InstrumentationTestRunner}, you use internal system classes called by
- Android tools. When you run a test in Android Studio the classes are called automatically.
- When you run a test from the command line, you run these classes with
- <a href="{@docRoot}tools/help/adb.html">Android Debug Bridge (adb)</a>.
-</p>
-<p>
- The system classes load and start the test package, kill any processes that
- are running an instance of the application under test, and then load a new instance of the
- application under test. They then pass control to
- {@link android.test.InstrumentationTestRunner}, which runs
- each test case class in the test package. You can also control which test cases and
- methods are run using settings in Android Studio or using flags with the command-line tools.
-</p>
-<p>
- Neither the system classes nor {@link android.test.InstrumentationTestRunner} run
- the application under test. Instead, the test case does this directly. It either calls methods
- in the application under test, or it calls its own methods that trigger lifecycle events in
- the application under test. The application is under the complete control of the test case,
- which allows it to set up the test environment (the test fixture) before running a test. This
- is demonstrated in the previous <a href="#ActivitySnippet">code snippet</a> that tests an
- Activity that displays a Spinner widget.
-</p>
-<p>
- To learn more about running tests, please read
- <a href="{@docRoot}tools/testing/testing_otheride.html">
- Testing from Other IDEs</a>.
-</p>
-<h2 id="TestResults">Seeing Test Results</h2>
-<p>
- The Android testing framework returns test results back to the tool that started the test.
- If you run a test in Android Studio, the results are displayed in a new JUnit view pane. If
- you run a test from the command line, the results are displayed in <code>STDOUT</code>. In
- both cases, you see a test summary that displays the name of each test case and method that
- was run. You also see all the assertion failures that occurred. These include pointers to the
- line in the test code where the failure occurred. Assertion failures also list the expected
- value and actual value.
-</p>
-<p>
- The test results have a format that is specific to the IDE that you are using. The test
-results format for tests run from the
- command line is described in
- <a href="{@docRoot}tools/testing/testing_otheride.html#RunTestsCommand">
- Testing from Other IDEs</a>.
-</p>
-<h2 id="Monkeys">monkey and monkeyrunner</h2>
+<p>To simplify your test development, we recommend that you use the
+<a href="https://github.com/hamcrest"
+class="external-link">Hamcrest</a> library, which lets you create more flexible tests using the
+Hamcrest matcher APIs.</p>
+
+<h2 id="Monkeys">Monkey and Monkeyrunner</h2>
<p>
The SDK provides two tools for functional-level application testing:
</p>
@@ -560,67 +289,4 @@
tests. You run programs that use the API with the <code>monkeyrunner</code> command-line
tool.
</li>
- </ul>
-<h2 id="PackageNames">Working With Package names</h2>
-<p>
- In the test environment, you work with both Android application package names and
- Java package identifiers. Both use the same naming format, but they represent substantially
- different entities. You need to know the difference to set up your tests correctly.
-</p>
-<p>
- An Android package name is a unique system name for a <code>.apk</code> file, set by the
- "android:package" attribute of the <manifest> element in the package's
- manifest. The Android package name of your test package must be different from the
- Android package name of the application under test. By default, Android tools create the
- test package name by appending ".test" to the package name of the application under test.
-</p>
-<p>
- The test package also uses an Android package name to target the application package it
- tests. This is set in the "android:targetPackage" attribute of the
- <instrumentation> element in the test package's manifest.
-</p>
-<p>
- A Java package identifier applies to a source file. This package name reflects the directory
- path of the source file. It also affects the visibility of classes and members to each other.
-</p>
-<p>
- Android tools that create test projects set up an Android test package name for you.
- From your input, the tools set up the test package name and the target package name for the
- application under test. For these tools to work, the application project must already exist.
-</p>
-<p>
- By default, these tools set the Java package identifier for the test class to be the same
- as the Android package identifier. You may want to change this if you want to expose
- members in the application under test by giving them package visibility. If you do this,
- change only the Java package identifier, not the Android package names, and change only the
- test case source files. Do not change the Java package name of the generated
- <code>R.java</code> class in your test package, because it will then conflict with the
- <code>R.java</code> class in the application under test. Do not change the Android package name
- of your test package to be the same as the application it tests, because then their names
- will no longer be unique in the system.
-</p>
-<h2 id="WhatToTest">What to Test</h2>
-<p>
- The topic <a href="{@docRoot}tools/testing/what_to_test.html">What To Test</a>
- describes the key functionality you should test in an Android application, and the key
- situations that might affect that functionality.
-</p>
-<p>
- Most unit testing is specific to the Android component you are testing.
- The topics <a href="{@docRoot}tools/testing/activity_testing.html">Activity Testing</a>,
- <a href="{@docRoot}tools/testing/contentprovider_testing.html">
- Content Provider Testing</a>, and <a href="{@docRoot}tools/testing/service_testing.html">
- Service Testing</a> each have a section entitled "What To Test" that lists possible testing
- areas.
-</p>
-<p>
- When possible, you should run these tests on an actual device. If this is not possible, you can
- use the <a href="{@docRoot}tools/devices/emulator.html">Android Emulator</a> with
- Android Virtual Devices configured for the hardware, screens, and versions you want to test.
-</p>
-<h2 id="NextSteps">Next Steps</h2>
-
-<p>
- If you want a step-by-step introduction to Android testing, try the
- <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a>.
-</p>
+ </ul>
\ No newline at end of file
diff --git a/docs/html/tools/testing/testing_otheride.jd b/docs/html/tools/testing/testing_otheride.jd
index 8a3eb05..4b2a6b1 100755
--- a/docs/html/tools/testing/testing_otheride.jd
+++ b/docs/html/tools/testing/testing_otheride.jd
@@ -1,6 +1,5 @@
-page.title=Testing from Other IDEs
-parent.title=Testing
-parent.link=index.html
+page.title=Testing from the Command-Line
+
@jd:body
<div id="qv-wrapper">
@@ -8,27 +7,13 @@
<h2>In this document</h2>
<ol>
<li>
- <a href="#CreateTestProjectCommand">Working with Test Projects</a>
- <ol>
- <li>
- <a href="#CreateTestProject">Creating a test project</a>
- </li>
- <li>
- <a href="#UpdateTestProject">Updating a test project</a>
- </li>
- </ol>
- </li>
- <li>
- <a href="#CreateTestApp">Creating a Test Package</a>
- </li>
- <li>
<a href="#RunTestsCommand">Running Tests</a>
<ol>
<li>
- <a href="#RunTestsAnt">Quick build and run with Gradle</a>
+ <a href="#RunTestsGradle">Running unit tests with Gradle</a>
</li>
<li>
- <a href="#RunTestsDevice">Running tests on a device or emulator</a>
+ <a href="#RunTestsDevice">Running tests with adb</a>
</li>
</ol>
</li>
@@ -47,288 +32,84 @@
<h2>See Also</h2>
<ol>
<li>
- <a href="{@docRoot}tools/testing/testing_android.html">
- Testing Fundamentals</a>
- </li>
- <li>
<a href="{@docRoot}tools/help/adb.html">Android Debug Bridge</a>
</li>
</ol>
</div>
</div>
<p>
- This document describes how to create and run tests directly from the command line.
- You can use the techniques described here if you are developing in an IDE other than Android Studio
- or if you prefer to work from the command line. This document assumes that you already know how
- to create a Android application in your programming environment. Before you start this
- document, you should read the topic
- <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>,
- which provides an overview of Android testing.
-</p>
-<p>
- If you are developing in Android Studio, you can set up and run your tests
- directly in Android Studio.
-</p>
-<h2 id="CreateTestProjectCommand">Working with Test Projects</h2>
-<p>
- You use the <code>android</code> tool to create test projects.
- You also use <code>android</code> to convert existing test code into an Android test project,
- or to add the <code>test</code> Gradle target to an existing Android test project.
- These operations are described in more detail in the section <a href="#UpdateTestProject">
- Updating a test project</a>. The <code>test</code> target is described in
- <a href="#RunTestsAnt">Quick build and run with Gradle</a>.
-</p>
-<h3 id="CreateTestProject">Creating a test project</h3>
-<p>
- To create a test project with the <code>android</code> tool, enter:
-</p>
-<pre>
-android create test-project -m <main_path> -n <project_name> -p <test_path>
-</pre>
-<p>
- You must supply all the flags. The following table explains them in detail:
-</p>
-<table>
- <tr>
- <th>Flag</th>
- <th>Value</th>
- <th>Description</th>
- </tr>
- <tr>
- <td><code>-m, --main</code></td>
- <td>
- Path to the project of the application under test, relative to the test package
- directory.
- </td>
- <td>
- For example, if the application under test is in <code>source/HelloAndroid</code>, and
- you want to create the test project in <code>source/HelloAndroidTest</code>, then the
- value of <code>--main</code> should be <code>../HelloAndroid</code>.
- <p>
- To learn more about choosing the location of test projects, please read
- <a href="{@docRoot}tools/testing/testing_android.html#TestProjects">
- Testing Fundamentals</a>.
- </p>
- </td>
- </tr>
- <tr>
- <td><code>-n, --name</code></td>
- <td>Name that you want to give the test project.</td>
- <td> </td>
- </tr>
- <tr>
- <td><code>-p, --path</code></td>
- <td>Directory in which you want to create the new test project.</td>
- <td>
- The <code>android</code> tool creates the test project files and directory structure
- in this directory. If the directory does not exist, <code>android</code> creates it.
- </td>
- </tr>
-</table>
-<p>
- If the operation is successful, <code>android</code> lists to STDOUT the names of the files
- and directories it has created.
-</p>
-<p>
- This creates a new test project with the appropriate directories and build files. The directory
- structure and build file contents are identical to those in a regular Android application
- project. They are described in detail in the topic
- <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>.
-</p>
-<p>
- The operation also creates an <code>AndroidManifest.xml</code> file with instrumentation
- information. When you run the test, Android uses this information to load the application you
- are testing and control it with instrumentation.
-</p>
-<p>
- For example, suppose you create a project in the directory <code>~/source/HelloAndroid</code>,
-with the package name <code>com.example.helloandroid</code>,
- and the activity name <code>HelloAndroid</code>. You can to create the test for this in
- <code>~/source/HelloAndroidTest</code>. To do so, you enter:
-</p>
-<pre>
-$ cd ~/source
-$ android create test-project -m ../HelloAndroid -n HelloAndroidTest -p HelloAndroidTest
-</pre>
-<p>
- This creates a directory called <code>~/src/HelloAndroidTest</code>. In the new directory you
- see the file <code>AndroidManifest.xml</code>. This file contains the following
- instrumentation-related elements and attributes:
-</p>
-<ul>
- <li>
- <code><application></code>: to contain the
- <code><uses-library></code> element.
- </li>
- <li>
- <code><uses-library android:name="android.test.runner"</code>:
- specifies this testing application uses the <code>android.test.runner</code> library.
- </li>
- <li>
- <code><instrumentation></code>: contains attributes that control Android
- instrumentation. The attributes are:
- <ul>
- <li>
- <code>android:name="android.test.InstrumentationTestRunner"</code>:
- {@link android.test.InstrumentationTestRunner} runs test cases. It extends both
- JUnit test case runner classes and Android instrumentation classes.
- </li>
- <li>
- <code>android:targetPackage="com.example.helloandroid"</code>: specifies
- that the tests in HelloAndroidTest should be run against the application with the
- <em>Android</em> package name <code>com.example.helloandroid</code>.
- </li>
- <li>
- <code>android:label="Tests for .HelloAndroid"</code>: specifies a
- user-readable label for the instrumentation class. By default,
- the <code>android</code> tool gives it the value "Tests for " plus
- the name of the main Activity of the application under test.
- </li>
- </ul>
- </li>
-</ul>
-<h3 id="UpdateTestProject">Updating a test project</h3>
-<p>
- You use the <code>android</code> tool when you need to change the path to the
- project of the application under test. If you are changing an existing test project created in
- Android Studio so that you can also build and run it from the command line, you must use the
- "create" operation. See the section <a href="#CreateTestProject">Creating a test project</a>.
-</p>
-<p class="note">
- <strong>Note:</strong> If you change the Android package name of the application under test,
- you must <em>manually</em> change the value of the <code><android:targetPackage></code>
- attribute within the <code>AndroidManifest.xml</code> file of the test package.
- Running <code>android update test-project</code> does not do this.
-</p>
-<p>
- To update a test project with the <code>android</code> tool, enter:
-</p>
-<pre>android update test-project -m <main_path> -p <test_path></pre>
-
-<table>
- <tr>
- <th>Flag</th>
- <th>Value</th>
- <th>Description</th>
- </tr>
- <tr>
- <td><code>-m, --main</code></td>
- <td>The path to the project of the application under test, relative to the test project</td>
- <td>
- For example, if the application under test is in <code>source/HelloAndroid</code>, and
- the test project is in <code>source/HelloAndroidTest</code>, then the value for
- <code>--main</code> is <code>../HelloAndroid</code>.
- </td>
- </tr>
- <tr>
- <td><code>-p, --path</code></td>
- <td>The of the test project.</td>
- <td>
- For example, if the test project is in <code>source/HelloAndroidTest</code>, then the
- value for <code>--path</code> is <code>HelloAndroidTest</code>.
- </td>
- </tr>
-</table>
-<p>
- If the operation is successful, <code>android</code> lists to STDOUT the names of the files
- and directories it has created.
-</p>
-<h2 id="CreateTestApp">Creating a Test Package</h2>
-<p>
- Once you have created a test project, you populate it with a test package.
- The application does not require an {@link android.app.Activity Activity},
- although you can define one if you wish. Although your test package can
- combine Activities, Android test class extensions, JUnit extensions, or
- ordinary classes, you should extend one of the Android test classes or JUnit classes,
- because these provide the best testing features.
-</p>
-<p>
- If you run your tests with {@link android.test.InstrumentationTestRunner}
- (or a related test runner), then it will run all the methods in each class. You can modify
- this behavior by using the {@link junit.framework.TestSuite TestSuite} class.
+ This document describes how to create and run tests directly from the command line. This
+ document assumes that you already know how to create a Android application in your programming
+ environment.
</p>
-<p>
- To create a test package, start with one of Android's test classes in the Java package
- {@link android.test android.test}. These extend the JUnit
- {@link junit.framework.TestCase TestCase} class. With a few exceptions, the Android test
- classes also provide instrumentation for testing.
-</p>
-<p>
- For test classes that extend {@link junit.framework.TestCase TestCase}, you probably want to
- override the <code>setUp()</code> and <code>tearDown()</code> methods:
-</p>
-<ul>
- <li>
- <code>setUp()</code>: This method is invoked before any of the test methods in the class.
- Use it to set up the environment for the test. You can use <code>setUp()</code>
- to instantiate a new <code>Intent</code> object with the action <code>ACTION_MAIN</code>.
- You can then use this intent to start the Activity under test.
- <p class="note">
- <strong>Note:</strong> If you override this method, call
- <code>super.setUp()</code> as the first statement in your code.
- </p>
- </li>
- <li>
- <code>tearDown()</code>: This method is invoked after all the test methods in the class. Use
- it to do garbage collection and re-setting before moving on to the next set of tests.
- <p class="note"><strong>Note:</strong> If you override this method, you must call
- <code>super.tearDown()</code> as the <em>last</em> statement in your code.</p>
- </li>
-</ul>
-<p>
- Another useful convention is to add the method <code>testPreConditions()</code> to your test
- class. Use this method to test that the application under test is initialized correctly. If this
- test fails, you know that the initial conditions were in error. When this happens, further
- test results are suspect, regardless of whether or not the tests succeeded.
-</p>
-<p>
- To learn more about creating test packages, see the topic <a
- href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>,
- which provides an overview of Android testing. If you prefer to follow a tutorial,
- try the <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing</a>
- tutorial, which leads you through the creation of tests for an actual Android application.
-</p>
<h2 id="RunTestsCommand">Running Tests</h2>
<p>
- You run tests from the command line, either with Gradle or with an
+ You can run tests from the command-line, either with Gradle or with an
<a href="{@docRoot}tools/help/adb.html">
Android Debug Bridge (adb)</a> shell.
</p>
-<h3 id="RunTestsAnt">Quick build and run with Gradle</h3>
+<h3 id="RunTestsGradle">Running unit tests with Gradle</h3>
+
+<p>The <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plugin for Gradle</a>
+lets you run unit tests from your Gradle project via the command-line. For more information on
+how to build unit tests for your app, see
+<a href="{@docRoot}training/testing/unit-testing/index.html">Building Effective Unit Tests</a>.</p>
+
+<p>The table below summarizes how to run your unit tests with Gradle:</p>
+<table>
+ <tr>
+ <th>Unit Test Type</th>
+ <th>Command To Run</th>
+ <th>Test Result Location</th>
+ </tr>
+ <tr>
+ <td>Local unit test</td>
+ <td>Call the {@code test} task:
+<pre>
+./gradlew test
+</pre></td>
+ <td>
+HTML test result files:
+{@code <path_to_your_project>/app/build/reports/tests/} directory.
+<p>XML test result files:
+{@code <path_to_your_project>/app/build/test-results/} directory.
+</p></td>
+ </tr>
+ <tr>
+ <td>Instrumented unit test</td>
+ <td>Call the {@code connectedAndroidTest} (or {@code cAT}) task:
+<pre>
+./gradlew cAT
+</pre>
+ </td>
+ <td>
+HTML test result files:
+{@code <path_to_your_project>/app/build/outputs/reports/androidTests/connected/} directory.
+<p>XML test result files:
+{@code <path_to_your_project>/app/build/outputs/androidTest-results/connected/} directory.
+</p></td>
+ </tr>
+</table>
+
+<h3 id="RunTestsDevice">Running tests with ADB</h3>
<p>
- You can use Gradle to run all the tests in your test project, using the target
- <code>test</code>, which is created automatically when you create a test project with
- the <code>android</code> tool.
-</p>
-<p>
- This target re-builds your main project and test project if necessary, installs the test
- application to the current AVD or device, and then runs all the test classes in the test
- application. The results are directed to <code>STDOUT</code>.
-</p>
-<p>
- You can update an existing test project to use this feature. To do this, use the
- <code>android</code> tool with the <code>update test-project</code> option. This is described
- in the section <a href="#UpdateTestProject">Updating a test project</a>.
-</p>
-<h3 id="RunTestsDevice">Running tests on a device or emulator</h3>
-<p>
- When you run tests from the command line with
+ When you run tests from the command-line with
<a href="{@docRoot}tools/help/adb.html">
Android Debug Bridge (adb)</a>, you get more options for choosing the tests
to run than with any other method. You can select individual test methods, filter tests
according to their annotation, or specify testing options. Since the test run is controlled
- entirely from a command line, you can customize your testing with shell scripts in various ways.
+ entirely from a command-line, you can customize your testing with shell scripts in various ways.
</p>
<p>
- To run a test from the command line, you run <code>adb shell</code> to start a command-line
+ To run a test from the command-line, you run <code>adb shell</code> to start a command-line
shell on your device or emulator, and then in the shell run the <code>am instrument</code>
command. You control <code>am</code> and your tests with command-line flags.
</p>
<p>
As a shortcut, you can start an <code>adb</code> shell, call <code>am instrument</code>, and
specify command-line flags all on one input line. The shell opens on the device or emulator,
- runs your tests, produces output, and then returns to the command line on your computer.
+ runs your tests, produces output, and then returns to the command-line on your computer.
</p>
<p>
To run a test with <code>am instrument</code>:
@@ -341,7 +122,7 @@
Install your test package and main application Android package files
(<code>.apk</code> files) to your current Android device or emulator</li>
<li>
- At the command line, enter:
+ At the command-line, enter:
<pre>
$ adb shell am instrument -w <test_package_name>/<runner_class>
</pre>
@@ -351,7 +132,9 @@
runner class you are using. The Android package name is the value of the
<code>package</code> attribute of the <code>manifest</code> element in the manifest file
(<code>AndroidManifest.xml</code>) of your test package. The Android test runner
- class is usually {@link android.test.InstrumentationTestRunner}.
+ class is usually
+<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+{@code AndroidJUnitRunner}</a>.
</p>
<p>
Your test results appear in <code>STDOUT</code>.
@@ -369,7 +152,7 @@
The general syntax of the <code>am instrument</code> command is:
</p>
<pre>
- am instrument [flags] <test_package>/<runner_class>
+am instrument [flags] <test_package>/<runner_class>
</pre>
<p>
The main input parameters to <code>am instrument</code> are described in the following table:
@@ -406,10 +189,13 @@
The class name of the instrumented test runner you are using.
</td>
<td>
- This is usually {@link android.test.InstrumentationTestRunner}.
+ This is usually
+<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+{@code AndroidJUnitRunner}</a>.
</td>
</tr>
</table>
+
<p>
The flags for <code>am instrument</code> are described in the following table:
</p>
@@ -465,12 +251,11 @@
<code>am instrument</code> tool passes these to the specified instrumentation class
via its <code>onCreate()</code> method. You can specify multiple occurrences of
<code>-e <test_options></code>. The keys and values are described in the
- section <a href="#AMOptionsSyntax">am instrument options</a>.
- <p>
- The only instrumentation class that uses these key-value pairs is
- {@link android.test.InstrumentationTestRunner} (or a subclass). Using them with
- any other class has no effect.
- </p>
+ section <a href="#AMOptionsSyntax">am instrument options</a>. You can only use these
+ key-value pairs with
+<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+{@code AndroidJUnitRunner}</a> or with {@link android.test.InstrumentationTestRunner} and its
+subclasses. Using them with any other class has no effect.
</td>
</tr>
</table>
@@ -478,25 +263,24 @@
<h3 id="AMOptionsSyntax">am instrument options</h3>
<p>
The <code>am instrument</code> tool passes testing options to
- <code>InstrumentationTestRunner</code> or a subclass in the form of key-value pairs,
- using the <code>-e</code> flag, with this syntax:
+<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+{@code AndroidJUnitRunner}</a> or {@link android.test.InstrumentationTestRunner} in the form of
+key-value pairs, using the <code>-e</code> flag, with this syntax:
</p>
<pre>
- -e <key> <value>
+-e <key> <value>
</pre>
<p>
Some keys accept multiple values. You specify multiple values in a comma-separated list.
- For example, this invocation of <code>InstrumentationTestRunner</code> provides multiple
- values for the <code>package</code> key:
+ For example, this invocation of
+<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+{@code AndroidJUnitRunner}</a> provides multiple values for the <code>package</code> key:
</p>
<pre>
$ adb shell am instrument -w -e package com.android.test.package1,com.android.test.package2 \
-> com.android.test/android.test.InstrumentationTestRunner
+> com.android.test/android.support.test.runner.AndroidJUnitRunner
</pre>
-<p>
- The following table describes the key-value pairs and their result. Please review the
- <strong>Usage Notes</strong> following the table.
-</p>
+<p>The following table lists the key-value pairs you can use with your test runner.</p>
<table>
<tr>
<th>Key</th>
@@ -554,8 +338,8 @@
[<code>small</code> | <code>medium</code> | <code>large</code>]
</td>
<td>
- Runs a test method annotated by size. The annotations are <code>@SmallTest</code>,
- <code>@MediumTest</code>, and <code>@LargeTest</code>.
+ Runs a test method annotated by size. The annotations are <code>@SmallTest</code>,
+ <code>@MediumTest</code>, and <code>@LargeTest</code>.
</td>
</tr>
<tr>
@@ -589,8 +373,9 @@
<td><code>true</code></td>
<td>
Runs an EMMA code coverage analysis and writes the output to
- <code>/data//coverage.ec</code> on the device. To override the file location, use the
- <code>coverageFile</code> key that is described in the following entry.
+ <code>/data/<app_package>/coverage.ec</code> on the device. To override the
+ file location, use the <code>coverageFile</code> key that is described in the
+ following entry.
<p class="note">
<strong>Note:</strong> This option requires an EMMA-instrumented build of the test
application, which you can generate with the <code>coverage</code> target.
@@ -632,24 +417,16 @@
The test package has the Android package name <code>com.android.demo.app.tests</code>
</li>
<li>
- There are three test classes:
+ Two instrumented test classes:
<ul>
- <li>
- <code>UnitTests</code>, which contains the methods
- <code>testPermissions</code> and <code>testSaveState</code>.
- </li>
- <li>
- <code>FunctionTests</code>, which contains the methods
- <code>testCamera</code>, <code>testXVGA</code>, and <code>testHardKeyboard</code>.
- </li>
- <li>
- <code>IntegrationTests</code>,
- which contains the method <code>testActivityProvider</code>.
- </li>
+ <li>{@code Foo1} which contains the test method {@code bar1}, and</li>
+ <li>{@code Foo2} which contains test methods {@code bar2} and {@code bar3}</li>
</ul>
</li>
<li>
- The test runner is {@link android.test.InstrumentationTestRunner}.
+ The test runner is
+<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+{@code AndroidJUnitRunner}</a>.
</li>
</ul>
<h4>Running the entire test package</h4>
@@ -657,7 +434,7 @@
To run all of the test classes in the test package, enter:
</p>
<pre>
-$ adb shell am instrument -w com.android.demo.app.tests/android.test.InstrumentationTestRunner
+$ adb shell am instrument -w com.android.demo.app.tests/android.support.test.runner.AndroidJUnitRunner
</pre>
<h4>Running all tests in a test case class</h4>
<p>
@@ -665,8 +442,8 @@
</p>
<pre>
$ adb shell am instrument -w \
-> -e class com.android.demo.app.tests.UnitTests \
-> com.android.demo.app.tests/android.test.InstrumentationTestRunner
+> -e class com.android.demo.app.tests.Foo \
+> com.android.demo.app.tests/android.support.test.runner.AndroidJUnitRunner
</pre>
<p>
<code>am instrument</code> gets the value of the <code>-e</code> flag, detects the
@@ -674,15 +451,11 @@
</p>
<h4>Selecting a subset of tests</h4>
<p>
- To run all of the tests in <code>UnitTests</code>, and the <code>testCamera</code> method in
- <code>FunctionTests</code>, enter:
+ To run all of the tests in <code>Foo1</code>, and the <code>bar3</code> method in
+ <code>Foo2</code>, enter:
</p>
<pre>
$ adb shell am instrument -w \
-> -e class com.android.demo.app.tests.UnitTests,com.android.demo.app.tests.FunctionTests#testCamera \
-> com.android.demo.app.tests/android.test.InstrumentationTestRunner
+> -e class com.android.demo.app.tests.Foo1,com.android.demo.app.tests.Foo2#bar3 \
+> com.android.demo.app.tests/android.support.test.runner.AndroidJUnitRunner
</pre>
-<p>
- You can find more examples of the command in the documentation for
- {@link android.test.InstrumentationTestRunner}.
-</p>
diff --git a/docs/html/tools/testing/testing_ui.jd b/docs/html/tools/testing/testing_ui.jd
deleted file mode 100644
index 4318a21..0000000
--- a/docs/html/tools/testing/testing_ui.jd
+++ /dev/null
@@ -1,356 +0,0 @@
-page.title=UI Testing
-parent.title=Testing
-parent.link=index.html
-@jd:body
-
-<div id="qv-wrapper">
- <div id="qv">
- <h2>In this document</h2>
- <ol>
- <li><a href="#overview">Overview</a></li>
- <ul>
- <li><a href="#workflow">Workflow</a></li>
- </ul>
- <li><a href="#uianalysis">Analyzing Your UI</a></li>
- <li><a href="#prepare">Preparing to Test</a>
- <ul>
- <LI><a href="#loading">Load the App</a></LI>
- <LI><a href="#identifyUI">Identify UI Components</a></LI>
- <LI><a href="#accessibility">Ensure Accessibility</a></LI>
- <LI><a href="#configure">Configure Development Environment</a></LI>
- </ul>
- </li>
- <li><a href="#creating">Creating Tests</a>
- <ul>
- <LI><a href="#classes">uiautomator API</a></LI>
- <li><a href="#sample">Sample Test Case</a>
- </ul>
- </li>
- <li><a href="#builddeploy">Building and Deploying Tests</a></li>
- <li><a href="#running">Running Tests</a></li>
- <li><a href="#bestpractices">Best Practices</a></li>
- </ol>
- <h2>Key classes</h2>
- <ol>
- <li><a href="{@docRoot}tools/help/uiautomator/IAutomationSupport.html">IAutomationSupport</a></li>
- <li><a href="{@docRoot}tools/help/uiautomator/UiAutomatorTestCase.html">UiAutomatorTestCase</a></li>
- <li><a href="{@docRoot}tools/help/uiautomator/UiCollection.html">UiCollection</a></li>
- <li><a href="{@docRoot}tools/help/uiautomator/UiDevice.html">UiDevice</a></li>
- <li><a href="{@docRoot}tools/help/uiautomator/UiObject.html">UiObject</a></li>
- <li><a href="{@docRoot}tools/help/uiautomator/UiScrollable.html">UiScrollable</a></li>
- <li><a href="{@docRoot}tools/help/uiautomator/UiSelector.html">UiSelector</a></li>
- </ol>
- <h2>See Also</h2>
- <ol>
- <li>
- <a href="{@docRoot}tools/help/uiautomator/index.html">uiautomator (reference)</a>
- </li>
- </ol>
- </div>
-</div>
-
-<p>
-In addition to unit testing the individual components that make up your Android application (such as activities, services, and content providers), it is also important that you test the behavior of your application’s user interface (UI) when it is running on a device. UI testing ensures that your application returns the correct UI output in response to a sequence of user actions on a device, such as entering keyboard input or pressing toolbars, menus, dialogs, images, and other UI controls.
-</p>
-<p>
-Functional or black-box UI testing does not require testers to know the internal implementation details of the app, only its expected output when a user performs a specific action or enters a specific input. This approach allows for better separation of development and testing roles in your organization.
-</p>
-<p>One common approach to UI testing is to run tests manually and verify that the app is behaving as expected. However, this approach can be time-consuming, tedious, and error-prone. A more efficient and reliable approach is to automate the UI testing with a software testing framework. Automated testing involves creating programs to perform testing tasks (test cases) to cover specific usage scenarios, and then using the testing framework to run the test cases automatically and in a repeatable manner.</p>
-
-<h2 id="overview">Overview</h2>
-<p>The Android SDK provides the following tools to support automated, functional UI testing on your application:
-<ul>
-<LI>{@code uiautomatorviewer} - A GUI tool to scan and analyze the UI components of an Android application.</LI>
-<LI>{@code uiautomator} - A Java library containing APIs to create customized functional UI tests, and an execution engine to automate and run the tests.</LI>
-</ul></p>
-
-<p>To use these tools, you must have the following versions of the Android development tools installed:
-<ul>
-<LI>Android SDK Tools, Revision 21 or higher</LI>
-<LI>Android SDK Platform, API 16 or higher</LI>
-</ul>
-</p>
-
-<h3 id="workflow">Workflow for the the uiautomator testing framework</h3>
-<p>Here's a short overview of the steps required to automate UI testing:
-<ol>
-<LI>Prepare to test by installing the app on a test device, analyzing the app’s UI components, and ensuring that your application is accessible by the test automation framework.</LI>
-<li>Create automated tests to simulate specific user interactions on your application.</li>
-<li>Compile your test cases into a JAR file and install it on your test device along with your app.</li>
-<li>Run the tests and view the test results.</li>
-<li>Correct any bugs or defects discovered in testing.</li>
-</ol>
-</p>
-
-<h2 id="uianalysis">Analyzing Your Application's UI</h2>
-<p>Before you start writing your test cases, it's helpful to familiarize yourself with the UI components (including the views and controls) of the targeted application. You can use the {@code uiautomatorviewer} tool to take a snapshot of the foreground UI screen on any Android device that is connected to your development machine. The {@code uiautomatorviewer} tool provides a convenient visual interface to inspect the layout hierarchy and view the properties of the individual UI components that are displayed on the test device. Using this information, you can later create {@code uiautomator} tests with selector objects that target specific UI components to test.</p>
-
-<a href="{@docRoot}images/testing/UIAutomatorViewer.png">
- <img src="{@docRoot}images/testing/UIAutomatorViewer.png"
- alt="User interface of uiautomatorviewer tool" height="327px" id="figure1"/>
-</a>
-<p class="img-caption">
- <strong>Figure 1.</strong> The {@code uiautomatorviewer} showing the captured interface of a test device.
-</p>
-
-<p>To analyze the UI components of the application that you want to test:</p>
-<ol>
-<li>Connect your Android device to your development machine.</li>
-<li>Open a terminal window and navigate to {@code <android-sdk>/tools/}.</li>
-<LI>Run the tool with this command:<pre>$ uiautomatorviewer</pre></LI>
-<li><p>To capture a screen for analysis, click the <strong>Device Screenshot</strong> button in the GUI of the {@code uiautomatorviewer} tool.</p>
-<p class="note"><strong>Note: </strong>If you have more than one device connected, specify the device for screen capture by setting the {@code ANDROID_SERIAL} environment variable:
- <ol type="a">
- <li>Find the serial numbers for your connected devices by running this command:<pre>$ adb devices</pre> </li>
- <li>Set the {@code ANDROID_SERIAL} environment variable to select the device to test:
- <ul>
- <li>In Windows: <pre>set ANDROID_SERIAL=<device serial number></pre></li>
- <li>In UNIX: <pre>export ANDROID_SERIAL=<device serial number></pre></li>
- </ul>
- </li>
- </ol>
-If you are connected to only a single device, you do not need to set the ANDROID_SERIAL environment variable.</p>
-</li>
-<li>View the UI properties for your application:
- <ul>
- <LI>Hover over the snapshot in the left-hand panel to see the UI components identified by the {@code uiautomatorviewer} tool. You can view the component’s properties listed in the lower right-hand panel, and the layout hierarchy in the upper right-hand panel.</LI>
- <li>Optionally, click on the <strong>Toggle NAF Nodes</strong> button to see UI components that are not accessible to the {@code uiautomator} testing framework. Only limited information may be available for these components.</li>
- </ul>
-</li>
-</ol>
-
-<h2 id="prepare">Preparing to Test</h2>
-<p>Before using the {@code uiautomator} testing framework, complete these pre-flight tasks:
-</p>
-<h3 id="loading">Load the application to a device</h3>
-<p>If you are reading this document, chances are that the Android application that you want to test has not been published yet. If you have a copy of the APK file, you can install the APK onto a test device by using the {@code adb} tool. To learn how to install an APK file using the {@code adb} tool, see the <a href="{@docRoot}tools/help/adb.html#move">{@code adb}</a> documentation. </p>
-
-<h3 id="identifyUI">Identify the application’s UI components</h3>
-<p>Before writing your {@code uiautomator} tests, first identify the UI components in the application that you want to test. Typically, good candidates for testing are UI components that are visible and that users can interact with. The UI components should also have visible text labels, <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">{@code android:contentDescription}</a> values, or both.
-
-<p>You can inspect the visible screen objects in an application conveniently by using the {@code uiautomatorviewer} tool. For more information about how to analyze an application screen with this tool, see the section <a href="#uianalaysis">Analyzing Your Application’s UI</a>. For more information about the common types of UI components provided by Android, see <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a>.</p>
-
-<h3 id="accessibility">Ensure that the application is accessible</h3>
-<p>This step is required because the {@code uiautomator} tool depends on the accessibility features of the Android framework to execute your functional UI tests. You should include these minimum optimizations to support the {@code uiautomator} tool:
-<ul>
-<LI>Use the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">{@code android:contentDescription}</a> attribute to label the {@link android.widget.ImageButton}, {@link android.widget.ImageView}, {@link android.widget.CheckBox} and other user interface controls.</LI>
-<li>Provide an <a href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">{@code android:hint}</a> attribute <em>instead</em> of a content description for {@link android.widget.EditText} fields</li>
-<li>Associate an <a href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">{@code android:hint}</a> attribute with any graphical icons used by controls that provide feedback to the user (for example, status or state information).</li>
-<li>Make sure that all the user interface elements are accessible with a directional controller, such as a trackball or D-pad.</li>
-<li>Use the {@code uiautomatorviewer} tool to ensure that the UI component is accessible to the testing framework. You can also test the application by turning on accessibility services like TalkBack and Explore by Touch, and try using your application using only directional controls. </li>
-</ul>
-</p>
-
-<p>For more information about implementing and testing accessibility, see <a href="{@docRoot}guide/topics/ui/accessibility/apps.html">Making Applications Accessible</a>.</p>
-
-<p class="note"><strong>Note: </strong>To identify the non-accessible components in the UI, click on the <strong>Toggle NAF Nodes</strong> option in the {@code uiautomatorviewer} tool.</p>
-
-<p>Generally, Android application developers get accessibility support for free, courtesy of the {@link android.view.View} and {@link android.view.ViewGroup} classes. However, some applications use custom view components to provide a richer user experience. Such custom components won't get the accessibility support that is provided by the standard Android UI components. If this applies to your application, ensure that the application developer exposes the custom drawn UI components to Android accessibility services, by implementing the {@link android.view.accessibility.AccessibilityNodeProvider} class. For more information about making custom view components accessible, see <a href="{@docRoot}guide/topics/ui/accessibility/apps.html#custom-views">Making Applications Accessible</a>.</p>
-
-<h3 id="configure">Configure your development environment</h3>
-<p>If you're developing in Eclipse, the Android SDK provides additional tools that help you write test cases using {@code uiautomator} and buiild your JAR file. In order to set up Eclipse to assist you, you need to create a project that includes the {@code uiautomator} client library, along with the Android SDK library. To configure Eclipse:</p>
-<ol>
-<li>Create a new Java project in Eclipse, and give your project a name that is relevant to the tests you’re about to create (for example, "MyAppNameTests"). In the project, you will create the test cases that are specific to the application that you want to test.</li>
-<li>From the <strong>Project Explorer</strong>, right-click on the new project that you created, then select <strong>Properties > Java Build Path</strong>, and do the following:
- <ol type="a">
- <LI>Click <strong>Add Library > JUnit</strong> then select <strong>JUnit3</strong> to add JUnit support.</LI>
- <li>Click <strong>Add External JARs...</strong> and navigate to the SDK directory. Under the platforms directory, select the latest SDK version and add both the {@code uiautomator.jar} and {@code android.jar} files.</li>
- </ol>
-</li>
-</ol>
-<p>If you did not configure Eclipse as your development environment, make sure that the {@code uiautomator.jar} and {@code android.jar} files from the {@code <android-sdk>/platforms/<sdk>} directory are in your Java class path.</p>
-<p>Once you have completed these prerequisite tasks, you're almost ready to start creating your {@code uiautomator} tests. </li>
-
-<h2 id="creating">Creating uiautomator Tests</h2>
-<p>To build a test that runs in the {@code uiautomator} framework, create a test case that extends the <a href="{@docRoot}tools/help/uiautomator/UiAutomatorTestCase.html">{@code UiAutomatorTestCase}</a> class. In Eclipse, the test case file goes under the {@code src} directory in your project. Later, you will build the test case as a JAR file, then copy this file to the test device. The test JAR file is not an APK file and resides separately from the application that you want to test on the device.</p>
-
-<p>Because the <a href="{@docRoot}tools/help/uiautomator/UiAutomatorTestCase.html">{@code UiAutomatorTestCase}</a> class extends {@code junit.framework.TestCase}, you can use the JUnit {@code Assert} class to test that UI components in the app return the expected results. To learn more about JUnit, you can read the documentation on the <a href="http://www.junit.org/">junit.org</a> home page.</p>
-
-<p>The first thing your test case should do is access the device that contains the target app. It’s also good practice to start the test from the Home screen of the device. From the Home screen (or some other starting location you’ve chosen in the target app), you can use the classes provided by the {@code uiautomator} API to simulate user actions and to test specific UI components. For an example of how to put together a {@code uiautomator} test case, see the <a href="#sample">sample test case</a>.</p>
-
-<h3 id="classes">uiautomator API</h3>
-<p>The {@code uiautomator} API is bundled in the {@code uiautomator.jar} file under the {@code <android-sdk>/platforms/} directory. The API includes these key classes that allow you to capture and manipulate UI components on the target app:</p>
-<dl>
-<DT><a href="{@docRoot}tools/help/uiautomator/UiDevice.html">{@code UiDevice}</a></DT>
-<dd><p>Represents the device state. In your tests, you can call methods on the <a href="{@docRoot}tools/help/uiautomator/UiDevice.html">{@code UiDevice}</a> instance to check for the state of various properties, such as current orientation or display size. Your tests also can use the <a href="{@docRoot}tools/help/uiautomator/UiDevice.html">{@code UiDevice}</a> instance to perform device level actions, such as forcing the device into a specific rotation, pressing the d-pad hardware button, or pressing the Home and Menu buttons.</p>
-<p>To get an instance of <a href="{@docRoot}tools/help/uiautomator/UiDevice.html">{@code UiDevice}</a> and simulate a Home button press:
-<pre>
-getUiDevice().pressHome();
-</pre></p></dd>
-
-<dt><a href="{@docRoot}tools/help/uiautomator/UiSelector.html">{@code UiSelector}</a></dt>
-<dd>Represents a search criteria to query and get a handle on specific elements in the currently displayed UI.
-If more than one matching element is found, the first matching element in the layout hierarchy is returned as the target {@code UiObject}. When constructing a <a href="{@docRoot}tools/help/uiautomator/UiSelector.html">{@code UiSelector}</a>, you can chain together multiple properties to refine your search. If no matching UI element is found, a <a href="{@docRoot}tools/help/uiautomator/UiAutomatorObjectNotFoundException.html">{@code UiAutomatorObjectNotFoundException}</a> is thrown. You can use the <a href="{@docRoot}tools/help/uiautomator/UiSelector.html#childSelector(com.android.uiautomator.core.UiSelector)">{@code childSelector()}</a> method to nest multiple <a href="{@docRoot}tools/help/uiautomator/UiSelector.html">{@code UiSelector}</a> instances. For example, the following code example shows how to specify a search to find the first {@link android.widget.ListView} in the currently displayed UI, then search within that {@link android.widget.ListView} to find a UI element with the text property {@code Apps}.
-<pre>
-UiObject appItem = new UiObject(new UiSelector()
- .className("android.widget.ListView").instance(1)
- .childSelector(new UiSelector().text("Apps")));
-</pre>
-</dd>
-
-<dt><a href="{@docRoot}tools/help/uiautomator/UiObject.html">{@code UiObject}</a></dt>
-<dd>Represents a UI element. To create a <a href="{@docRoot}tools/help/uiautomator/UiObject.html">{@code UiObject}</a> instance, use a {@code UiSelector} that describes how to search for, or select, the UI element.
-<p>The following code example shows how to construct <a href="{@docRoot}tools/help/uiautomator/UiObject.html">{@code UiObject}</a> instances that represent a <strong>Cancel</strong> button and a <strong>OK</strong> button in your application.</p>
-<pre>
-UiObject cancelButton = new UiObject(new UiSelector().text("Cancel"));
-UiObject okButton = new UiObject(new UiSelector().text("OK"));
-</pre>
-<p>You can reuse the <a href="{@docRoot}tools/help/uiautomator/UiObject.html">{@code UiObject}</a> instances that you have created in other parts of your app testing, as needed. Note that the {@code uiautomator} test framework searches the current display for a match every time your test uses a <a href="{@docRoot}tools/help/uiautomator/UiObject.html">{@code UiObject}</a> instance to click on a UI element or query a property.</p>
-<p>In the following code example, the {@code uiautomator} test framework searches for a UI element with the text property {@code OK}. If a match is found and if the element is enabled, the framework simulates a user click action on the element.</p>
-<pre>
-if(okButton.exists() && okButton.isEnabled())
-{
- okButton.click();
-}
-</pre>
-<p>You can also restrict the search to find only elements of a specific class. For example, to find matches of the {@link android.widget.Button} class:</p>
-<pre>
-UiObject cancelButton = new UiObject(new UiSelector().text("Cancel")
- .className("android.widget.Button"));
-UiObject okButton = new UiObject(new UiSelector().text("OK")
- .className("android.widget.Button"));
-</pre>
-</dd>
-
-<dt><a href="{@docRoot}tools/help/uiautomator/UiCollection.html">{@code UiCollection}</a></dt>
-<dd>Represents a collection of items, for example songs in a music album or a list of emails in an inbox. Similar to a <a href="{@docRoot}tools/help/uiautomator/UiObject.html">{@code UiObject}</a>, you construct a <a href="{@docRoot}tools/help/uiautomator/UiCollection.html">{@code UiCollection}</a> instance by specifying a <a href="{@docRoot}tools/help/uiautomator/UiSelector.html">{@code UiSelector}</a>. The <a href="{@docRoot}tools/help/uiautomator/UiSelector.html">{@code UiSelector}</a> for a <a href="{@docRoot}tools/help/uiautomator/UiCollection.html">{@code UiCollection}</a> should search for a UI element that is a container or wrapper of other child UI elements (such as a layout view that contains child UI elements). For example, the following code snippet shows how to construct a <a href="{@docRoot}tools/help/uiautomator/UiCollection.html">{@code UiCollection}</a> to represent a video album that is displayed within a {@link android.widget.FrameLayout}:
-<pre>
-UiCollection videos = new UiCollection(new UiSelector()
- .className("android.widget.FrameLayout"));
-</pre>
-<p>If the videos are listed within a {@link android.widget.LinearLayout} view, and you want to to retrieve the number of videos in this collection:</p>
-<pre>
-int count = videos.getChildCount(new UiSelector()
- .className("android.widget.LinearLayout"));
-</pre>
-<p>If you want to find a specific video that is labeled with the text element {@code Cute Baby Laughing} from the collection and simulate a user-click on the video:</p>
-<pre>
-UiObject video = videos.getChildByText(new UiSelector()
- .className("android.widget.LinearLayout"), "Cute Baby Laughing");
-video.click();
-</pre>
-<p>Similarly, you can simulate other user actions on the UI object. For example, if you want
-to simulate selecting a checkbox that is associated with the video:</p>
-<pre>
-UiObject checkBox = video.getChild(new UiSelector()
- .className("android.widget.Checkbox"));
-if(!checkBox.isSelected()) checkbox.click();
-</pre>
-</dd>
-
-<dt><a href="{@docRoot}tools/help/uiautomator/UiScrollable.html">{@code UiScrollable}</a></dt>
-<dd>Represents a scrollable collection of UI elements. You can use the <a href="{@docRoot}tools/help/uiautomator/UiScrollable.html">{@code UiScrollable}</a> class to simulate vertical or horizontal scrolling across a display. This technique is helpful when a UI element is positioned off-screen and you need to scroll to bring it into view.
-<p>For example, the following code shows how to simulate scrolling down the Settings menu and clicking on an <strong>About tablet</strong> option:</p>
-<pre>
-UiScrollable settingsItem = new UiScrollable(new UiSelector()
- .className("android.widget.ListView"));
-UiObject about = settingsItem.getChildByText(new UiSelector()
- .className("android.widget.LinearLayout"), "About tablet");
-about.click()
-</pre>
-</dd>
-</dl>
-<p>For more information about these APIs, see the <a href="{@docRoot}tools/help/uiautomator/index.html">{@code uiautomator}</a> reference.</p>
-
-<h3 id="sample">A sample uiautomator test case</h3>
-<p>The following code example shows a simple test case which simulates a user bringing up the Settings app in a stock Android device. The test case mimics all the steps that a user would typically take to perform this task, including opening the Home screen, launching the <strong>All Apps</strong> screen, scrolling to the <strong>Settings</strong> app icon, and clicking on the icon to enter the Settings app.</p>
-<pre>
-package com.uia.example.my;
-
-// Import the uiautomator libraries
-import com.android.uiautomator.core.UiObject;
-import com.android.uiautomator.core.UiObjectNotFoundException;
-import com.android.uiautomator.core.UiScrollable;
-import com.android.uiautomator.core.UiSelector;
-import com.android.uiautomator.testrunner.UiAutomatorTestCase;
-
-public class LaunchSettings extends UiAutomatorTestCase {
-
- public void testDemo() throws UiObjectNotFoundException {
-
- // Simulate a short press on the HOME button.
- getUiDevice().pressHome();
-
- // We’re now in the home screen. Next, we want to simulate
- // a user bringing up the All Apps screen.
- // If you use the uiautomatorviewer tool to capture a snapshot
- // of the Home screen, notice that the All Apps button’s
- // content-description property has the value “Apps”. We can
- // use this property to create a UiSelector to find the button.
- UiObject allAppsButton = new UiObject(new UiSelector()
- .description("Apps"));
-
- // Simulate a click to bring up the All Apps screen.
- allAppsButton.clickAndWaitForNewWindow();
-
- // In the All Apps screen, the Settings app is located in
- // the Apps tab. To simulate the user bringing up the Apps tab,
- // we create a UiSelector to find a tab with the text
- // label “Apps”.
- UiObject appsTab = new UiObject(new UiSelector()
- .text("Apps"));
-
- // Simulate a click to enter the Apps tab.
- appsTab.click();
-
- // Next, in the apps tabs, we can simulate a user swiping until
- // they come to the Settings app icon. Since the container view
- // is scrollable, we can use a UiScrollable object.
- UiScrollable appViews = new UiScrollable(new UiSelector()
- .scrollable(true));
-
- // Set the swiping mode to horizontal (the default is vertical)
- appViews.setAsHorizontalList();
-
- // Create a UiSelector to find the Settings app and simulate
- // a user click to launch the app.
- UiObject settingsApp = appViews.getChildByText(new UiSelector()
- .className(android.widget.TextView.class.getName()),
- "Settings");
- settingsApp.clickAndWaitForNewWindow();
-
- // Validate that the package name is the expected one
- UiObject settingsValidation = new UiObject(new UiSelector()
- .packageName("com.android.settings"));
- assertTrue("Unable to detect Settings",
- settingsValidation.exists());
- }
-}
-</pre>
-
-<h2 id="builddeploy">Building and Deploying Your uiautomator Tests</h2>
-<p>Once you have coded your test, follow these steps to build and deploy your test JAR to your target Android test device:</p>
-<ol>
-<li>Create the required build configuration files to build the output JAR. To generate the build configuration files, open a terminal and run the following command:
-<pre><android-sdk>/tools/android create uitest-project -n <name> -t 1 -p <path></pre>
-The {@code <name>} is the name of the project that contains your {@code uiautomator} test source files, and the {@code <path>} is the path to the corresponding project directory.
-</li>
-<LI>From the command line, set the {@code ANDROID_HOME} variable:
-<ul>
-<li>In Windows:
-<pre>set ANDROID_HOME=<path_to_your_sdk></pre>
-</li>
-<li>In UNIX:
-<pre>export ANDROID_HOME=<path_to_your_sdk></pre>
-</li>
-</ul>
-</LI>
-<li>Go to the project directory where your {@code build.xml} file is located and build your test JAR. <pre>ant build</pre></li>
-<li>Deploy your generated test JAR file to the test device by using the {@code adb push} command: <pre>adb push <path_to_output_jar> /data/local/tmp/</pre>
-<p>Here’s an example: <pre>adb push ~/dev/workspace/LaunchSettings/bin/LaunchSettings.jar /data/local/tmp/</pre></p>
-</li>
-</ol>
-
-<h2 id="running">Running uiautomator Tests</h2>
-<p>Here’s an example of how to run a test that is implemented in the {@code LaunchSettings.jar} file. The tests are bundled in the {@code com.uia.example.my} package:</p>
-<pre>adb shell uiautomator runtest LaunchSettings.jar -c com.uia.example.my.LaunchSettings</pre>
-<p>To learn more about the syntax, subcommands, and options for {@code uiautomator}, see the <a href="{@docRoot}tools/help/uiautomator/index.html">{@code uiautomator}</a> reference.</p>
-
-
-<h2 id="bestpractices">Best Practices</h2>
-<p>Here are some best practices for functional UI testing with the {@code uiautomator} framework: </p>
-<ul>
-<LI>Ensure that you validate the same UI functions on your application across the various types of devices that your application might run on (for example, devices with different screen densities).</LI>
-<li>You should also test your UI against common scenarios such as in-coming phone calls, network interruptions, and user-initiated switching to other applications on the device.</li>
-</ul>
-
diff --git a/docs/html/tools/testing/what_to_test.jd b/docs/html/tools/testing/what_to_test.jd
deleted file mode 100644
index 77ae211..0000000
--- a/docs/html/tools/testing/what_to_test.jd
+++ /dev/null
@@ -1,86 +0,0 @@
-page.title=What To Test
-parent.title=Testing
-parent.link=index.html
-@jd:body
-<p>
- As you develop Android applications, knowing what to test is as important as knowing how to
- test. This document lists some most common Android-related situations that you should consider
- when you test, even at the unit test level. This is not an exhaustive list, and you consult the
- documentation for the features that you use for more ideas. The
- <a href="http://groups.google.com/group/android-developers">android-developers</a> Google Groups
- site is another resource for information about testing.
-</p>
-<h2 id="Tests">Ideas for Testing</h2>
-<p>
- The following sections are organized by behaviors or situations that you should test. Each
- section contains a scenario that further illustrates the situation and the test or tests you
- should do.
-</p>
-<h4>Change in orientation</h4>
-<p>
- For devices that support multiple orientations, Android detects a change in orientation when
- the user turns the device so that the display is "landscape" (long edge is horizontal) instead
- of "portrait" (long edge is vertical).
-</p>
-<p>
- When Android detects a change in orientation, its default behavior is to destroy and then
- re-start the foreground Activity. You should consider testing the following:
-</p>
-<ul>
- <li>
- Is the screen re-drawn correctly? Any custom UI code you have should handle changes in the
- orientation.
- </li>
- <li>
- Does the application maintain its state? The Activity should not lose anything that the
- user has already entered into the UI. The application should not "forget" its place in the
- current transaction.
- </li>
-</ul>
-<h4>Change in configuration</h4>
-<p>
- A situation that is more general than a change in orientation is a change in the device's
- configuration, such as a change in the availability of a keyboard or a change in system
- language.
-</p>
-<p>
- A change in configuration also triggers the default behavior of destroying and then restarting
- the foreground Activity. Besides testing that the application maintains the UI and its
- transaction state, you should also test that the application updates itself to respond
- correctly to the new configuration.
-</p>
-<h4>Battery life</h4>
-<p>
- Mobile devices primarily run on battery power. A device has finite "battery budget", and when it
- is gone, the device is useless until it is recharged. You need to write your application to
- minimize battery usage, you need to test its battery performance, and you need to test the
- methods that manage battery usage.
-</p>
-<p>
- Techniques for minimizing battery usage were presented at the 2010 Google I/O conference in the
- presentation
- <a href="http://code.google.com/events/io/2009/sessions/CodingLifeBatteryLife.html">
- Coding for Life -- Battery Life, That Is</a>. This presentation describes the impact on battery
- life of various operations, and the ways you can design your application to minimize these
- impacts. When you code your application to reduce battery usage, you also write the
- appropriate unit tests.
-</p>
-<h4>Dependence on external resources</h4>
-<p>
- If your application depends on network access, SMS, Bluetooth, or GPS, then you should
- test what happens when the resource or resources are not available.
-</p>
-<p>
- For example, if your application uses the network,it can notify the user if access is
- unavailable, or disable network-related features, or do both. For GPS, it can switch to
- IP-based location awareness. It can also wait for WiFi access before doing large data transfers,
- since WiFi transfers maximize battery usage compared to transfers over 3G or EDGE.
-</p>
-<p>
- You can use the emulator to test network access and bandwidth. To learn more, please see
- <a href="{@docRoot}tools/help/emulator.html#netspeed">Network Speed Emulation</a>.
- To test GPS, you can use the emulator console and {@link android.location.LocationManager}. To
- learn more about the emulator console, please see
- <a href="{@docRoot}tools/help/emulator.html#console">
- Using the Emulator Console</a>.
-</p>
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index f41184e..04ed705 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -83,56 +83,11 @@
<li><a href="<?cs var:toroot ?>tools/building/building-studio.html">
<span class="en">From Android Studio</span></a></li>
<li><a href="<?cs var:toroot ?>tools/building/building-cmdline.html">
- <span class="en">From the Command Line</span></a></li>
+ <span class="en">From the Command-Line</span></a></li>
</ul>
</li>
-
- <li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot?>tools/testing/index.html">
- <span class="en">Testing</span>
- </a></div>
- <ul>
- <li>
- <a href="<?cs var:toroot?>tools/testing/testing_android.html">
- <span class="en">Fundamentals</span></a>
- </li>
- <li><a href="<?cs var:toroot ?>tools/testing/testing_eclipse.html">
- <span class="en">From Eclipse</span></a>
- </li>
- <li><a href="<?cs var:toroot ?>tools/testing/testing_otheride.html">
- <span class="en">From Other IDEs</span></a>
- </li>
- <li>
- <a href="<?cs var:toroot?>tools/testing/activity_testing.html">
- <span class="en">Activity Testing</span></a>
- </li>
- <li>
- <a href="<?cs var:toroot?>tools/testing/service_testing.html">
- <span class="en">Service Testing</span></a>
- </li>
- <li>
- <a href="<?cs var:toroot?>tools/testing/contentprovider_testing.html">
- <span class="en">Content Provider Testing</span></a>
- </li>
- <li>
- <a href="<?cs var:toroot?>tools/testing/testing_accessibility.html">
- <span class="en">Accessibility Testing</span></a>
- </li>
- <li>
- <a href="<?cs var:toroot?>tools/testing/testing_ui.html">
- <span class="en">UI Testing</span></a>
- </li>
- <li>
- <a href="<?cs var:toroot ?>tools/testing/what_to_test.html">
- <span class="en">What To Test</span></a>
- </li>
- <li>
- <a href="<?cs var:toroot ?>tools/testing/activity_test.html">
- <span class="en">Activity Testing Tutorial</span></a>
- </li>
- </ul>
- </li><!-- end of testing -->
+ <li><a href="<?cs var:toroot?>tools/testing/index.html"><span class="en">Testing</span></a></li>
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot ?>tools/debugging/index.html"><span class="en">Debugging</span></a></div>
@@ -307,15 +262,23 @@
<!-- Testing Tools menu-->
<li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/testing/testing-tools.html"><span class="en">Testing Tools</span></a></div>
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/testing/testing-tools.html">
+ <span class="en">Testing Tools</span></a></div>
<ul>
+ <li><a href="<?cs var:toroot ?>tools/testing/testing_android.html">Testing Concepts</a></li>
<li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/testing-support-library/index.html"><span
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>tools/testing-support-library/index.html"><span
class="en">Testing Support Library</span></a></div>
<ul>
- <li><a href="<?cs var:toroot ?>reference/android/support/test/package-summary.html">API Reference</a></li>
+ <li><a href="<?cs var:toroot ?>reference/android/support/test/package-summary.html">
+ API Reference</a></li>
</ul>
</li>
+ <li><a href="<?cs var:toroot ?>training/testing/start/index.html">
+ Testing with Android Studio</a></li>
+ <li><a href="<?cs var:toroot ?>tools/testing/testing_otheride.html">
+ Testing from the Command-Line</a></li>
<li><a href="<?cs var:toroot ?>tools/help/monkey.html">monkey</a></li>
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot
diff --git a/docs/html/training/accessibility/index.jd b/docs/html/training/accessibility/index.jd
index ea54dc4..7a5d6d7 100644
--- a/docs/html/training/accessibility/index.jd
+++ b/docs/html/training/accessibility/index.jd
@@ -50,5 +50,7 @@
and uses that information to communicate with the user. The example will
use a text-to-speech engine to speak to the user.</dd>
+ <dt><b><a href="testing.html">Accessibility Checklist</a></b></dt>
+ <dd>Learn how to test your app for accessibility.</dd>
</dl>
diff --git a/docs/html/tools/testing/testing_accessibility.jd b/docs/html/training/accessibility/testing.jd
similarity index 97%
rename from docs/html/tools/testing/testing_accessibility.jd
rename to docs/html/training/accessibility/testing.jd
index 20948fa..6563f4e 100644
--- a/docs/html/tools/testing/testing_accessibility.jd
+++ b/docs/html/training/accessibility/testing.jd
@@ -1,11 +1,13 @@
page.title=Accessibility Testing Checklist
-parent.title=Testing
-parent.link=index.html
+page.tags=testing,accessibility
+
+trainingnavtop=true
+startpage=true
@jd:body
-<div id="qv-wrapper">
- <div id="qv">
- <h2>In this document</h2>
+<div id="tb-wrapper">
+ <div id="tb">
+ <h2>Checklist sections</h2>
<ol>
<li><a href="#goals">Testing Goals</a></li>
<li><a href="#requirements">Testing Requirements</a></li>
@@ -20,7 +22,7 @@
</li>
</ol>
- <h2>See Also</h2>
+ <h2>You should also read</h2>
<ol>
<li>
<a href="{@docRoot}guide/topics/ui/accessibility/checklist.html">
diff --git a/docs/html/training/activity-testing/activity-basic-testing.jd b/docs/html/training/activity-testing/activity-basic-testing.jd
deleted file mode 100644
index 016289d..0000000
--- a/docs/html/training/activity-testing/activity-basic-testing.jd
+++ /dev/null
@@ -1,227 +0,0 @@
-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>
-
-
-
diff --git a/docs/html/training/activity-testing/activity-functional-testing.jd b/docs/html/training/activity-testing/activity-functional-testing.jd
deleted file mode 100644
index 7c8ff1d..0000000
--- a/docs/html/training/activity-testing/activity-functional-testing.jd
+++ /dev/null
@@ -1,166 +0,0 @@
-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>
-
-
-
-
-
-
-
-
diff --git a/docs/html/training/activity-testing/activity-ui-testing.jd b/docs/html/training/activity-testing/activity-ui-testing.jd
deleted file mode 100644
index 644f3ca..0000000
--- a/docs/html/training/activity-testing/activity-ui-testing.jd
+++ /dev/null
@@ -1,216 +0,0 @@
-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>
-
-
-
-
diff --git a/docs/html/training/activity-testing/activity-unit-testing.jd b/docs/html/training/activity-testing/activity-unit-testing.jd
deleted file mode 100644
index 74dcda9..0000000
--- a/docs/html/training/activity-testing/activity-unit-testing.jd
+++ /dev/null
@@ -1,134 +0,0 @@
-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>
-
-
-
-
-
-
-
diff --git a/docs/html/training/activity-testing/index.jd b/docs/html/training/activity-testing/index.jd
deleted file mode 100644
index efa67a2..0000000
--- a/docs/html/training/activity-testing/index.jd
+++ /dev/null
@@ -1,68 +0,0 @@
-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 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>
-
diff --git a/docs/html/training/activity-testing/preparing-activity-testing.jd b/docs/html/training/activity-testing/preparing-activity-testing.jd
deleted file mode 100644
index c43c9ed..0000000
--- a/docs/html/training/activity-testing/preparing-activity-testing.jd
+++ /dev/null
@@ -1,95 +0,0 @@
-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>
-
diff --git a/docs/html/training/articles/user-data-ids.jd b/docs/html/training/articles/user-data-ids.jd
new file mode 100644
index 0000000..5a4648b
--- /dev/null
+++ b/docs/html/training/articles/user-data-ids.jd
@@ -0,0 +1,741 @@
+page.title=Best Practices for Unique Identifiers
+page.metaDescription=How to manage unique identifiers the right way for users.
+page.tags=ids, user data
+meta.tags="ids", "user data"
+page.image=images/cards/card-user-ids_2x.png
+
+page.article=true
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#tenets_of_working_with_android_identifiers">Tenets of Working with
+ Android Identifiers</a></li>
+ <li><a href="#version_specific_details_identifiers_in_m">Identifiers in Android 6.0+</a></li>
+ <li><a href="#working_with_advertising_ids">Working with Advertising IDs</a></li>
+ <li><a href="#working_with_instance_ids_&_guids">Working with Instance IDs and GUIDs</a></li>
+ <li><a href="#understand_identifier_characteristics">Understanding Identifier
+ Characteristics</a>
+ <ol>
+ <li><a href="#scope">Scope</a></li>
+ <li><a href="#resettability_&_persistence">Resettability & persistence</a></li>
+ <li><a href="#uniqueness">Uniqueness</h3>
+ <li><a href="#integrity_protection_and_non-repudiability">Integrity protection and
+ non-repudiability</a></li>
+ </ol>
+ </li>
+ <li><a href="#use_appropriate_identifiers">Common Use Cases and the Identifier to Use</a>
+ <ol>
+ <li><a href="#a_track_signed-out_user_preferences">Tracking signed-out user
+ preferences</a></li>
+ <li><a href="#b_track_signed-out_user_behavior">Tracking signed-out user behavior</a></li>
+ <li><a href="#c_generate_signed-out_anonymous_user_analytics">Generating
+ signed-out/anonymous user analytics</a></li>
+ <li><a href="#d_track_signed-out_user_conversion">Tracking signed-out user
+ conversion</a></li>
+ <li><a href="#e_handle_multiple_installations">Handling multiple installations</a></li>
+ <li><a href="#f_anti-fraud_enforcing_free_content_limits_detecting_sybil_attacks">Anti-fraud:
+ Enforcing free content limits / detecting Sybil attacks</a></li>
+ <li><a href="#g_manage_telephony_&_carrier_functionality">Managing telephony and carrier
+ functionality</a></li>
+ <li><a href="#h_abuse_detection_identifying_bots_and_ddos_attacks">Abuse detection:
+ Identifying bots and DDoS attacks</a></li>
+ <li><a href="#i_abuse_detection_detecting_high_value_stolen_credentials">Abuse detection:
+ Detecting high value stolen credentials</a></li>
+ </ol>
+ </li>
+ </ol>
+ </div>
+</div>
+
+<p>
+ While there are valid reasons why your application may need to identify a
+ device rather than an instance of the application or an authenticated user on
+ the device, for the vast majority of applications, the ultimate goal is to
+ identify a particular <em>installation</em> of your app (not the actual
+ physical device).
+</p>
+
+<p>
+ Fortunately, identifying an installation on Android is straightforward using
+ an Instance ID or by creating your own GUID at install time. This document
+ provides guidance for selecting appropriate identifiers for your application,
+ based on your use-case.
+</p>
+
+<p>
+ For a general look at Android permissions, please see <a href=
+ "{@docRoot}training/articles/user-data-overview.html">Permissions
+ and User Data</a>. For specific best practices for
+ working with Android permissions, please see <a href=
+ "{@docRoot}training/articles/user-data-permissions.html">Best Practices for
+ App Permissions</a>.
+</p>
+
+
+<h2 id="tenets_of_working_with_android_identifiers">Tenets of Working with Android Identifiers</h2>
+
+<p>
+ We recommend that you follow these tenets when working with Android
+ identifiers:
+</p>
+
+<p>
+ <em><strong>#1: Avoid using hardware identifiers.</strong></em> Hardware
+ identifiers such as SSAID (Android ID) and IMEI can be avoided in most
+ use-cases without limiting required functionality.
+</p>
+
+<p>
+ <em><strong>#2: Only use Advertising ID for user profiling or ads
+ use-cases.</strong></em> When using an <a href=
+ "https://support.google.com/googleplay/android-developer/answer/6048248?hl=en">
+ Advertising ID</a>, always respect the <a href=
+ "https://play.google.com/about/developer-content-policy.html#ADID">Limit Ad
+ Tracking</a> flag, ensure the identifier cannot be connected to personally
+ identifiable information (PII) and avoid bridging Advertising ID resets.
+</p>
+
+<p>
+ <em><strong>#3: Use an Instance ID or a privately stored GUID whenever
+ possible for all other use-cases except payment fraud prevention and
+ telephony.</strong></em> For the vast majority of non-ads use-cases, an
+ instance ID or GUID should be sufficient.
+</p>
+
+<p>
+ <em><strong>#4: Use APIs that are appropriate to your use-case to minimize
+ privacy risk.</strong></em> Use the
+ <a href="http://source.android.com/devices/drm.html">DRM
+ API</a> API for high value content
+ protection and the <a href="{@docRoot}training/safetynet/index.html">SafetyNet
+ API</a> for abuse prevention. The Safetynet API is
+ the easiest way to determine whether a device is genuine without incurring
+ privacy risk.
+</p>
+
+<p>
+ The remaining sections of this guide elaborate on these rules in the context
+ of developing Android applications.
+</p>
+
+<h2 id="version_specific_details_identifiers_in_m">Identifiers in Android 6.0+</h2>
+
+<p>
+ MAC addresses are globally unique, not user-resettable and survive factory
+ reset. It is generally not recommended to use MAC address for any form of
+ user identification. As a result, as of Android M, local device MAC addresses
+ (for example, Wifi and Bluetooth) <em><strong>are not available via third party
+ APIs</strong></em>. The {@link android.net.wifi.WifiInfo#getMacAddress WifiInfo.getMacAddress()}
+ method and the {@link android.bluetooth.BluetoothAdapter#getAddress
+ BluetoothAdapter.getDefaultAdapter().getAddress()} method will
+ both return <code>02:00:00:00:00:00</code>..
+</p>
+
+<p>
+ Additionally, you must hold the following permissions to access MAC addresses
+ of nearby external devices available via Bluetooth and Wifi scans:
+</p>
+
+<table>
+ <tr>
+ <th><strong>Method/Property</strong></td>
+ <th><strong>Permissions Required</strong></td>
+ </tr>
+ <tr>
+ <td>
+ <code><a href="{@docRoot}reference/android/net/wifi/WifiManager.html#getScanResults()">WifiManager.getScanResults()</a></code>
+ </td>
+ <td>
+ <code>ACCESS_FINE_LOCATION</code> or <code>ACCESS_COARSE_LOCATION</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><a href="{@docRoot}reference/android/bluetooth/BluetoothDevice.html#ACTION_FOUND">BluetoothDevice.ACTION_FOUND</a></code>
+ </td>
+ <td>
+ <code>ACCESS_FINE_LOCATION</code> or <code>ACCESS_COARSE_LOCATION</code>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><a href="{@docRoot}reference/android/bluetooth/le/BluetoothLeScanner.html#startScan(android.bluetooth.le.ScanCallback)">BluetoothLeScanner.startScan(ScanCallback)</a></code>
+ </td>
+ <td>
+ <code>ACCESS_FINE_LOCATION</code> or <code>ACCESS_COARSE_LOCATION</code>
+ </td>
+ </tr>
+</table>
+
+
+<h2 id="working_with_advertising_ids">Working with Advertising IDs</h2>
+
+<p>
+ Advertising ID is a user-resettable identifier and is appropriate for Ads
+ use-cases, but there are some key points to bear in mind when using it:
+</p>
+
+<p>
+ <em><strong>Always respect the user’s intention in resetting the advertising
+ ID</strong></em>. Do not bridge user resets by using a more persistent device
+ identifier or fingerprint to link subsequent Advertising IDs together without
+ the user’s consent. The <a href=
+ "https://play.google.com/about/developer-content-policy.html">Google Play
+ Developer Content Policy</a> states:
+</p>
+
+<div style="padding:.5em 2em;">
+<div style="border-left:4px solid #999;padding:0 1em;font-style:italic;">
+<p>...upon reset, a new advertising
+ identifier must not be connected to a previous advertising identifier or data
+ derived from a previous advertising identifier without the explicit consent
+ of the user</span></p>
+</div>
+</div>
+
+<p>
+ <em><strong>Always respect the associated Interest Based Advertising
+ flag</strong></em>. Advertising IDs are configurable in that users can limit
+ the amount of tracking associated with the ID. Always use the <code><a href=
+ "https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html#isLimitAdTrackingEnabled()">
+ AdvertisingIdClient.Info.isLimitAdTrackingEnabled()</a></code> method to
+ ensure you are not circumventing your users' wishes. The <a href=
+ "https://play.google.com/about/developer-content-policy.html">Google Play
+ Developer Content Policy</a> states:
+</p>
+
+
+<div style="padding:.5em 2em;">
+<div style="border-left:4px solid #999;padding:0 1em;font-style:italic;">
+<p>...you must abide by a user’s ‘opt out of
+ interest-based advertising’ setting. If a user has enabled this setting, you
+ may not use the advertising identifier for creating user profiles for
+ advertising purposes or for targeting users with interest-based advertising.
+ Allowed activities include contextual advertising, frequency capping,
+ conversion tracking, reporting and security and fraud detection.</span></p>
+</div>
+</div>
+
+<p>
+ <em><strong>Be aware of any privacy or security policies associated with SDKs
+ you use that are related to Advertising ID use.</strong></em> For example, if
+ you are using the Google Analytics SDK
+ <code><a href=
+ "https://developers.google.com/android/reference/com/google/android/gms/analytics/Tracker.html#enableAdvertisingIdCollection(boolean)">mTracker.enableAdvertisingIdCollection(true)</a></code>
+ method, make sure to review and adhere to all applicable <a href=
+ "https://developers.google.com/analytics/devguides/collection/android/v4/policy">
+ Analytics SDK policies</a>.
+</p>
+
+<p>
+ Also, be aware that the <a href=
+ "https://play.google.com/about/developer-content-policy.html">Google Play
+ Developer Content Policy</a> requires that the Advertising ID “must not be
+ connected to personally-identifiable information or associated with any
+ persistent device identifier (for example: SSAID, MAC address, IMEI, etc.,)
+ without the explicit consent of the user.”
+</p>
+
+<p>
+ As an example, suppose you want to collect information to populate database
+ tables with the following columns:
+</p>
+
+<table>
+ <tr>
+ <td>
+ <table>
+ <tr>
+ <td class="tab2">
+ <code>timestamp</code></td>
+ <td class="tab2">
+ <code>ad_id</code></td>
+ <td>
+ <code><strong>account_id</strong></code></td>
+ <td class="tab2">
+ <code>clickid</code></td>
+ </tr>
+ </table>
+
+ <p>TABLE-01</p>
+ </td>
+ <td>
+ <table>
+ <tr>
+ <td>
+ <code><strong>account_id</strong></code></td>
+ <td class="tab2">
+ <code>name</code></td>
+ <td class="tab2">
+ <code>dob</code></td>
+ <td class="tab2">
+ <code>country</code></td>
+ </tr>
+ </table>
+ <p>TABLE-02</p>
+ </td>
+ </tr>
+</table>
+
+
+<p>
+ In this example, the <code>ad_id</code> column could be joined to PII via the
+ <code>account_id</code> column in both tables, which would be a violation of
+ the <a href=
+ "https://play.google.com/about/developer-content-policy.html">Google Play
+ Developer Content Policy</a>.
+</p>
+
+<p>
+ Keep in mind that links between Advertiser ID and PII aren't always this
+ explicit. It's possible to have “quasi-identifiers” that appear in both PII
+ and Ad ID keyed tables, which also cause problems. For example, assume we
+ change TABLE-01 and TABLE-02 as follows:
+</p>
+
+<table>
+ <tr>
+ <td><table>
+ <tr>
+ <td>
+ <code><strong>timestamp</strong></code></td>
+ <td class="tab2">
+ <code>ad_id</code></td>
+ <td>
+ <code>clickid</code></td>
+ <td>
+ <code><strong>dev_model</strong></code></td>
+ </tr>
+ </table>
+
+ </pre>
+ <p>TABLE-01</p>
+ </td>
+ <td>
+ <table>
+ <tr>
+ <td>
+ <code><strong>timestamp</strong></code></td>
+ <td class="tab2">
+ <code>demo</code></td>
+ <td class="tab2">
+ <code>account_id</code></td>
+ <td>
+ <code><strong>dev_model</strong></code></td>
+ <td class="tab2">
+ <code>name</code></td>
+ </tr>
+ </table>
+ <p>TABLE-02</p>
+ </td>
+ </tr>
+</table>
+
+
+<p>
+ In this case, with sufficiently rare click events, it's still possible to
+ join between the Advertiser ID TABLE-01 and the PII contained in TABLE-2
+ using the timestamp of the event and the device model.
+</p>
+
+<p>
+ While it is often difficult to guarantee that no such quasi-identifiers exist
+ in a dataset, the most obvious join risks can be prevented by generalizing
+ unique data where possible. In the example, this would mean reducing the
+ accuracy of the timestamp so that multiple devices with the same model appear
+ for every timestamp.
+</p>
+
+<p>
+ Other solutions include:
+</p>
+
+<ul>
+<li><em><strong>Not designing tables that explicitly link PII with Advertising
+IDs</strong></em>. In the first example above this would mean not including the
+account_id column in TABLE-01.</li>
+
+<li><em><strong>Segregating and monitoring access control lists for users or roles
+that have access to both the Advertising ID keyed data and PII</strong></em>. If the
+ability to access both sources simultaneously (for example, to perform
+a join between two tables) is tightly controlled and audited, it reduces the
+risk of association between the Advertising ID and PII. Generally speaking,
+controlling access means:
+
+<ol>
+ <li> Keeping access control lists (ACLs) for Advertiser ID keyed data and PII disjoint to
+ minimize the number of individuals or roles that are in both ACLs, and</li>
+ <li> Implementing access logging and auditing to detect and manage any exceptions to
+ this rule.</li>
+</ol>
+</li>
+</ul>
+
+<p>
+ For more information on working responsibly with Advertising IDs, please see
+ the <a href=
+ "https://support.google.com/googleplay/android-developer/answer/6048248?hl=en">
+ Advertising ID</a> help center article.
+</p>
+
+<h2 id="working_with_instance_ids_&_guids">Working with Instance IDs and GUIDs</h2>
+
+<p>
+ The most straightforward solution to identifying an application instance
+ running on a device is to use an Instance ID, and this is the recommended
+ solution in the majority of non-ads use-cases. Only the app instance for
+ which it was provisioned can access this identifier, and it's (relatively)
+ easily resettable because it only persists as long as the app is installed.
+</p>
+
+<p>
+ As a result, Instance IDs provide better privacy properties compared to
+ non-resettable, device-scoped hardware IDs. They also come with a key-pair
+ for message signing (and similar actions) and are available on Android, iOS
+ and Chrome. Please see the <a href=
+ "https://developers.google.com/instance-id/">What is Instance ID?</a> help
+ center document for more information.
+</p>
+
+<p>
+ In cases where an Instance ID isn't practical, custom globally unique IDs
+ (GUIDs) can also be used to uniquely identify an app instance. The simplest
+ way to do so is by generating your own GUID using the following code.
+</p>
+
+<pre>String uniqueID = UUID.randomUUID().toString();</pre>
+
+<p>
+ Because the identifier is globally unique, it can be used to identify a
+ specific app instance. To avoid concerns related to linking the identifier
+ across applications, GUIDs should be stored in internal storage rather than
+ external (shared) storage. Please see <a href=
+ "{@docRoot}guide/topics/data/data-storage.html">Storage Options</a> guide for
+ more information.
+</p>
+
+
+<h2 id="understand_identifier_characteristics">Understanding Identifier Characteristics</h2>
+
+<p>
+ The Android Operating system offers a number of IDs with different behavior
+ characteristics and which ID you should use depends on how those following
+ characteristics work with your use-case. But these characteristics also come
+ with privacy implications so it's important to understand how these
+ characteristics play together.
+</p>
+
+<h3 id="scope">Scope</h3>
+
+<p>
+ Identifier scope explains which systems can access the identifier. Android
+ identifier scope generally comes in three flavors:
+</p>
+
+<ul>
+ <li> <em>Single app</em>. the ID is internal to the app and not accessible to other apps.
+ <li> <em>Group of apps</em> - the ID is accessible to a pre-defined group of related apps.
+ <li> <em>Device</em> - the ID is accessible to all apps installed on the device.
+</ul>
+
+<p>
+ The wider the scope granted to an identifier, the greater the risk of it
+ being used for tracking purposes. Conversely, if an identifier can only be
+ accessed by a single app instance, it can’t be used to track a device across
+ transactions in different apps.
+</p>
+<h3 id="resettability_&_persistence">Resettability and persistence</h3>
+
+<p>
+ Resettability and persistence define the lifespan of the identifier and
+ explain how it can be reset. Common reset triggers are: in-app resets, resets
+ via System Settings, resets on launch, and resets on installation. Android
+ Identifiers can have varying lifespans, but the lifespan is usually related
+ to how the ID is reset:
+</p>
+<ul>
+ <li> <em>Session-only</em> - a new ID is used every time the user restarts the app.
+ <li> <em>Install-reset</em> - a new ID is used every time user uninstalls and reinstalls the app.
+ <li> <em>FDR-reset</em> - a new ID is used every time the user factory-resets the device.
+ <li> <em>FDR-persistent</em> - the ID survives factory reset.
+</ul>
+
+<p>
+ Resettability gives users the ability to create a new ID that is
+ disassociated from any existing profile information. This is important
+ because the longer, and more reliably, an identifier persists (e.g. across
+ factory resets etc.), the greater the risk that the user may be subjected to
+ long-term tracking. If the identifier is reset upon app reinstall, this
+ reduces the persistence and provides a means for the ID to be reset, even if
+ there is no explicit user control to reset it from within the app or the
+ System Settings.
+</p>
+<h3 id="uniqueness">Uniqueness</h3>
+
+<p>
+ Uniqueness establishes the likelihood that identical identifiers exist within
+ the associated scope. At the highest level, a globally unique identifier will
+ never have a collision - even on other devices/apps. Otherwise, the level of
+ uniqueness depends on the size of the identifier and the source of randomness
+ used to create it. For example, the chance of a collision is much higher for
+ random identifiers seeded with the calendar date of installation (e.g.,
+ 2015-01-05) than for identifiers seeded with the Unix timestamp of
+ installation (e.g., 1445530977).
+</p>
+
+<p>
+ In general, user account identifiers can be considered unique (i.e., each
+ device/account combo has a unique ID). On the other hand, the less unique
+ an identifier is within a population (e.g. of devices), the greater the
+ privacy protection because it's less useful for tracking an individual user.
+</p>
+
+<h3 id="integrity_protection_and_non-repudiability">Integrity protection and
+non-repudiability</h3>
+
+<p>
+ An identifier that is difficult to spoof or replay can be used to prove that
+ the associated device or account has certain properties (e.g. it’s not a
+ virtual device used by a spammer). Difficult to spoof identifiers also
+ provide <em>non-repudiability</em>. If the device signs a message with a
+ secret key, it is difficult to claim someone else’s device sent the message.
+ Non-repudiability could be something a user wants (e.g. authenticating a
+ payment) or it could be an undesirable property (e.g. sending a message they
+ regret).
+</p>
+
+
+<h2 id="use_appropriate_identifiers">Common Use Cases and the Identifier to Use</h2>
+
+<p>
+ This section provides alternatives to using hardware IDs such as IMEI or
+ SSAID for the majority of use-cases. Relying on hardware IDs is discouraged
+ because the user cannot reset them and generally has limited control over
+ their collection.
+</p>
+
+<h3 id="a_track_signed-out_user_preferences">Tracking signed-out user preferences</h3>
+
+<p>
+ <em>In this case, you are saving per-device state on the server side.</em>
+</p>
+
+<p>
+ <strong>We Recommend</strong>: Instance ID or a GUID.
+</p>
+
+<p>
+ <strong>Why this Recommendation?</strong>
+</p>
+
+<p>
+ Persisting information through reinstalls is not recommended because users
+ may want to reset their preferences by reinstalling the app.
+</p>
+
+<h3 id="b_track_signed-out_user_behavior">Tracking signed-out user behavior</h3>
+
+<p>
+ <em>In this case, you have created a profile of a user based on their
+ behavior across different apps/sessions on the same device.</em>
+</p>
+
+<p>
+ <strong>We Recommend</strong>: Advertising ID.
+</p>
+
+<p>
+ <strong>Why this Recommendation?</strong>
+</p>
+
+<p>
+ Use of the Advertising ID is mandatory for Advertising use-cases per the
+ <a href="https://play.google.com/about/developer-content-policy.html">Google
+ Play Developer Content Policy</a> because the user can reset it.
+</p>
+
+<h3 id="c_generate_signed-out_anonymous_user_analytics">Generating signed-out/anonymous user analytics</h3>
+
+<p>
+ <em>In this case, you are measuring usage statistics and analytics for
+ signed-out or anonymous users.</em>
+</p>
+
+<p>
+ <strong>We Recommend</strong>: Instance ID; if an Instance ID is
+ insufficient, you can also use a GUID.
+</p>
+
+<p>
+ <strong>Why this Recommendation?</strong>
+</p>
+
+<p>
+ An Instance ID or a GUID is scoped to the app that creates it, which prevents
+ it from being used to track users across apps. It is also easily reset by
+ clearing app data or reinstalling the app. Creating Instance IDs and GUIDs is
+ straightforward:
+</p>
+
+<ul>
+ <li> Creating an Instance ID: <code>String iid = InstanceID.getInstance(context).getId()</code>
+ <li> Creating a GUID: <code>String uniqueID = UUID.randomUUID().toString</code>
+</ul>
+
+<p>
+ Be aware that if you have told the user that the data you are collecting is
+ anonymous, you should <em><strong>ensure you are not connecting the
+ identifier to PII</strong></em> or other identifiers that may be linked to
+ PII.
+</p>
+
+<p>
+ You can also use Google Analytics for Mobile Apps, which offers a solution
+ for per-app analytics.
+</p>
+
+<h3 id="d_track_signed-out_user_conversion">Tracking signed-out user conversion</h3>
+
+<p>
+ <em>In this case, you are tracking conversions to detect if your marketing
+ strategy was successful.</em>
+</p>
+
+<p>
+ <strong>We Recommend</strong>: Advertising ID.
+</p>
+
+<p>
+ <strong>Why this Recommendation?</strong>
+</p>
+
+<p>
+ This is an ads-related use-case which may require an ID that is available
+ across different apps so using an Advertising ID is the most appropriate
+ solution.
+</p>
+
+<h3 id="e_handle_multiple_installations">Handling multiple installations</h3>
+
+<p>
+ <em>In this case, you need to identify the correct instance of the app when
+ it's installed on multiple devices for the same user.</em>
+</p>
+
+<p>
+ <strong>We Recommend</strong>: Instance ID or GUID.
+</p>
+
+<p>
+ <strong>Why this Recommendation?</strong>
+</p>
+
+<p>
+ Instance ID is designed explicitly for this purpose; its scope is limited to
+ the app so that it cannot be used to track users across different apps and it
+ is reset upon app reinstall. In the rare cases where an Instance ID is
+ insufficient, you can also use a GUID.
+</p>
+
+<h3 id="f_anti-fraud_enforcing_free_content_limits_detecting_sybil_attacks">Anti-fraud: Enforcing free content limits / detecting Sybil attacks</h3>
+
+<p>
+ <em>In this case, you want to limit the number of free content (e.g.
+ articles) a user can see on a device.</em>
+</p>
+
+<p>
+ <strong>We Recommend</strong>: Instance ID or GUID.
+</p>
+
+<p>
+ <strong>Why this Recommendation?</strong>
+</p>
+
+<p>
+ Using a GUID or Instance ID forces the user to reinstall the app in order to
+ overcome the content limits, which is a sufficient burden to deter most
+ people. If this is not sufficient protection, Android provides a
+ <a href="http://source.android.com/devices/drm.html">DRM API</a>
+ which can be used to limit access to content.
+</p>
+
+<h3 id="g_manage_telephony_&_carrier_functionality">Managing telephony and carrier functionality</h3>
+
+<p>
+ <em>In this case, your app is interacting with the device's phone and texting
+ functionality.</em>
+</p>
+
+<p>
+ <strong>We Recommend</strong>: IMEI, IMSI, and Line1 (requires <code>PHONE</code>
+ permission group in Android 6.0 (API level 23) and higher).
+</p>
+
+<p>
+ <strong>Why this Recommendation?</strong>
+</p>
+
+<p>
+ Leveraging hardware identifiers is acceptable if it is required for
+ telephony/carrier related functionality; for example, switching between
+ cellular carriers/SIM slots or delivering SMS messages over IP (for Line1) -
+ SIM-based user accounts. But it's important to note that in Android 6.0+
+ these identifiers can only be used via a runtime permission and that users
+ may toggle off this permission so your app should handle these exceptions
+ gracefully.
+</p>
+
+<h3 id="h_abuse_detection_identifying_bots_and_ddos_attacks">Abuse detection:
+Identifying bots and DDoS attacks</h3>
+
+<p>
+ <em>In this case, you are trying to detect multiple fake devices attacking
+ your backend services.</em>
+</p>
+
+<p>
+ <strong>We Recommend:</strong> The Safetynet API.
+</p>
+
+<p>
+ <strong>Why this Recommendation?</strong>
+</p>
+
+<p>
+ An identifier in isolation does little to indicate that a device is genuine.
+ You can verify that a request comes from a genuine Android device (as opposed
+ to an emulator or other code spoofing another device) using the Safetynet
+ API's <code>SafetyNet.SafetyNetApi.attest(mGoogleApiClient, nonce)</code>
+ method to verify the integrity of a device making a request. For more
+ detailed information, please see <a href=
+ "{@docRoot}training/safetynet/index.html">Safetynet's API documentation</a>.
+</p>
+
+<h3 id="i_abuse_detection_detecting_high_value_stolen_credentials">Abuse detection:
+Detecting high value stolen credentials</h3>
+
+<p>
+ <em>In this case, you are trying to detect if a single device is being used
+ multiple times with high-value, stolen credentials (e.g. to make fraudulent
+ payments).</em>
+</p>
+
+<p>
+ <strong>We Recommend</strong>: IMEI/IMSI (requires <code>PHONE</code>
+ permission group in Android 6.0 (API level 23) and higher.)
+</p>
+
+<p>
+ <strong>Why this Recommendation?</strong>
+</p>
+
+<p>
+ With stolen credentials, devices can be used to monetize multiple high value
+ stolen credentials (such as tokenized credit cards). In these scenarios,
+ software IDs can be reset to avoid detection, so hardware identifiers may be
+ used.
+</p>
\ No newline at end of file
diff --git a/docs/html/training/articles/user-data-overview.jd b/docs/html/training/articles/user-data-overview.jd
new file mode 100644
index 0000000..42322a9
--- /dev/null
+++ b/docs/html/training/articles/user-data-overview.jd
@@ -0,0 +1,266 @@
+page.title=Permissions and User Data
+page.metaDescription=An overview of permissions on Android and how to manage them.
+page.tags="user data","permissions","identifiers"
+page.image=images/cards/card-user_2x.png
+
+page.article=true
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#introduction">Introduction</a></li>
+ <li><a href="#permission_groups">Permission Groups</a></li>
+ <li><a href="#permission_requests_and_app_downloads">Permission
+ Requests and App Downloads</a></li>
+ <li><a href="#permission_requests_trend_downward">Permission Requests
+ Trend Downward</a></li>
+ </ol>
+ <h2>You should also read</h2>
+ <ol>
+ <li><a href="{@docRoot}guide/topics/security/permissions.html">System Permissions</a></li>
+ <li><a href="{@docRoot}training/permissions/index.html">Working with System
+ Permissions</a></li>
+ </ol>
+ </div>
+</div>
+
+<p>
+ Permissions protect sensitive information available from a device and should
+ only be used when access to information is necessary for the functioning of
+ your app.
+</p>
+
+<p>
+ This document provides a high-level overview on how permissions work in
+ Android so you can make better, more informed decisions about the permissions
+ you're requesting. The information in this document is not use-case specific
+ and avoids complex, low-level discussions of the underlying code.
+</p>
+
+<p>
+ For specific recommendations on how to manage permissions, please see
+ <a href="{@docRoot}training/articles/user-data-permissions.html">Best
+ Practices for App Permissions</a>. For best practices on using unique
+ identifiers on Android, please see <a href=
+ "{@docRoot}training/articles/user-data-ids.html">Best Practices for Unique
+ Identifiers</a>. For details on how to work with permissions in your code,
+ see <a href="{@docRoot}training/permissions/index.html">Working with System
+ Permissions</a>.
+</p>
+
+
+<h2 id="introduction">Introduction</h2>
+
+<p>
+ Every Android application must have a <em>manifest file</em> that presents
+ essential information about the app to the Android system. The Android system
+ also requires apps to request permission when they want to access sensitive
+ device or user information, and these requests must be documented in advance
+ as a part of your app's manifest. Moreover, accessing sensitive information
+ can affect user behavior, so it's important to make sure you are only making
+ permission requests when that information is necessary for the functioning of
+ your app.
+</p>
+
+
+<h2 id="permission_groups">Permission Groups</h2>
+
+<p>
+ Permissions in Android are organized into <code><a href=
+ "{@docRoot}guide/topics/security/permissions.html#perm-groups">permission
+ groups</a></code> that organize, and group, permissions related to a device's
+ capabilities or features. Under this system, permission requests are handled
+ at the group level and a <em><strong>single permission group</strong></em>
+ corresponds to <em><strong>several permission declarations</strong></em> in
+ the app manifest; for example, the SMS group includes both the
+ <code>READ_SMS</code> and the <code>RECEIVE_SMS</code> declarations.
+</p>
+
+
+<div class="wrap">
+ <img src="{@docRoot}images/training/articles/user-data-overview-permissions-flow01.jpg">
+</div>
+
+<p>
+ This arrangement is simpler and more informative for users; once an app is
+ granted permission to access the group, it can use API calls within that
+ group and users with auto-update enabled will not be asked for additional
+ permissions because they have already granted access to the group. Grouping
+ permissions in this way enables the user to make more meaningful and informed
+ choices, without being overwhelmed by complex and technical permission
+ requests.
+</p>
+
+<p>
+ This also means that when you request access to a particular API call or
+ query a content provider behind a permission, the user will be presented with
+ a request to grant permission for the whole group rather than the specific
+ API call. For example, if you request the <code>MANAGE_ACOUNTS</code>
+ permission, the user will be asked to grant access to the <em>Identity</em>
+ group (in API level 22 and lower), which is composed of the <code>GET_ACCOUNTS</code>,
+ <code>READ_PROFILE</code>, and <code>WRITE_PROFILE</code> permissions, and
+ all their associated methods.
+</p>
+
+<div class="wrap">
+ <img src="{@docRoot}images/training/articles/user-data-overview-permissions-flow02.jpg">
+</div>
+
+<p>
+ One consequence of grouping permissions is that a single API call within your
+ app can have a multiplying effect in terms of the number of permissions
+ requested by your app.
+</p>
+
+<ol>
+<li>API Call →</li>
+<li stydle="margin-left:.5em;">Triggers a specific <em>Permission Group</em> access
+request →</li>
+<li stydle="margin-left:1em;">Successful request grants access to all permissions in
+group (if auto-update
+enabled) →</li>
+<li stydle="margin-left:1.5em;">Each permission grants access to all APIs under that
+permission</li>
+</ol>
+
+<p>
+ As another example, let's assume your application uses one or more <a href=
+ "{@docRoot}reference/android/telephony/TelephonyManager.html"><code>TelephonyManager</code></a>
+ methods, such as:
+</p>
+
+<pre class="prettyprint">
+TelephonyManager.getDeviceId()
+TelephonyManager.getSubscriberId()
+TelephonyManager.getSimSerialNumber()
+TelephonyManager.getLine1Number()
+TelephonyManager.getVoiceMailNumber()
+</pre>
+
+<p>
+ To use these methods, the <code>READ_PHONE_STATE</code> permission must be
+ declared in the app's manifest, and the associated permission group,
+ <em>Device ID and Call information</em>, will be surfaced to the user. This
+ is important, because it means the user will be asked to grant permission for
+ the relevant group and all its associated permissions and API calls, rather
+ than for the specific API call you're requesting.
+</p>
+
+<p>For a full mapping between permissions and their associated permission groups,
+please refer to the appropriate version-specific documentation below:</p>
+
+<ul>
+ <!--<li> <a href="">pre-M Android OS versions</a>.</li> -->
+ <li> <a href="{@docRoot}guide/topics/security/permissions.html#perm-groups">Permission
+ groups, Android 6.0 Marshmallow (API level 23) and later</a>.</li>
+</ul>
+
+
+<h2 id="permission_requests_and_app_downloads">Permission Requests and App Downloads</h2>
+
+<div style="padding:.5em 2em;">
+<div style="border-left:4px solid #999;padding:0 1em;font-style:italic;">
+<p><em>I'm currently using the READ_PHONE_STATE permission in Android to pause my
+media player when there's a call, and to resume playback when the call is over.
+The permission seems to scare a lot of people</em>...<span
+style="font-size:.8em;color:#777"><sup><em><a
+href="#references" style="color:#777;padding-left:.1em;">1</a></em></span></p>
+</div>
+</div>
+
+<p>
+ Research shows that among apps that are otherwise identical (e.g.,
+ functionality, brand recognition), requesting fewer permissions leads to more
+ downloads. Publicly available sources exist that assign grades to apps based
+ on their permissions usage and allow users to compare related apps by score;
+ such grades exist for many of the current Android apps and users pay close
+ attention to the related rankings.
+</p>
+
+<p>
+ One study<span style="font-size:.8em;color:#777"><sup><em><a href=
+ "#references" style=
+ "color:#777;padding-left:.1em;">2</a></em></sup></span><sup>, in which users
+ were shown two unbranded apps with similar ratings that had the same
+ functionality but different sets of permission requests, showed that users
+ were, on average, 3 times more likely to install the app with fewer
+ permissions requests. And a similar study<span style=
+ "font-size:.8em;color:#777"><sup><em><a href="#references" style=
+ "color:#777;padding-left:.1em;">3</a></em></sup> showed that users are 1.7
+ times more likely, on average, to select the application with fewer
+ permission requests.</span></sup>
+</p>
+
+<p>
+ <sup>Finally, permissions usage is not evenly distributed across apps within
+ a similar category of Play apps. For example, 39.3% of arcade game apps in
+ the Play store request no permissions that are surfaced to the user while
+ only 1.5% of arcade games request the Phone permission group (see Figure
+ 1).</sup>
+</p>
+
+<div class="wrap">
+ <div class="cols">
+ <div class="col-16of16">
+ <img src="{@docRoot}images/training/articles/user-data-overview-permissions-groups.png">
+ <p class="figure-caption"><strong>Figure 1.</strong> Distribution of
+ permission groups use across Arcade Games category.</p>
+ </div>
+ </div>
+</div>
+
+<p>
+ Users comparing your app to other similar apps may determine that it is
+ making unusual permission requests for that category - in this case, Arcade
+ Games apps accessing the <em>Phone</em> permission group. As a result, they
+ may install a similar app in that category that avoids those
+ requests.<span style="font-size:.8em;color:#777"><sup><em><a href=
+ "#references" style="color:#777;padding-left:.1em;">4</a></em></sup></span>
+</p>
+
+
+<h2 id="permission_requests_trend_downward">Permission Requests Trend Downward</h2>
+
+<p>
+ A recent analysis of Play store apps over time indicated that many developers
+ trim permissions after first publishing their apps, suggesting that they may
+ be employing more caution around which permission groups they declare.
+</p>
+
+<div class="wrap">
+ <div class="cols">
+ <div class="col-16of16">
+ <img src="{@docRoot}images/training/articles/user-data-overview-permissions-usage.jpg">
+ <p class="figure-caption"><strong>Figure 2.</strong> Developer usage of popular
+ permissions has decreased over time.</p>
+ </div>
+ </div>
+</div>
+
+<p>
+ The graph in <em>Figure 2</em> illustrates this trend. There has been a
+ steady decrease in the average percentage of developers' apps requesting at
+ least one of the three most popular permissions in the Play store
+ (<code>READ_PHONE_STATE</code>, <code>ACCESS_FINE_LOCATION</code>, and
+ <code>ACCESS_COARSE_LOCATION</code>). These results indicate that developers
+ are reducing the permissions their apps request in response to user behavior.
+</p>
+
+<p>
+ The bottom line is that providing the same functionality to the user with
+ minimal access to sensitive information means more downloads for your app.
+ For specific recommendations on how to achieve this, please see <a href=
+ "{@docRoot}training/articles/user-data-permissions.html">Best Practices for
+ Application Permissions</a>.
+</p>
+
+
+<h2 id="references">References</h2>
+
+<p>[1] Developer quote on StackOverflow. <em>(<a
+ href="http://stackoverflow.com/questions/24374701/alternative-to-read-phone-state-permission-for-getting-notified-of-call">source</a>)</em></p>
+<p>[2] <em>Using Personal Examples to Improve Risk Communication for Security and Privacy Decisions</em>, by M. Harbach, M. Hettig, S. Weber, and M. Smith. In Proceedings of ACM CHI 2014.</p>
+<p>[3] <em>Modeling Users’ Mobile App Privacy Preferences: Restoring Usability in a Sea of Permission Settings</em>, by J. Lin B. Liu, N. Sadeh and J. Hong. In Proceedings of SOUPS 2014.</p>
+<p>[4] <em>Teens and Mobile Apps Privacy. (<a href="http://www.pewinternet.org/files/old-media/Files/Reports/2013/PIP_Teens%20and%20Mobile%20Apps%20Privacy.pdf">source</a>)</em></p>
diff --git a/docs/html/training/articles/user-data-permissions.jd b/docs/html/training/articles/user-data-permissions.jd
new file mode 100644
index 0000000..edc7558
--- /dev/null
+++ b/docs/html/training/articles/user-data-permissions.jd
@@ -0,0 +1,381 @@
+page.title=Best Practices for App Permissions
+page.metaDescription=How to manage permissions to give users context and control.
+page.tags=permissions, user data
+meta.tags="permissions", "user data"
+page.image=images/cards/card-user-permissions_2x.png
+
+page.article=true
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#tenets_of_working_with_android_permissions">Tenets</a></li>
+ <li><a href="#version_specific_details_permissions_in_m">Permissions in Android
+ 6.0+</h2></a></li>
+ <li><a href="#avoid_requesting_unnecessary_permissions">Avoid Requesting
+Unnecessary Permissions</h2></a>
+ <ol>
+ <li><a href="#a_camera_contact_access_with_real-time_user_requests">Camera/Contact
+ access with realtime user requests</a></li>
+ <li><a href="#b_running_in_the_background_after_losing_audio_focus">Running in
+the background after losing audio focus</a></li>
+ <li><a href="#c_determine_the_device_your_instance_is_running_on">Determine the
+device your instance is running on</a></li>
+ <li><a href="#d_create_a_unique_identifier_for_advertising_or_user_analytics">
+Create a unique identifier for advertising or user analytics</a></li>
+ </ol>
+ </li>
+ <li><a href="#know_the_libraries_you're_working_with">Know the Libraries You're
+Working With</a></li>
+ <li><a href="#be_transparent">Be Transparent</a></li>
+ </ol>
+ <h2>You should also read</h2>
+ <ol>
+ <li><a href="{@docRoot}guide/topics/security/permissions.html">System Permissions</a></li>
+ <li><a href="{@docRoot}training/permissions/index.html">Working with System
+ Permissions</a></li>
+ </ol>
+ </div>
+</div>
+
+<p>
+ Permission requests protect sensitive information available from a device and
+ should only be used when access to information is necessary for the
+ functioning of your app. This document provides tips on ways you might be
+ able to achieve the same (or better) functionality without requiring access
+ to such information; it is not an exhaustive discussion of how permissions
+ work in the Android operating system.
+</p>
+
+<p>
+ For a more general look at Android permissions, please see <a href=
+ "{@docRoot}training/articles/user-data-overview.html">Permissions
+ and User Data</a>. For details on how to work with permissions in your code,
+ see <a href="{@docRoot}training/permissions/index.html">Working with System Permissions</a>.
+ For best practices for working with unique identifiers, please see <a href=
+ "{@docRoot}training/articles/user-data-ids.html">Best Practices for
+ Unique Identifiers</a>.
+</p>
+
+<h2 id="tenets_of_working_with_android_permissions">Tenets of Working
+with Android Permissions</h2>
+
+<p>
+ We recommend following these tenets when working with Android permissions:
+</p>
+
+<p>
+ <em><strong>#1: Only use the permissions necessary for your app to
+ work</strong></em>. Depending on how you are using the permissions, there may
+ be another way to do what you need (system intents, identifiers,
+ backgrounding for phone calls) without relying on access to sensitive
+ information.
+</p>
+
+<p>
+ <em><strong>#2: Pay attention to permissions required by
+ libraries.</strong></em> When you include a library, you also inherit its
+ permission requirements. You should be aware of what you're including, the
+ permissions they require, and what those permissions are used for.
+</p>
+
+<p>
+ <em><strong>#3: Be transparent.</strong></em> When you make a permissions
+ request, be clear about what you’re accessing, and why, so users can make
+ informed decisions. Make this information available alongside the permission
+ request including install, runtime, or update permission dialogues.
+</p>
+
+<p>
+ <em><strong>#4: Make system accesses explicit.</strong></em> Providing
+ continuous indications when you access sensitive capabilities (for example, the
+ camera or microphone) makes it clear to users when you’re collecting data and
+ avoids the perception that you're collecting data surreptitiously.
+</p>
+
+<p>
+ The remaining sections of this guide elaborate on these rules in the context
+ of developing Android applications.
+</p>
+
+<h2 id="version_specific_details_permissions_in_m">Permissions in Android 6.0+</h2>
+
+<p>
+ Android 6.0 Marshmallow introduced a <a href=
+ "{@docRoot}training/permissions/requesting.html">new permissions model</a> that
+ lets apps request permissions from the user at runtime, rather than prior to
+ installation. Apps that support the new model request permissions when the app
+ actually requires the services or data protected by the services. While this
+ doesn't (necessarily) change overall app behavior, it does create a few
+ changes relevant to the way sensitive user data is handled:
+</p>
+
+<p>
+ <em><strong>Increased situational context</strong></em>: Users are
+ prompted at runtime, in the context of your app, for permission to access the
+ functionality covered by those permission groups. Users are more sensitive to
+ the context in which the permission is requested, and if there’s a mismatch
+ between what you are requesting and the purpose of your app, it's even
+ more important to provide detailed explanation to the user as to why you’re
+ requesting the permission; whenever possible, you should provide an
+ explanation of your request both at the time of the request and in a
+ follow-up dialog if the user denies the request.
+</p>
+
+<p>
+ <em><strong>Greater flexibility in granting permissions</strong></em>: Users
+ can deny access to individual permissions at the time they’re requested
+ <em>and</em> in settings, but they may still be surprised when functionality is
+ broken as a result. It’s a good idea to monitor how many users are denying
+ permissions (e.g. using Google Analytics) so that you can either refactor
+ your app to avoid depending on that permission or provide a better
+ explanation of why you need the permission for your app to work properly. You
+ should also make sure that your app handles exceptions created when users
+ deny permission requests or toggle off permissions in settings.
+</p>
+
+<p>
+ <em><strong>Increased transactional burden</strong></em>: Users will be asked
+ to grant access for permission groups individually and not as a set. This
+ makes it extremely important to minimize the number of permissions you’re
+ requesting because it increases the user burden for granting permissions and
+ increases the probability that at least one of the requests will be denied.
+</p>
+
+<h2 id="avoid_requesting_unnecessary_permissions">Avoid Requesting
+Unnecessary Permissions</h2>
+
+<p>
+ This section provides alternatives to common use-cases that will help you
+ limit the number of permission requests you make. Since the number and type
+ of user-surfaced permissions requested affects downloads compared to other
+ similar apps requesting fewer permissions, it’s best to avoid requesting
+ permissions for unnecessary functionality.
+</p>
+
+<h3 id="a_camera_contact_access_with_real-time_user_requests">Camera/contact
+access with realtime user requests</h3>
+
+<p>
+ <em>In this case, you need occasional access to the device's camera or
+ contact information and don’t mind the user being asked every time you need
+ access.</em>
+</p>
+
+<p>
+ If your requirement for access to user data is infrequent — in other
+ words, it's not unacceptably disruptive for the user to be presented with a
+ runtime dialogue each time you need to access data — you can use an
+ <em>intent based request</em>. Android provides some system intents that
+ applications can use without requiring permissions because the user chooses
+ what, if anything, to share with the app at the time the intent based request
+ is issued.
+</p>
+
+<p>
+ For example, an intent action type of <code><a href=
+ "{@docRoot}reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE">MediaStore.ACTION_IMAGE_CAPTURE</a></code>
+ or <code><a href=
+ "{@docRoot}reference/android/provider/MediaStore.html#ACTION_VIDEO_CAPTURE">MediaStore.ACTION_VIDEO_CAPTURE</a></code>
+ can be used to capture images or videos without directly using the <a href=
+ "{@docRoot}reference/android/hardware/Camera.html">Camera</a> object (or
+ requiring the permission). In this case, the system intent will ask for the
+ user’s permission on your behalf every time an image is captured.
+</p>
+
+<h3 id="b_running_in_the_background_after_losing_audio_focus">Running in
+the background after losing audio focus</h3>
+
+<p>
+ <em>In this case, your application needs to go into the background when the
+ user gets a phone call and refocus only once the call stops.</em>
+</p>
+
+<p>
+ The common approach in these cases - for example, a media player muting or
+ pausing during a phone call - is to listen for changes in the call state
+ using <code>PhoneStateListener</code> or listening for the broadcast of
+ <code>android.intent.action.PHONE_STATE</code>. The problem with this
+ solution is that it requires the <code>READ_PHONE_STATE</code> permission,
+ which forces the user to grant access to a wide cross section of sensitive
+ data such as their device and SIM hardware IDs and the phone number of the
+ incoming call.
+</p>
+
+<p>
+ You can avoid this by requesting <code>AudioFocus</code> for your app, which
+ doesn't require explicit permissions (because it does not access sensitive
+ information). Simply put the code required to background your audio in the
+ <code><a href=
+ "{@docRoot}reference/android/media/AudioManager.OnAudioFocusChangeListener.html#onAudioFocusChange(int)">
+ onAudioFocusChange()</a></code> event handler and it will run automatically
+ when the OS shifts its audio focus. More detailed documentation on how to do
+ this can be found <a href=
+ "{@docRoot}training/managing-audio/audio-focus.html">here</a>.
+</p>
+
+<h3 id="c_determine_the_device_your_instance_is_running_on">Determine the
+device your instance is running on</h3>
+
+<p>
+ <em>In this case, you need a unique identifier to determine which device the
+ instance of your app is running on.</em>
+</p>
+
+<p>
+ Applications may have device-specific preferences or messaging (e.g., saving
+ a device-specific playlist for a user in the cloud so that they can have a
+ different playlist for their car and at home). A common solution is to
+ leverage device identifiers such as <code>Device IMEI</code>, but this
+ requires the <code>Device ID and call information</code>
+ permission group (<code>PHONE</code> in M+). It also uses an identifier which
+ cannot be reset and is shared across all apps.
+</p>
+
+<p>
+ There are two alternatives to using these types of identifiers:
+</p>
+
+<ol>
+ <li> Use the <code>com.google.android.gms.iid</code> InstanceID API.
+ <code>getInstance(Context context).getID()<strong></code> </strong>will return a
+ unique device identifier for your application instance. The
+result is an app instance scoped identifier that can be used as a key when
+storing information about the app and is reset if the user re-installs the app.
+ <li> Create your own identifier that’s scoped to your app’s storage using basic
+ system functions like <a
+ href="{@docRoot}reference/java/util/UUID.html#randomUUID()"><code>randomUUID()</code></a>.</li>
+</ol>
+
+<h3 id="d_create_a_unique_identifier_for_advertising_or_user_analytics">Create a unique
+identifier for advertising or user analytics</h3>
+
+<p>
+ <em>In this case, you need a unique identifier for building a profile for
+ users who are not signed in to your app (e.g., for ads targeting or measuring
+ conversions).</em>
+</p>
+
+<p>
+ Building a profile for advertising and user analytics sometimes requires an
+ identifier that is shared across other applications. Common solutions for
+ this involve leveraging device identifiers such as <code>Device IMEI</code>,
+ which requires the <code>Device ID</code> <code>and call information</code>
+ permission group (<code>PHONE</code> in API level 23+) and cannot be reset by
+ the user. In any of these cases, in addition to using a non-resettable
+ identifier and requesting a permission that might seem unusual to users, you
+ will also be in violation of the <a href=
+ "https://play.google.com/about/developer-content-policy.html">Play Developer
+ Program Policies</a>.
+</p>
+
+<p>
+ Unfortunately, in these cases using the
+ <code>com.google.android.gms.iid</code> InstanceID API or system functions to
+ create an app-scoped ID are not appropriate solutions because the ID may need
+ to be shared across apps. An alternative solution is to use the
+ <code>Advertising Identifier</code> available from the <code><a href=
+ "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html">
+ AdvertisingIdClient.Info</a></code> class via the <code>getId()</code>
+ method. You can create an <code>AdvertisingIdClient.Info</code> object using
+ the <code>getAdvertisingIdInfo(Context)</code> method and call the
+ <code>getId()</code> method to use the identifier. <em><strong>Note that this
+ method is blocking</strong></em>, so you should not call it from the main
+ thread; a detailed explanation of this method is available <a href=
+ "{@docRoot}google/play-services/id.html">here</a>.
+</p>
+
+<h2 id="know_the_libraries_you're_working_with">Know the Libraries You're
+Working With</h2>
+
+<p>
+ Sometimes permissions are required by the libraries you use in your app. For
+ example, ads and analytics libraries may require access to the
+ <code>Location</code> or <code>Identity</code> permissions groups to
+ implement the required functionality. But from the user’s point of view, the
+ permission request comes from your app, not the library.
+</p>
+
+<p>
+ Just as users select apps that use fewer permissions for the same
+ functionality, developers should review their libraries and select
+ third-party SDKs that are not using unnecessary permissions. For example, try
+ to avoid libraries that require the <code>Identity</code> permission group
+ unless there is a clear user-facing reason why the app needs those permissions.
+ In particular, for libraries that provide location functionality, make sure you
+ are not required to request the <code>FINE_LOCATION</code> permission unless
+ you are using location-based targeting functionality.
+</p>
+
+<h2 id="be_transparent">Be Transparent</h2>
+
+<p>You should inform your users about what you’re accessing and why. Research shows
+that users are much less uncomfortable with permissions requests if they know
+why the app needs them. A user study showed that:</p>
+
+<div style="padding:.5em 2em;">
+<div style="border-left:4px solid #999;padding:0 1em;font-style:italic;">
+<p>...a user’s willingness to grant a given permission to a given mobile app is
+strongly influenced by the purpose associated with such a permission. For
+instance a user’s willingness to grant access to his or her location will vary
+based on whether the request is required to support the app’s core
+functionality or whether it is to share this information with an advertising
+network or an analytics company.<span
+style="font-size:.8em;color:#777"><sup><em><a
+ href="#references" style="color:#777;padding-left:.1em;">1</a></em></sup></span></p>
+</div>
+</div>
+
+<p>
+ Based on his group’s research, Professor Jason Hong from CMU concluded that,
+ in general:
+</p>
+
+<div style="padding:.5em 2em;">
+<div style="border-left:4px solid #999;padding:0 1em;font-style:italic;">
+<p>...when people know why an app is using something as sensitive as their location —
+for example, for targeted advertising — it makes them more comfortable than
+when simply told an app is using their location.<span
+style="font-size:.8em;color:#777"><sup><em><a
+ href="#references" style="color:#777;padding-left:.1em;">1</a></em></sup></span></p>
+</div>
+</div>
+
+<p>
+ As a result, if you’re only using a fraction of the API calls that fall under
+ a permission group, it helps to explicitly list which of those permissions
+ you're using, and why. For example:
+</p>
+
+<ul>
+ <li> If you’re only using coarse location, let the user know this in your app
+ description or in help articles about your app. </li>
+ <li> If you need access to SMS messages to receive authentication codes that
+ protect the user from fraud, let the user know this in your app description
+ and/or the first time you access the data.</li>
+</ul>
+
+<p>
+ Under certain conditions, it's also advantageous to let users know about
+ sensitive data accesses in real-time. For example, if you’re accessing the
+ camera or microphone, it’s usually a good idea to let the user know with a
+ notification icon somewhere in your app, or in the notification tray (if the
+ application is running in the background), so it doesn't seem like you're
+ collecting data surreptitiously.
+</p>
+
+<p>
+ Ultimately, if you need to request a permission to make something in your app
+ work, but the reason is not clear to the user, find a way to let the user
+ know why you need the most sensitive permissions.
+</p>
+
+<h2 id="references">References</h2>
+
+<p>
+ [1] <em>Modeling Users’ Mobile App Privacy Preferences: Restoring Usability
+ in a Sea of Permission Settings</em>, by J. Lin B. Liu, N. Sadeh and J. Hong.
+ In Proceedings of SOUPS 2014.
+</p>
diff --git a/docs/html/training/auto/audio/index.jd b/docs/html/training/auto/audio/index.jd
index d183f11..75974e4 100644
--- a/docs/html/training/auto/audio/index.jd
+++ b/docs/html/training/auto/audio/index.jd
@@ -210,6 +210,34 @@
<p class="note"><strong>Note:</strong> The icon you provide should have transparency enabled, so the
icon's background gets filled in with the app's primary color.</p>
+<h2 id=isconnected">Determine if Your App is Connected</h2>
+<p>
+It is possible to determine if your app is selected as the current media app.</p>
+<p>
+Android Auto broadcasts an intent with <code>com.google.android.gms.car.media.
+STATUS</code> action when a user connects or disconnects from a media app. The broadcast intent is
+scoped to the package name of the media app selected. You can register a broadcast receiver in your
+app, preferably in your <a href="{@docRoot}reference/android/service/media/MediaBrowserService.html">
+MediaBrowserService</a> implementation and listen for this intent
+and adjust advertisements, metadata, and UI buttons in your app to operate safely in a vehicle.</p>
+
+<p>The broadcasted intent has a String extra <code>media_connection_status</code>, that
+contains either <code>media_connected</code> or <code>media_disconnected</code> string that represents
+ the current connection status. </p>
+
+<pre>
+IntentFilter filter = new IntentFilter("com.google.android.gms.car.media.STATUS");
+BroadcastReceiver receiver = new BroadcastReceiver() {
+ ...
+ public void onReceive(Context context, Intent intent) {
+ String status = intent.getStringExtra("media_connection_status");
+ boolean isConnectedToCar = "media_connected".equals(status);
+ // adjust settings based on the connection status
+ }
+};
+registerReceiver(receiver, filter);
+</pre>
+
<h2 id="implement_browser">Build a Browser Service</h2>
diff --git a/docs/html/training/best-permissions-ids.jd b/docs/html/training/best-permissions-ids.jd
new file mode 100644
index 0000000..e98c095
--- /dev/null
+++ b/docs/html/training/best-permissions-ids.jd
@@ -0,0 +1,9 @@
+page.title=Best Practices for Permissions and Identifiers
+page.trainingcourse=true
+
+@jd:body
+
+
+
+<p>The articles below highlight key guidelines for using permissions
+and identifiers properly in your apps.</p>
\ No newline at end of file
diff --git a/docs/html/training/contacts-provider/retrieve-names.jd b/docs/html/training/contacts-provider/retrieve-names.jd
old mode 100644
new mode 100755
index d97b81b..49d6e95
--- a/docs/html/training/contacts-provider/retrieve-names.jd
+++ b/docs/html/training/contacts-provider/retrieve-names.jd
@@ -230,7 +230,7 @@
{@link android.provider.ContactsContract.Contacts#DISPLAY_NAME_PRIMARY
Contacts.DISPLAY_NAME_PRIMARY} requires Android 3.0 (API version 11) or later, setting your
app's <code>minSdkVersion</code> to 10 or below generates an Android Lint warning in
- Eclipse with ADK. To turn off this warning, add the annotation
+ Android Studio. To turn off this warning, add the annotation
<code>@SuppressLint("InlinedApi")</code> before the definition of <code>FROM_COLUMNS</code>.
</p>
<h3 id="InitializeFragment">Initialize the Fragment</h3>
diff --git a/docs/html/training/in-app-billing/preparing-iab-app.jd b/docs/html/training/in-app-billing/preparing-iab-app.jd
old mode 100644
new mode 100755
index ca33008..2c6e9a0
--- a/docs/html/training/in-app-billing/preparing-iab-app.jd
+++ b/docs/html/training/in-app-billing/preparing-iab-app.jd
@@ -84,9 +84,9 @@
<p>To add the In-app Billing Version 3 library to your new In-app Billing project:</p>
<ol>
<li>Copy the {@code TrivialDrive} sample files into your Android project.</li>
-<li>Modify the package name in the files you copied to use the package name for your project. In Eclipse, you can use this shortcut: right-click the package name, then select <strong>Refactor</strong> > <strong>Rename</strong>.</li>
+<li>Modify the package name in the files you copied to use the package name for your project. In Android Studio, you can use this shortcut: right-click the package name, then select <strong>Refactor</strong> > <strong>Rename</strong>.</li>
<li>Open the {@code AndroidManifest.xml} file and update the package attribute value to use the package name for your project.</li>
-<li>Fix import statements as needed so that your project compiles correctly. In Eclipse, you can use this shortcut: press <strong>Ctrl+Shift+O</strong> in each file showing errors.</li>
+<li>Fix import statements as needed so that your project compiles correctly. In Android Studio, you can use this shortcut: press <strong>Ctrl+Shift+O</strong> in each file showing errors.</li>
<li>Modify the sample to create your own application. Remember to copy the Base64 public license key for your application from the Developer Console over to your {@code MainActivity.java}.</li>
</ol>
@@ -98,7 +98,6 @@
<li>In Android Studio: Create a directory named {@code aidl} under {@code src/main}, add a new
package {@code com.android.vending.billing} in this directory, and import the
{@code IInAppBillingService.aidl} file into this package.</li>
- <li>In Eclipse: Import the {@code IInAppBillingService.aidl} file into your {@code /src} directory.</li>
<li>In other dev environments: Create the following directory {@code /src/com/android/vending/billing} and copy the {@code IInAppBillingService.aidl} file into this directory.</li>
</ul>
</li>
diff --git a/docs/html/training/material/animations.jd b/docs/html/training/material/animations.jd
index 3375af6..a29354f 100644
--- a/docs/html/training/material/animations.jd
+++ b/docs/html/training/material/animations.jd
@@ -85,7 +85,7 @@
int cy = myView.getHeight() / 2;
// get the final radius for the clipping circle
-int finalRadius = Math.max(myView.getWidth(), myView.getHeight());
+float finalRadius = (float) Math.hypot(cx, cy);
// create the animator for this view (the start radius is zero)
Animator anim =
@@ -107,7 +107,7 @@
int cy = myView.getHeight() / 2;
// get the initial radius for the clipping circle
-int initialRadius = myView.getWidth();
+float initialRadius = (float) Math.hypot(cx, cy);
// create the animation (the final radius is zero)
Animator anim =
diff --git a/docs/html/training/monitoring-device-state/doze-standby.jd b/docs/html/training/monitoring-device-state/doze-standby.jd
index 50c3d11..8038e38 100644
--- a/docs/html/training/monitoring-device-state/doze-standby.jd
+++ b/docs/html/training/monitoring-device-state/doze-standby.jd
@@ -32,7 +32,7 @@
<li><a href="#testing_your_app_with_app_standby">Testing your app with App Standby</a></li>
</ol>
</li>
- <li><a href="#whitelisting-cases">Example Use Cases for Whitelisting</a></li>
+ <li><a href="#whitelisting-cases">Acceptable Use Cases for Whitelisting</a></li>
</ol>
</div>
</div>
@@ -422,7 +422,7 @@
</ol>
-<h2 id="whitelisting-cases">Example Use Cases for Whitelisting</h2>
+<h2 id="whitelisting-cases">Acceptable Use Cases for Whitelisting</h2>
<p>The table below highlights the acceptable use cases for requesting or being on
the Battery Optimizations exceptions whitelist. In general, your app should not be on the
@@ -456,13 +456,22 @@
<tr>
<td rowspan="1">Instant messaging, chat, or calling app;
- enterprise VOIP apps</td>
+ enterprise VOIP apps.</td>
<td>No, can not use GCM because of technical dependency on another messaging
service or Doze and App Standby break the core function of the app.</td>
<td style="color:green">Acceptable</td>
<td></td>
</tr>
+ <tr>
+ <td rowspan="1">Task automation app</td>
+ <td>App's core function is scheduling automated actions, such as for instant
+ messaging, voice calling, new photo management, or location actions.</td>
+ <td>If applicable.</td>
+ <td style="color:green">Acceptable</td>
+ <td></td>
+ </tr>
+
</table>
diff --git a/docs/html/training/testing/index.jd b/docs/html/training/testing/index.jd
new file mode 100644
index 0000000..d6405c8
--- /dev/null
+++ b/docs/html/training/testing/index.jd
@@ -0,0 +1,72 @@
+page.title=Best Practices for Testing
+page.article=true
+page.image=images/testing/hwtest_junit_success.png
+
+meta.tags="testing"
+page.tags="testing"
+
+page.metaDescription=Starting point for testing Android apps, with guidelines, information, and examples.
+
+@jd:body
+
+<img src="/images/testing/testing-icon.png"
+style="float:right; margin:0 0 20px 30px" width="245" height="229" />
+
+<p>
+ Testing your app is an integral part of the app development process. Testing allows you to verify
+ the correctness, functional behavior, and usability of your app before it is released publicly.
+</p>
+<br>
+<br>
+
+<h2 id="start">Get Started</h2>
+
+<p>
+ Learn the basics of testing your app, with information about building and running your tests with
+ Android Studio:
+</p>
+
+<div class="resource-widget resource-flow-layout col-12"
+ data-query="collection:training/testing/overview"
+ data-cardSizes="6x3"
+ data-maxresults="3">
+</div>
+
+
+<h2 id="tools">Testing Tools and APIs</h2>
+
+<p>
+ Learn about the tools provided by the Android platform that help you test every aspect of your app
+ at every level:
+</p>
+
+<div class="resource-widget resource-flow-layout landing col-12"
+ data-query="collection:training/testing/tools"
+ data-cardSizes="15x3, 9x2, 9x2, 9x2, 9x2"
+ data-maxResults="5">
+</div>
+
+
+<h2 id="techniques">App Testing Techniques</h2>
+
+<p>
+ Learn techniques for testing your apps:
+</p>
+
+<div class="resource-widget resource-flow-layout landing col-12"
+ data-query="collection:training/testing/techniques"
+ data-cardSizes="6x3
+ data-maxResults="3">
+</div>
+
+<h2 id="resources">Other Resources</h2>
+
+<p>
+ More resources for app testing:
+</p>
+
+<div class="resource-widget resource-flow-layout landing col-12"
+ data-query="collection:training/testing/resources"
+ data-cardSizes="9x3"
+ data-maxResults="6">
+</div>
\ No newline at end of file
diff --git a/docs/html/training/testing/integration-testing/content-provider-testing.jd b/docs/html/training/testing/integration-testing/content-provider-testing.jd
new file mode 100644
index 0000000..75869d9
--- /dev/null
+++ b/docs/html/training/testing/integration-testing/content-provider-testing.jd
@@ -0,0 +1,174 @@
+page.title=Testing Your Content Provider
+page.tags=testing, content provider
+trainingnavtop=true
+
+@jd:body
+
+<!-- This is the training bar -->
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>Dependencies and Prerequisites</h2>
+
+ <ul>
+ <li>Android 2.2 (API level 8) or higher</li>
+ <li><a href="{@docRoot}tools/testing-support-library/index.html">
+ Android Testing Support Library</a></li>
+ <li><a href="{@docRoot}tools/studio/index.html">Android Studio 1.4.1 or higher</a>.</li>
+ </ul>
+
+ <h2>This lesson teaches you to</h2>
+
+ <ol>
+ <li><a href="#build">Create Integration Tests for Content Providers</a></li>
+ <li><a href="#WhatToTest">What to Test</a></li>
+ </ol>
+
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
+ </li>
+ </ul>
+</div>
+</div>
+
+<p>
+ If you are implementing a <a href="{@docRoot}guide/topics/providers/content-providers.html">
+ content provider</a> to store and retrieve data or to make data
+ accessible to other apps, you should test your provider to ensure that it doesn't behave in an
+ unexpected way. This lesson describes how to test public content providers, and is also
+ applicable to providers that you keep private to your own app.
+</p>
+<h2 id="build">Create Integration Tests for Content Providers</h2>
+<p>
+In Android, apps view content providers as data APIs that provide
+tables of data, with their internals hidden from view. A content provider may have many
+public constants, but it usually has few if any public methods and no public variables.
+For this reason, you should write your tests based only on the provider's public members.
+A content provider that is designed like this is offering a contract between itself and its users.
+</p>
+<p>
+Content providers let you access actual user data, so it's important to ensure
+that you test the content provider in an isolated testing environment. This approach allows you to
+only run against data dependencies set explicitly in the test case. It also means that your tests
+do not modify actual user data. For example, you should avoid writing a test that fails because
+there was data left over from a previous test. Similarly, your test should avoid adding or deleting
+actual contact information in a provider.
+</p>
+
+<p>
+To test your content provider in isolation, use the {@link android.test.ProviderTestCase2} class.
+This class allows you to use Android mock object classes such as {@link android.test.IsolatedContext}
+and {@link android.test.mock.MockContentResolver} to access file and database information without
+affecting the actual user data.
+</p>
+
+<p>Your integration test should be written as a JUnit 4 test class. To learn more about creating
+JUnit 4 test classes and using JUnit 4 assertions, see
+<a href="{@docRoot}training/testing/unit-testing/local-unit-tests.html#build">
+Create a Local Unit Test Class</a>.</p>
+
+<p>To create an integration test for your content provider, you must perform these steps:</p>
+<ul>
+ <li>Create your test class as a subclass of {@link android.test.ProviderTestCase2}.</li>
+ <li>Add the
+{@code @RunWith(AndroidJUnit4.class)} annotation at the beginning of your test class
+definition.</li>
+ <li>Specify the
+<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+{@code AndroidJUnitRunner}</a> class that the
+<a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>
+provides as your default test runner. This step is described in more detail in
+<a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests">
+Getting Started with Testing</a>.</li>
+ <li>Set the {@link android.content.Context} object from the
+<a href="{@docRoot}reference/android/support/test/InstrumentationRegistry.html">
+{@code InstrumentationRegistry}</a> class. See the snippet below for an example.
+ <pre>
+@Override
+protected void setUp() throws Exception {
+ setContext(InstrumentationRegistry.getTargetContext());
+ super.setUp();
+}</pre>
+ </li>
+</ul>
+
+<h3 id="ProviderTestCase2">How ProviderTestCase2 works</h3>
+<p>
+ You test a provider with a subclass of {@link android.test.ProviderTestCase2}. This base class
+ extends {@link android.test.AndroidTestCase}, so it provides the JUnit testing framework as well
+ as Android-specific methods for testing application permissions. The most important
+ feature of this class is its initialization, which creates the isolated test environment.
+</p>
+<p>
+ The initialization is done in the constructor for {@link android.test.ProviderTestCase2}, which
+ subclasses call in their own constructors. The {@link android.test.ProviderTestCase2}
+ constructor creates an {@link android.test.IsolatedContext} object that allows file and
+ database operations but stubs out other interactions with the Android system.
+ The file and database operations themselves take place in a directory that is local to the
+ device or emulator and has a special prefix.
+</p>
+<p>
+ The constructor then creates a {@link android.test.mock.MockContentResolver} to use as the
+ resolver for the test.
+</p>
+<p>
+ Lastly, the constructor creates an instance of the provider under test. This is a normal
+ {@link android.content.ContentProvider} object, but it takes all of its environment information
+ from the {@link android.test.IsolatedContext}, so it is restricted to
+ working in the isolated test environment. All of the tests done in the test case class run
+ against this isolated object.
+</p>
+
+<p>
+You run integration tests for content providers the same way as instrumented unit tests. To run the
+integration test for your content provider, follow the steps described in <a
+href="{@docRoot}training/testing/unit-testing/instrumented-unit-tests.html#run">
+Run Instrumented Unit Tests</a>.
+</p>
+
+<h2 id="WhatToTest">What to Test</h2>
+<p>
+Here are some specific guidelines for testing content providers.
+</p>
+<ul>
+ <li>
+ Test with resolver methods: Even though you can instantiate a provider object in
+ {@link android.test.ProviderTestCase2}, you should always test with a resolver object
+ using the appropriate URI. Doing so ensures that you are testing the provider by performing
+ the same interaction that a regular application would use.
+ </li>
+ <li>
+ Test a public provider as a contract: If you intend your provider to be public and
+ available to other applications, you should test it as a contract. Some examples of how to
+ do so are as follows:
+ <ul>
+ <li>
+ Test with constants that your provider publicly exposes. For
+ example, look for constants that refer to column names in one of the provider's
+ data tables. These should always be constants publicly defined by the provider.
+ </li>
+ <li>
+ Test all the URIs that your provider offers. Your provider may offer several URIs,
+ each one referring to a different aspect of the data.
+ </li>
+ <li>
+ Test invalid URIs: Your unit tests should deliberately call the provider with an
+ invalid URI, and look for errors. A good provider design is to throw an
+ {@code IllegalArgumentException} for invalid URIs.
+
+ </li>
+ </ul>
+ </li>
+ <li>
+ Test the standard provider interactions: Most providers offer six access methods:
+ {@code query()}, {@code insert()}, {@code delete()}, {@code update()},
+ {@code getType()}, and {@code onCreate()}. Your tests should verify that all
+ of these methods work. These methods are described in more detail in the topic
+ <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>.
+ </li>
+ <li>
+ Test business logic: If the content provider implements business logic, you should test it.
+ Business logic includes handling of invalid values, financial or arithmetic calculations,
+ elimination or combining of duplicates.
+ </li>
+</ul>
\ No newline at end of file
diff --git a/docs/html/training/testing/integration-testing/index.jd b/docs/html/training/testing/integration-testing/index.jd
new file mode 100644
index 0000000..d7ce899
--- /dev/null
+++ b/docs/html/training/testing/integration-testing/index.jd
@@ -0,0 +1,55 @@
+page.title=Testing App Component Integrations
+page.tags=testing,integration
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>
+ You should also read
+ </h2>
+ <ul>
+ <li>
+ <a href="{@docRoot}tools/testing-support-library/index.html">Testing Support Library</a>
+ </li>
+ </ul>
+</div>
+</div>
+
+<p>
+If your app uses components that users do not directly interact with, such as
+a <a href="{@docRoot}guide/components/services.html">Service</a> or
+<a href="{@docRoot}guide/topics/providers/content-providers.html">Content Provider</a>, you
+should validate that these components behave in a correct way with your app.</p>
+<p>When developing such components, you should get into the habit of writing
+<em>integration tests</em> in order to validate the component's behavior when your app runs on a
+device or an emulator.</p>
+
+<p class="note"><strong>Note:</strong> Android does not provide a separate test case class for
+{@link android.content.BroadcastReceiver}. To verify that a
+{@link android.content.BroadcastReceiver} responds correctly, you can test the component that sends
+it an {@link android.content.Intent} object. Alternatively, you can create an instance of your
+{@link android.content.BroadcastReceiver} by calling
+<a href="{@docRoot}reference/android/support/test/InstrumentationRegistry.html#getContext()">
+{@code InstrumentationRegistry.getTargetContext()}</a>, then call the
+{@link android.content.BroadcastReceiver} method that you want to test (usually, this is
+the
+{@link android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
+onReceive()} method).</p>
+
+<p>This class teaches you to build automated integration tests using the testing APIs and tools
+that the Android platform provides.</p>
+<h2>Lessons</h2>
+<dl>
+ <dt><strong><a href="service-testing.html">
+Testing Your Service</a></strong></dt>
+ <dd>Learn how to build integration tests to verify that a service works correctly with your
+ app.</dd>
+ <dt><strong><a href="content-provider-testing.html">
+Testing Your Content Provider</a></strong></dt>
+ <dd>Learn how to build integration tests to verify that a content provider works correctly with
+ your app.</dd>
+</dl>
\ No newline at end of file
diff --git a/docs/html/training/testing/integration-testing/service-testing.jd b/docs/html/training/testing/integration-testing/service-testing.jd
new file mode 100644
index 0000000..7b420ac
--- /dev/null
+++ b/docs/html/training/testing/integration-testing/service-testing.jd
@@ -0,0 +1,140 @@
+page.title=Testing Your Service
+page.tags=testing, service
+trainingnavtop=true
+
+@jd:body
+
+<!-- This is the training bar -->
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>Dependencies and Prerequisites</h2>
+
+ <ul>
+ <li>Android 2.2 (API level 8) or higher</li>
+ <li><a href="{@docRoot}tools/testing-support-library/index.html">
+ Android Testing Support Library</a></li>
+ <li><a href="{@docRoot}tools/studio/index.html">Android Studio 1.4.1 or higher</a>.</li>
+ </ul>
+
+ <h2>This lesson teaches you to</h2>
+
+ <ol>
+ <li><a href="#setup">Set Up Your Testing Environment</a></li>
+ <li><a href="#build">Create an Integrated Test for Services</a></li>
+ <li><a href="#run">Run Integration Tests for Services</a></li>
+ </ol>
+
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/components/services.html">Services</a></li>
+ </ul>
+
+ <h2>Try it out</h2>
+
+ <ul>
+ <li>
+<a href="https://github.com/googlesamples/android-testing/tree/master/integration/ServiceTestRuleSample"
+class="external-link">Service Test Code Samples</a></li>
+ </ul>
+</div>
+</div>
+
+<p>
+If you are implementing a local {@link android.app.Service} as a component of
+your app, you should test the {@link android.app.Service} to ensure that it doesn't behave in an
+unexpected way. You can create
+<a href="{@docRoot}training/testing/unit-testing/instrumented-unit-tests.html">
+instrumented unit tests</a> to verify that the behavior in the {@link android.app.Service}
+is correct; for example, the service stores and returns valid data values and performs
+data operations correctly.
+</p>
+
+<p>
+The <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>
+provides an API for testing your {@link android.app.Service} objects in isolation.
+The
+<a href="{@docRoot}reference/android/support/test/rule/ServiceTestRule.html">ServiceTestRule</a>
+class is a JUnit 4 rule that starts your service before your unit test methods
+run, and shuts down the service after tests complete. By using this test rule, you ensure that the
+connection to the service is always established before your test method runs. To
+learn more about JUnit 4 rules, see the <a href="https://github.com/junit-team/junit/wiki/Rules"
+class="external-link">JUnit documentation</a>.
+</p>
+
+<p style="note">
+<strong>Note</strong>: The
+<a href="{@docRoot}reference/android/support/test/rule/ServiceTestRule.html">ServiceTestRule</a>
+class does not support testing of {@link android.app.IntentService} objects.
+If you need to test a {@link android.app.IntentService} object, you should encapsulate the logic
+in a separate class and create a corresponding unit test instead.
+</p>
+
+<h2 id="setup">Set Up Your Testing Environment</h2>
+<p>Before building your integration test for the service, make sure to configure your project for
+ instrumented tests, as described in
+<a href="{@docRoot}training/testing/start/index.html#config-instrumented-tests">
+Getting Started with Testing</a>.</p>
+
+<h2 id="build">Create an Integration Test for Services</h2>
+<p>Your integration test should be written as a JUnit 4 test class. To learn more about creating
+JUnit 4 test classes and using JUnit 4 assertion methods, see
+<a href="{@docRoot}training/testing/unit-testing/instrumented-unit-tests.html#build">
+Create an Instrumented Unit Test Class</a>.</p>
+
+<p>To create an integration test for your service, add the {@code @RunWith(AndroidJUnit4.class)}
+annotation at the beginning of your test class definition. You also need to specify the
+<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+{@code AndroidJUnitRunner}</a> class that the Android Testing Support Library provides as your
+default test runner. This step is described in more detail in
+<a href="{@docRoot}training/testing/unit-testing/instrumented-unit-tests.html#run">
+Run Instrumented Unit Tests</a>.</p>
+
+<p>Next, create a
+<a href="{@docRoot}reference/android/support/test/rule/ServiceTestRule.html">ServiceTestRule</a>
+instance in your test by using the {@code @Rule} annotation.</p>
+
+<pre>
+@Rule
+public final ServiceTestRule mServiceRule = new ServiceTestRule();
+</pre>
+
+<p>The following example shows how you might implement an integration test for a service.
+The test method {@code testWithBoundService} verifies that the app binds successfully to a
+local service and that the service interface behaves correctly.</p>
+
+<pre>
+@Test
+public void testWithBoundService() throws TimeoutException {
+ // Create the service Intent.
+ Intent serviceIntent =
+ new Intent(InstrumentationRegistry.getTargetContext(),
+ LocalService.class);
+
+ // Data can be passed to the service via the Intent.
+ serviceIntent.putExtra(LocalService.SEED_KEY, 42L);
+
+ // Bind the service and grab a reference to the binder.
+ IBinder binder = mServiceRule.bindService(serviceIntent);
+
+ // Get the reference to the service, or you can call
+ // public methods on the binder directly.
+ LocalService service =
+ ((LocalService.LocalBinder) binder).getService();
+
+ // Verify that the service is working correctly.
+ assertThat(service.getRandomInt(), is(any(Integer.class)));
+}
+</pre>
+
+<h2 id="run">Run Integration Tests for Services</h2>
+<p>
+You can run integration tests from <a href="{@docRoot}sdk/index.html">Android Studio</a> or
+from the command-line. Make sure to specify
+<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+ {@code AndroidJUnitRunner}</a> as the default instrumentation runner in your project.
+</p>
+<p>
+To run the integration test for your service, follow the steps for running instrumented tests
+described in <a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests">
+Getting Started with Testing</a>.
+</p>
diff --git a/docs/html/training/testing/performance.jd b/docs/html/training/testing/performance.jd
index 2b968b3..8592c0f 100644
--- a/docs/html/training/testing/performance.jd
+++ b/docs/html/training/testing/performance.jd
@@ -28,6 +28,7 @@
</ul>
</li>
</ol>
+
</div>
</div>
diff --git a/docs/html/training/testing/start/index.jd b/docs/html/training/testing/start/index.jd
new file mode 100644
index 0000000..a4b4aea
--- /dev/null
+++ b/docs/html/training/testing/start/index.jd
@@ -0,0 +1,252 @@
+page.title=Getting Started with Testing
+page.tags="testing"
+page.article=true
+page.image=images/tools/studio-main-screen.png
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
+<h2>Dependencies and prerequisites</h2>
+<ul>
+ <li><a href="{@docRoot}tools/studio/index.html">Android Studio (latest version)</a>.</li>
+</ul>
+
+<h2>This lesson teaches you to</h2>
+<ol>
+<li><a href="#setup">Set Up Your Testing Environment</a></li>
+<li><a href="#build">Build and Run Your Tests</a></li>
+</ol>
+
+<h2>You Should Also Read</h2>
+<ul>
+<li><a href="{@docRoot}tools/testing/testing_android.html">Testing Concepts</a></li>
+<li><a href="https://github.com/googlesamples/android-testing"
+ class="external-link">Android Testing Samples</a></li>
+<li><a href="{@docRoot}about/dashboards/index.html">Android Dashboards</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>You should be writing and running tests as part of your Android app development cycle.
+Well-written tests can help you catch bugs early in development and give you confidence in your
+code.</p>
+
+<p>To verify specific behavior in your app, and to check for consistency across different Android
+devices, you can write a <a href="//en.wikipedia.org/wiki/Test_case"
+class="external-link">test case</a>. This lesson teaches you how to build a test case using the
+JUnit 4 framework and the testing APIs and tools provided by Google, and how to run your
+tests.</p>
+
+<h2 id="setup">Set Up Your Testing Environment</h2>
+
+<p>Before you start writing and running your tests, you must set up your test
+development environment. Android Studio provides an integrated development environment for you to
+create, build, and run Android app test cases from a graphical user interface (GUI).</p>
+
+<p>You must first download the prerequisite Android development tools before proceeding:
+<ul>
+<li><a href="{@docRoot}sdk/index.html">Android Studio</a> (latest version).</li>
+<li>The latest Android Support Repository using the
+ <a href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a>. </li>
+</ul>
+
+<p>Based on the type of test you want to create, configure the test code source location and the
+ project dependencies in Android Studio as described in the following sections.</p>
+
+<h3 id="config-local-tests">Configure Your Project for Local Unit Tests</h3>
+<p><em>Local unit tests</em> are tests that run on your local machine, without needing access to the
+Android framework or an Android device. To learn how to develop local units tests, see
+<a href="{@docRoot}training/testing/unit-testing/local-unit-tests.html">
+Building Local Unit Tests</a>.</p>
+<p>In your Android Studio project, you must store the source files for local unit tests under a
+specific source directory ({@code src/test/java}). This feature improves your project organization
+by letting you group your unit tests together into a single source set.</p>
+<p>As with production code, you can create local unit tests for a
+<a href="http://developer.android.com/tools/building/configuring-gradle.html#workBuildVariants"
+class="external-link">specific flavor or build type</a>. Keep your unit tests in a test
+source tree location that corresponds to your production source tree, such as:</p>
+
+<table>
+<tr>
+<th>Path to Production Class</th>
+<th>Path to Local Unit Test Class</th>
+</tr>
+<tr>
+<td>{@code src/main/java/Foo.java}</td>
+<td>{@code src/test/java/FooTest.java}</td>
+</tr>
+<tr>
+<td>{@code src/debug/java/Foo.java}</td>
+<td>{@code src/testDebug/java/FooTest.java}</td>
+</tr>
+<tr>
+<td>{@code src/myFlavor/java/Foo.java}</td>
+<td>{@code src/testMyFlavor/java/FooTest.java}</td>
+</tr>
+</table>
+
+<p>You'll need to configure the testing dependencies for your project to use the
+ standard APIs provided by the JUnit 4 framework. To simplify your local unit test development,
+ we recommend that you include the <a href="https://github.com/mockito/mockito"
+ class="external-link">Mockito</a> library if your test needs to interact with Android
+ dependencies. To learn more about using mock objects in your local unit tests, see
+<a href="{@docRoot}training/testing/unit-testing/local-unit-tests.html#mocking-dependencies">
+ Mocking Android dependencies</a>.</p>
+<p>In the {@code build.gradle} file of your Android app module, specify your dependencies like
+this:</p>
+
+<pre>
+dependencies {
+ // Required -- JUnit 4 framework
+ testCompile 'junit:junit:4.12'
+ // Optional -- Mockito framework
+ testCompile 'org.mockito:mockito-core:1.10.19'
+}
+</pre>
+
+<h3 id="config-instrumented-tests">Configure Your Project for Instrumented Tests</h3>
+<p><em>Instrumented tests</em> are tests that run on an Android device or emulator. These tests
+have access to {@link android.app.Instrumentation} information, such as the
+{@link android.content.Context} for the app under test. Instrumented tests can be used for unit,
+user interface (UI), or app component integration testing. To learn how to develop instrumented
+tests for your specific needs, see these additional topics:
+<ul>
+<li><a href="{@docRoot}training/testing/unit-testing/instrumented-unit-tests.html">
+ Building Instrumented Unit Tests</a> - Build more complex unit tests that have Android
+ dependencies which cannot be easily filled by using mock objects.</li>
+<li><a href="{@docRoot}training/testing/ui-testing/index.html">
+ Automating User Interface Tests</a> - Create tests to verify that the user interface behaves
+ correctly for user interactions within a single app or for interactions across multiple apps.</li>
+<li><a href="{@docRoot}training/testing/integration-testing/index.html">
+ Testing App Component Integrations</a> - Verify the behavior of components that users do not
+directly interact with, such as a <a href="{@docRoot}guide/components/services.html">Service</a> or
+a <a href="guide/topics/providers/content-providers.html">Content Provider</a>.</li>
+</ul>
+</p>
+<p>
+In your Android Studio project, you must place the source code for your instrumentated tests under
+a specific directory (<code>src/androidTest/java</code>).
+</p>
+<p>
+Download the Android Testing Support Library, which provides APIs that allow you to quickly build and
+run instrumented test code for your apps. The Testing Support Library includes a JUnit 4 test runner
+(<a href="{@docRoot}tools/testing-support-library/index.html#AndroidJUnitRunner">AndroidJUnitRunner
+</a>) and APIs for functional UI tests
+(<a href="{@docRoot}tools/testing-support-library/index.html#Espresso">Espresso</a> and
+<a href="{@docRoot}tools/testing-support-library/index.html#UIAutomator">UI Automator</a>). To
+learn how to install the library, see
+<a href="{@docRoot}tools/testing-support-library/index.html#setup">Testing Support Library Setup</a>.
+</p>
+<p>You'll need to configure the Android testing dependencies for your project to use the test runner
+and the rules APIs provided by the Testing Support Library. To simplify your test development,
+we also recommend that you include the <a href="https://github.com/hamcrest"
+class="external-link">Hamcrest</a> library, which lets you create more flexible assertions using the
+Hamcrest matcher APIs.</p>
+<p>In the {@code build.gradle} file of your Android app module, specify your dependencies like
+this:</p>
+<pre>
+dependencies {
+ androidTestCompile 'com.android.support:support-annotations:23.0.1'
+ androidTestCompile 'com.android.support.test:runner:0.4.1'
+ androidTestCompile 'com.android.support.test:rules:0.4.1'
+ // Optional -- Hamcrest library
+ androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
+ // Optional -- UI testing with Espresso
+ androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
+ // Optional -- UI testing with UI Automator
+ androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1'
+}
+</pre>
+
+<h2 id="build">Build and Run Your Tests</h2>
+
+<p>You can run build and run your tests in a similar way to how you run your Android apps --
+ graphically in Android Studio or from the command-line using the
+<a href="{@docRoot}tools/building/plugin-for-gradle.html">
+Android Plugin for Gradle</a>.</p>
+
+<h3 id="run-local-tests">Run Local Unit Tests</h3>
+<p>
+The Android Plugin for Gradle compiles the local unit test code located in the default directory
+({@code src/test/java}), builds a test app, and executes it locally
+using the default test runner class.
+</p>
+<p>
+To run local unit tests in your Gradle project from Android Studio:
+</p>
+<ol>
+<li>In the <strong>Project</strong> window, right click on the project and synchronize your project.
+</li>
+<li>Open the <strong>Build Variants</strong> window by clicking the left-hand tab, then change the
+test artifact to <em>Unit Tests</em>.
+</li>
+<li>In the <strong>Project</strong> window, drill down to your unit test class or method,
+then right-click and run it. To run all tests in the unit test directory, select the directory then
+right-click and press <strong>Run tests</strong>.
+</li>
+</ol>
+
+<p>Android Studio displays the results of the unit test execution in the <strong>Run</strong>
+window.</p>
+
+<p>To run local unit tests in your Gradle project from the command-line, call the {@code test} task
+command.</p>
+
+<pre>
+./gradlew test
+</pre>
+
+<p>If there are failing tests, the command will display links to HTML reports (one per build
+variant). You can find the generated HTML test result reports in the
+{@code <path_to_your_project>/app/build/reports/tests/} directory, and the corresponding XML
+files in the {@code <path_to_your_project>/app/build/test-results/} directory.</p>
+
+<h3 id="run-instrumented-tests">Run Instrumented Tests</h3>
+<p>
+The Android Plugin for Gradle compiles the instrumented test code located in the default directory
+({@code src/androidTest/java}), builds a test APK and production APK, installs both APKs on the
+connected device or emulator, and executes the tests.</p>
+
+<p>Make sure to specify
+<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+{@code AndroidJUnitRunner}</a> as the default test instrumentation runner in your project. To do
+this, add the following setting in your {@code build.gradle} file:</p>
+
+<pre>
+android {
+ defaultConfig {
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+}
+</pre>
+
+<p>To run your instrumented tests in Android Studio:</p>
+<ol>
+<li>Open the <strong>Build Variants</strong> window by clicking the left-hand tab, then set the
+test artifact to <em>Android Instrumentation Tests</em>.
+</li>
+<li>In the <strong>Project</strong> window, drill down to your instrumented test class or method,
+ then right-click and run it using the Android Test configuration. To run all tests in the
+instrumented test directory, select the directory then right-click and press
+<strong>Run tests</strong>.
+</li>
+</ol>
+
+<p>Android Studio displays the results of the instrumented test execution in the
+<strong>Run</strong> window.</p>
+
+<p>To run your instrumented tests from the command-line via Gradle, call the
+ {@code connectedAndroidTest} (or {@code cAT}) task:</p>
+
+<pre>
+./gradlew cAT
+</pre>
+
+<p>You can find the generated HTML test result reports in the
+{@code <path_to_your_project>/app/build/outputs/reports/androidTests/connected/} directory,
+and the corresponding XML files in the
+{@code <path_to_your_project>/app/build/outputs/androidTest-results/connected/} directory.</p>
\ No newline at end of file
diff --git a/docs/html/training/testing/ui-testing/espresso-testing.jd b/docs/html/training/testing/ui-testing/espresso-testing.jd
index 72689ff..45a4ceb 100644
--- a/docs/html/training/testing/ui-testing/espresso-testing.jd
+++ b/docs/html/training/testing/ui-testing/espresso-testing.jd
@@ -55,6 +55,8 @@
<a href="https://github.com/googlesamples/android-testing"
class="external-link">Espresso Code Samples</a>
</li>
+ <li><a href="https://www.code-labs.io/codelabs/android-testing/index.html?index=..%2F..%2Findex#0"
+ class="external-link">Android Testing Codelab</a></li>
</ul>
</div>
</div>
@@ -90,75 +92,51 @@
Set Up Espresso
</h2>
- <p>
- Before you begin using Espresso, you must:
- </p>
+<p>Before building your UI test with Espresso, make sure to configure your test source code
+location and project dependencies, as described in
+<a href="{@docRoot}training/testing/start/index.html#config-instrumented-tests">
+Getting Started with Testing</a>.</p>
- <ul>
- <li>
- <strong>Install the Android Testing Support Library</strong>. The Espresso API is
- located under the {@code com.android.support.test.espresso} package. These classes allow
- you to create tests that use the Espresso testing framework. To learn how to install the
- library, see <a href="{@docRoot}tools/testing-support-library/index.html#setup">
- Testing Support Library Setup</a>.
- </li>
+<p>In the {@code build.gradle} file of your Android app module, you must set a dependency
+ reference to the Espresso library:</p>
- <li>
- <strong>Set up your project structure.</strong> In your Gradle project, the source code for
- the target app that you want to test is typically placed under the {@code app/src/main}
- folder. The source code for instrumentation tests, including
- your Espresso tests, must be placed under the <code>app/src/androidTest</code> folder. To
- learn more about setting up your project directory, see
- <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>.
- </li>
-
- <li>
- <strong>Specify your Android testing dependencies</strong>. In order for the
- <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for Gradle</a> to
- correctly build and run your Espresso tests, you must specify the following libraries in
- the {@code build.gradle} file of your Android app module:
-
- <pre>
+<pre>
dependencies {
- androidTestCompile 'com.android.support:support-annotations:23.0.1'
- androidTestCompile 'com.android.support.test:runner:0.4.1'
- androidTestCompile 'com.android.support.test:rules:0.4.1'
+ ...
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
- // Set this dependency if you want to use Hamcrest matching
- androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
}
</pre>
- </li>
- <li>
- <strong>Turn off animations on your test device.</strong> Leaving system animations turned
- on in the test device might cause unexpected results or may lead your test to fail. Turn
- off animations from <em>Settings</em> by opening <em>Developing Options</em> and
- turning all the following options off:
+<p>Turn off animations on your test device — leaving system animations turned on in the test
+device might cause unexpected results or may lead your test to fail. Turn off animations from
+<em>Settings</em> by opening <em>Developing Options</em> and turning all the following options off:
+</p>
<ul>
<li>
- <em>Window animation scale</em>
+ <strong>Window animation scale</strong>
</li>
<li>
- <em>Transition animation scale</em>
+ <strong>Transition animation scale</strong>
</li>
<li>
- <em>Animator duration scale</em>
+ <strong>Animator duration scale</strong>
</li>
</ul>
</li>
</ul>
+<p>If you want to set up your project to use Espresso features other than what the core API
+ provides, see this
+ <a href="https://google.github.io/android-testing-support-library/docs/espresso/index.html"
+ class="external-link">resource</a>.</p>
<h2 id="build">
Create an Espresso Test Class
</h2>
<p>
- To create an Espresso test, create a Java class or an
- {@link android.test.ActivityInstrumentationTestCase2}
- subclass that follows this programming model:
+ To create an Espresso test, create a Java class that follows this programming model:
</p>
<ol>
@@ -203,11 +181,70 @@
.perform(click()) // click() is a ViewAction
.check(matches(isDisplayed())); // matches(isDisplayed()) is a ViewAssertion
</pre>
+<h3 id="espresso-atr">Using Espresso with ActivityTestRule</h3>
+<p>
+The following section describes how to create a new Espresso test in the JUnit 4 style and use
+<a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html">
+{@code ActivityTestRule}</a> to reduce the amount of boilerplate code you need to write. By using
+<a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html">
+{@code ActivityTestRule}</a>, the testing framework launches the activity under test
+before each test method annotated with {@code @Test} and before any method annotated with
+{@code @Before}. The framework handles shutting down the activity after the test finishes
+and all methods annotated with {@code @After} are run.</p>
+
+<pre>
+package com.example.android.testing.espresso.BasicSample;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+...
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ChangeTextBehaviorTest {
+
+ private String mStringToBetyped;
+
+ @Rule
+ public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(
+ MainActivity.class);
+
+ @Before
+ public void initValidString() {
+ // Specify a valid string.
+ mStringToBetyped = "Espresso";
+ }
+
+ @Test
+ public void changeText_sameActivity() {
+ // Type text and then press the button.
+ onView(withId(R.id.editTextUserInput))
+ .perform(typeText(mStringToBetyped), closeSoftKeyboard());
+ onView(withId(R.id.changeTextBt)).perform(click());
+
+ // Check that the text was changed.
+ onView(withId(R.id.textToBeChanged))
+ .check(matches(withText(mStringToBetyped)));
+ }
+}
+</pre>
<h3 id="espresso-aitc2">
Using Espresso with ActivityInstrumentationTestCase2
</h3>
-
+<p>The following section describes how to migrate to Espresso if you have existing test classes
+subclassed from {@link android.test.ActivityInstrumentationTestCase2} and you don't want to rewrite
+them to use JUnit4.</p>
+<p class="note"><strong>Note:</strong> For new UI tests, we strongly recommend that you write your
+test in the JUnit 4 style and use the
+<a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html">
+{@code ActivityTestRule}</a> class, instead of
+{@link android.test.ActivityInstrumentationTestCase2}.</p>
<p>
If you are subclassing {@link android.test.ActivityInstrumentationTestCase2}
to create your Espresso test class, you must inject an
@@ -544,40 +581,13 @@
</pre>
<h2 id="run">Run Espresso Tests on a Device or Emulator</h2>
-
- <p>
- To run Espresso tests, you must use the
- <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a>
- class provided in the
- <a href="{@docRoot}tools/testing-support-library/index.html">
- Android Testing Support Library</a> as your default test runner. The
- <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for
- Gradle</a> provides a default directory ({@code src/androidTest/java}) for you to store the
- instrumented test classes and test suites that you want to run on a device. The
- plug-in compiles the test code in that directory and then executes the test app using
- the configured test runner class.
- </p>
-
- <p>
- To run Espresso tests in your Gradle project:
- </p>
-
- <ol>
- <li>Specify
- <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a>
- as the default test instrumentation runner in
- your {@code build.gradle} file:
-
- <pre>
-android {
- defaultConfig {
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- }
-}</pre>
- </li>
- <li>Run your tests from the command-line by calling the the {@code connectedAndroidTest}
- (or {@code cAT}) task:
- <pre>
-./gradlew cAT</pre>
- </li>
- </ol>
+<p>
+You can run Espresso tests from <a href="{@docRoot}sdk/index.html">Android Studio</a> or
+from the command-line. Make sure to specify
+<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+ {@code AndroidJUnitRunner}</a> as the default instrumentation runner in your project.
+</p>
+<p>
+To run your Espresso test, follow the steps for running instrumented tests
+described in <a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests">
+Getting Started with Testing</a>.</p>
diff --git a/docs/html/training/testing/ui-testing/index.jd b/docs/html/training/testing/ui-testing/index.jd
index d660c60..1aa95a4 100644
--- a/docs/html/training/testing/ui-testing/index.jd
+++ b/docs/html/training/testing/ui-testing/index.jd
@@ -1,5 +1,6 @@
page.title=Automating User Interface Tests
page.tags=testing
+page.image=images/testing/UIAutomatorViewer.png
trainingnavtop=true
startpage=true
diff --git a/docs/html/training/testing/ui-testing/uiautomator-testing.jd b/docs/html/training/testing/ui-testing/uiautomator-testing.jd
index ea15d8b..5dca40b 100644
--- a/docs/html/training/testing/ui-testing/uiautomator-testing.jd
+++ b/docs/html/training/testing/ui-testing/uiautomator-testing.jd
@@ -61,43 +61,21 @@
</p>
<h2 id="setup">Set Up UI Automator</h2>
-<p>Before you begin using UI Automator, you must:</p>
- <ul>
- <li>
- <strong>Install the Android Testing Support Library</strong>. The UI Automator API is
- located under the {@code com.android.support.test.uiautomator} package. These classes allow
- you to create tests that use the Espresso testing framework. To learn how to install the
- library, see <a href="{@docRoot}tools/testing-support-library/index.html#setup">
- Testing Support Library Setup</a>.
- </li>
+<p>Before building your UI test with UI Automator, make sure to configure your test source code
+location and project dependencies, as described in
+<a href="{@docRoot}training/testing/start/index.html#config-instrumented-tests">
+Getting Started with Testing</a>.</p>
- <li>
- <strong>Set up your project structure.</strong> In your Gradle project, the source code for
- the target app that you want to test is typically placed under the {@code app/src/main}
- folder. The source code for instrumentation tests, including
- your UI Automator tests, must be placed under the <code>app/src/androidTest</code> folder.
- To learn more about setting up your project directory, see
- <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>.
- </li>
+<p>In the {@code build.gradle} file of your Android app module, you must set a dependency
+ reference to the UI Automator library:</p>
- <li>
- <strong>Specify your Android testing dependencies</strong>. In order for the
- <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for Gradle</a> to
- correctly build and run your UI Automator tests, you must specify the following libraries in
- the {@code build.gradle} file of your Android app module:
-
- <pre>
+<pre>
dependencies {
- androidTestCompile 'com.android.support:support-annotations:23.0.1'
- androidTestCompile 'com.android.support.test:runner:0.4.1'
+ ...
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1'
- // Set this dependency if you want to use Hamcrest matching
- androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
}
</pre>
- </li>
- </ul>
<p>To optimize your UI Automator testing, you should first inspect the target app’s UI components
and ensure that they are accessible. These optimization tips are described in the next two
@@ -257,14 +235,10 @@
<pre>
import org.junit.Before;
import android.support.test.runner.AndroidJUnit4;
-import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.Until;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import static org.junit.Assert.assertThat;
+...
@RunWith(AndroidJUnit4.class)
@SdkSuppress(minSdkVersion = 18)
@@ -305,6 +279,10 @@
}
</pre>
+<p>In the example, the {@code @SdkSuppress(minSdkVersion = 18)} statement helps to ensure that
+ tests will only run on devices with Android 4.3 (API level 18) or higher, as required by the
+ UI Automator framework.</p>
+
<p>Use the
<a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html#findObject(android.support.test.uiautomator.UiSelector)">{@code findObject()}</a>
method to retrieve a
@@ -533,33 +511,14 @@
</pre>
<h2 id="run">Run UI Automator Tests on a Device or Emulator</h2>
-<p>UI Automator tests are based on the {@link android.app.Instrumentation} class. The
-<a href="https://developer.android.com/tools/building/plugin-for-gradle.html">
- Android Plug-in for Gradle</a>
-provides a default directory ({@code src/androidTest/java}) for you to store the instrumented test
-classes and test suites that you want to run on a device. The plug-in compiles the test
-code in that directory and then executes the test app using a test runner class. You are
-strongly encouraged to use the
-<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a>
-class provided in the
-<a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>
-as your default test runner. </p>
-
-<p>To run UI Automator tests in your Gradle project:</p>
-
-<ol>
-<li>Specify
-<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a>
-as the default test instrumentation runner in your {@code build.gradle} file:
-<pre>
-android {
- defaultConfig {
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- }
-}</pre>
-</li>
-<li>Run your tests from the command-line by calling the {@code connectedCheck}
- (or {@code cC}) task:
-<pre>./gradlew cC</pre>
-</li>
-</ol>
\ No newline at end of file
+<p>
+You can run UI Automator tests from <a href="{@docRoot}sdk/index.html">Android Studio</a> or
+from the command-line. Make sure to specify
+<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+ {@code AndroidJUnitRunner}</a> as the default instrumentation runner in your project.
+</p>
+<p>
+To run your UI Automator test, follow the steps for running instrumented tests
+described in <a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests">
+Getting Started with Testing</a>.
+</p>
\ No newline at end of file
diff --git a/docs/html/training/testing/unit-testing/index.jd b/docs/html/training/testing/unit-testing/index.jd
index a35ba80..6610761 100644
--- a/docs/html/training/testing/unit-testing/index.jd
+++ b/docs/html/training/testing/unit-testing/index.jd
@@ -1,5 +1,6 @@
page.title=Building Effective Unit Tests
page.tags=testing,androidjunitrunner,junit,unit test
+page.image=images/testing/hwtest_junit_success.png
trainingnavtop=true
startpage=true
diff --git a/docs/html/training/testing/unit-testing/instrumented-unit-tests.jd b/docs/html/training/testing/unit-testing/instrumented-unit-tests.jd
index db4cc8c..38321ee 100644
--- a/docs/html/training/testing/unit-testing/instrumented-unit-tests.jd
+++ b/docs/html/training/testing/unit-testing/instrumented-unit-tests.jd
@@ -13,6 +13,7 @@
<li>Android 2.2 (API level 8) or higher</li>
<li><a href="{@docRoot}tools/testing-support-library/index.html">
Android Testing Support Library</a></li>
+ <li><a href="{@docRoot}tools/studio/index.html">Android Studio (latest version)</a>.</li>
</ul>
<h2>This lesson teaches you to</h2>
@@ -29,6 +30,8 @@
<li>
<a href="https://github.com/googlesamples/android-testing/tree/master/unit/BasicUnitAndroidTest"
class="external-link">Instrumented Unit Tests Code Samples</a></li>
+ <li><a href="https://www.code-labs.io/codelabs/android-studio-testing/index.html?index=..%2F..%2Findex#0"
+class="external-link">Unit and UI Testing in Android Studio (codelab)</a></li>
</ul>
</div>
</div>
@@ -46,45 +49,10 @@
</p>
<h2 id="setup">Set Up Your Testing Environment</h2>
-<p>Before building instrumented unit tests, you must:</p>
-
- <ul>
- <li>
- <strong>Install the Android Testing Support Library</strong>. The
- <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
- {@code AndroidJUnitRunner}</a> API, located under the
- {@code com.android.support.test.runner} package, allows you to
- create and run instrumented unit tests. To learn how to install the
- library, see <a href="{@docRoot}tools/testing-support-library/index.html#setup">
- Testing Support Library Setup</a>.
- </li>
-
- <li>
- <strong>Set up your project structure.</strong> In your Gradle project, the source code for
- the target app that you want to test is typically placed under the {@code app/src/main/java}
- folder. The source code for instrumentatation tests, including your unit tests, must be
- placed under the <code>app/src/androidTest/java</code> folder.
- To learn more about setting up your project directory, see
- <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>.
- </li>
-
- <li>
- <strong>Specify your Android testing dependencies</strong>. In order for the
- <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for Gradle</a> to
- correctly build and run your instrumented unit tests, you must specify the following
- libraries in the {@code build.gradle} file of your Android app module:
-
- <pre>
-dependencies {
- androidTestCompile 'com.android.support:support-annotations:23.0.1'
- androidTestCompile 'com.android.support.test:runner:0.4.1'
- androidTestCompile 'com.android.support.test:rules:0.4.1'
- // Set this dependency if you want to use Hamcrest matching
- androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
-}
-</pre>
- </li>
- </ul>
+<p>Before building your instrumented unit test, make sure to configure your test source code
+location and project dependencies, as described in
+<a href="{@docRoot}training/testing/start/index.html#config-instrumented-tests">
+Getting Started with Testing</a>.</p>
<h2 id="build">Create an Instrumented Unit Test Class</h2>
<p>
@@ -97,8 +65,8 @@
<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
{@code AndroidJUnitRunner}</a> class
provided in the Android Testing Support Library as your default test runner. This step is described
-in more detail in <a href="#run">Run Instrumented Unit Tests</a>.
-</p>
+in more detail in <a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests">
+Getting Started with Testing</p>
<p>The following example shows how you might write an instrumented unit test to test that
the {@link android.os.Parcelable} interface is implemented correctly for the
@@ -115,6 +83,7 @@
import static org.junit.Assert.assertThat;
@RunWith(AndroidJUnit4.class)
+@SmallTest
public class LogHistoryAndroidUnitTest {
public static final String TEST_STRING = "This is a string";
@@ -195,57 +164,7 @@
<h2 id="run">Run Instrumented Unit Tests</h2>
<p>
-The
-<a href="https://developer.android.com/tools/building/plugin-for-gradle.html">
- Android Plug-in for Gradle</a>
-provides a default directory ({@code src/androidTest/java}) for you to store the instrumented unit
-and integration test classes and test suites that you want to run on a device. The plug-in compiles
-the test code in that directory and then executes the test app using a test runner class. You must
-set the
-<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
-{@code AndroidJUnitRunner}</a> class provided in the
-<a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>
-as your default test runner.</p>
-</p>
-
-<p>To specify
-<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
-{@code AndroidJUnitRunner}</a> as the default test instrumentation runner, add the following
-setting in your {@code build.gradle} file:</p>
-<pre>
-android {
- defaultConfig {
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- }
-}
-</pre>
-
-<h3 id="run-from-Android-Studio">Running instrumented unit tests from Android Studio</h3>
-<p>
-To run instrumented unit tests in your Gradle project from Android Studio:
-</p>
-<ol>
-<li>Open the <strong>Build Variants</strong> window by clicking the left-hand tab, then set the
-test artifact to <em>Android Instrumentation Tests</em>.
-</li>
-<li>In the <strong>Project</strong> window, drill down to your unit test class or method, then
- right-click and run it using the Android Test configuration.
-</li>
-</ol>
-
-<p>Android Studio displays the results of the unit test execution in the <strong>Run</strong>
-window.</p>
-
-<h3 id="run-from-commandline">Running instrumented unit tests from the command-line</h3>
-
-<p>To run instrumented unit tests in your Gradle project from the command-line, call the
- {@code connectedCheck} (or {@code cC}) task:</p>
-
-<pre>
-./gradlew cC
-</pre>
-
-<p>You can find the generated HTML test result reports in the
-{@code <path_to_your_project>/app/build/outputs/reports/androidTests/connected/} directory,
-and the corresponding XML files in the
-{@code <path_to_your_project>/app/build/outputs/androidTest-results/connected/} directory.</p>
\ No newline at end of file
+To run your test, follow the steps for running instrumented tests
+described in <a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests">
+Getting Started with Testing</a>.
+</p>
\ No newline at end of file
diff --git a/docs/html/training/testing/unit-testing/local-unit-tests.jd b/docs/html/training/testing/unit-testing/local-unit-tests.jd
index 98939fa..893d957 100644
--- a/docs/html/training/testing/unit-testing/local-unit-tests.jd
+++ b/docs/html/training/testing/unit-testing/local-unit-tests.jd
@@ -10,7 +10,7 @@
<h2>Dependencies and Prerequisites</h2>
<ul>
- <li>Android Plug-in for Gradle 1.1.0 or higher</li>
+ <li><a href="{@docRoot}tools/studio/index.html">Android Studio (latest version)</a>.</li>
</ul>
<h2>This lesson teaches you to</h2>
@@ -27,6 +27,8 @@
<li>
<a href="https://github.com/googlesamples/android-testing/tree/master/unit/BasicSample"
class="external-link">Local Unit Tests Code Samples</a></li>
+ <li><a href="https://codelabs.developers.google.com/codelabs/android-testing/index.html?index=..%2F..%2Findex#0"
+class="external-link">Android Testing Codelab</a></li>
</ul>
</div>
</div>
@@ -36,47 +38,15 @@
you avoid the overhead of loading the target app and unit test code onto a physical device or
emulator every time your test is run. Consequently, the execution time for running your unit
test is greatly reduced. With this approach, you normally use a mocking framework, like
-<a href="https://code.google.com/p/mockito/" class="external-link">Mockito</a>, to fulfill any
+<a href="https://github.com/mockito/mockito" class="external-link">Mockito</a>, to fulfill any
dependency relationships.</p>
-<p><a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for Gradle</a>
-version 1.1.0 and higher allows you to create a source directory ({@code src/test/java}) in your
-project to store JUnit tests that you want to run on a local machine. This feature improves your
-project organization by letting you group your unit tests together into a single source set. You
-can run the tests from Android Studio or the command-line, and the plugin executes them on the
-local Java Virtual Machine (JVM) on your development machine. </p>
-
<h2 id="setup">Set Up Your Testing Environment</h2>
-<p>Before building local unit tests, you must:</p>
+<p>Before building your local unit test, make sure to configure your test source code location and
+project dependencies, as described in
+<a href="{@docRoot}training/testing/start/index.html#config-local-tests">
+Getting Started with Testing</a>.</p>
- <ul>
- <li>
- <strong>Set up your project structure.</strong> In your Gradle project, the source code for
- the target app that you want to test is typically placed under the {@code app/src/main/java}
- folder. The source code for your local unit tests must be placed under the
- <code>app/src/test/java</code> folder.
- To learn more about setting up your project directory, see
- <a href="#run">Run Local Unit Tests</a> and
- <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>.
- </li>
-
- <li>
- <strong>Specify your Android testing dependencies</strong>. In order to use JUnit 4 and
- Mockito with your local unit tests, specify the following libraries in
- the {@code build.gradle} file of your Android app module:
-
- <pre>
-dependencies {
- // Unit testing dependencies
- testCompile 'junit:junit:4.12'
- // Set this dependency if you want to use Mockito
- testCompile 'org.mockito:mockito-core:1.10.19'
- // Set this dependency if you want to use Hamcrest matching
- testCompile 'org.hamcrest:hamcrest-library:1.1'
-}
-</pre>
- </li>
- </ul>
<h2 id="build">Create a Local Unit Test Class</h2>
<p>Your local unit test class should be written as a JUnit 4 test class.
@@ -116,44 +86,10 @@
<a href="http://junit.org/javadoc/latest/org/junit/Assert.html" class="external-link">
junit.Assert</a> methods to perform validation checks (or <em>assertions</em>) to compare the state
of the component under test against some expected value. To make tests more readable, you
-can use <a href="https://code.google.com/p/hamcrest/wiki/Tutorial" class="external-link">
+can use <a href="https://github.com/hamcrest" class="external-link">
Hamcrest matchers</a> (such as the {@code is()} and {@code equalTo()} methods) to match the
returned result against the expected result.</p>
-<p>In your JUnit 4 test class, you can use annotations to call out sections in your test code for
-special processing, such as:</p>
-
-<ul>
-<li>
-{@code @Before}: Use this annotation to specify a block of code with test setup operations. This
-code block will be invoked before each test. You can have multiple {@code @Before} methods but
-the order which these methods are called is not fixed.
-</li>
-<li>
-{@code @After}: This annotation specifies a block of code with test tear-down operations. This
-code block will be called after every test method. You can define multiple {@code @After}
-operations in your test code. Use this annotation to release any resources from memory.
-</li>
-<li>
-{@code @Test}: Use this annotation to mark a test method. A single test class can contain
-multiple test methods, each prefixed with this annotation.
-</li>
-<li>
-{@code @BeforeClass}: Use this annotation to specify static methods to be invoked only once per
-test class. This testing step is useful for expensive operations such as connecting to a database.
-</li>
-<li>
-{@code @AfterClass}: Use this annotation to specify static methods to be invoked only after all
-tests in the class have been run. This testing step is useful for releasing any resources allocated
-in the {@code @BeforeClass} block.
-</li>
-<li>
-{@code @Test(timeout=<milliseconds>)}: Specifies a timeout period for the test. If the
-test starts but does not complete within the given timeout period, it automatically fails. You must
-specify the timeout period in milliseconds, for example: {@code @Test(timeout=5000)}.
-</li>
-</ul>
-
<h3 id="mocking-dependencies">Mocking Android dependencies</h3>
<p>
By default, the <a href="{@docRoot}tools/building/plugin-for-gradle.html">
@@ -166,7 +102,7 @@
your component interacts with a dependency in an expected way. By substituting Android dependencies
with mock objects, you can isolate your unit test from the rest of the Android system while
verifying that the correct methods in those dependencies are called. The
-<a href="https://code.google.com/p/mockito/" class="external-link">Mockito</a> mocking framework
+<a href="https://github.com/mockito/mockito" class="external-link">Mockito</a> mocking framework
for Java (version 1.9.5 and higher) offers compatibility with Android unit testing.
With Mockito, you can configure mock objects to return some specific value when invoked.</p>
@@ -240,63 +176,8 @@
<h2 id="run">Run Local Unit Tests</h2>
<p>
-The Android Plug-in for Gradle provides a default directory ({@code src/test/java}) for you to
-store unit test classes that you want to run on a local JVM. The plug-in compiles the test code in
-that directory and then executes the test app locally using the default test runner class.
+To run your tests, follow the steps for running local unit tests
+described in <a href="{@docRoot}training/testing/start/index.html#run-local-tests">
+Getting Started with Testing</a>.
</p>
-<p>
-As with production code, you can create unit tests for a
-<a href="http://developer.android.com/tools/building/configuring-gradle.html#workBuildVariants"
-class="external-link">specific flavor or build type</a>. You should keep unit tests in a test
-source tree location that corresponds to your production source tree, such as:
-<table>
-<tr>
-<th>Path to Production Class</th>
-<th>Path to Local Unit Test Class</th>
-</tr>
-<tr>
-<td>{@code src/main/java/Foo.java}</td>
-<td>{@code src/test/java/FooTest.java}</td>
-</tr>
-<tr>
-<td>{@code src/debug/java/Foo.java}</td>
-<td>{@code src/testDebug/java/FooTest.java}</td>
-</tr>
-<tr>
-<td>{@code src/myFlavor/java/Foo.java}</td>
-<td>{@code src/testMyFlavor/java/FooTest.java}</td>
-</tr>
-</table>
-
-<h3 id="run-from-Android-Studio">Running local unit tests from Android Studio</h3>
-<p>
-To run local unit tests in your Gradle project from Android Studio:
-</p>
-<ol>
-<li>In the <strong>Project</strong> window, right click on the project and synchronize your project.
-</li>
-<li>Open the <strong>Build Variants</strong> window by clicking the left-hand tab, then change the
-test artifact to <em>Unit Tests</em>.
-</li>
-<li>In the <strong>Project</strong> window, drill down to your unit test class or method, then
-right-click and run it.
-</li>
-</ol>
-
-<p>Android Studio displays the results of the unit test execution in the <strong>Run</strong>
-window.</p>
-
-<h3 id="run-from-commandline">Running local unit tests from the command-line</h3>
-
-<p>To run local unit tests in your Gradle project from the command-line, call the {@code test} task
-command with the {@code --continue} option.</p>
-
-<pre>
-./gradlew test --continue
-</pre>
-
-<p>If there are failing tests, the command will display links to HTML reports (one per build
-variant). You can find the generated HTML test result reports in the
-{@code <path_to_your_project>/app/build/reports/tests/} directory, and the corresponding XML
-files in the {@code <path_to_your_project>/app/build/test-results/} directory.</p>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 9e156d0..3d1cf39 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -1098,6 +1098,10 @@
ja-lang="再生中カードを表示する">
Displaying a Now Playing Card</a>
</li>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/playback/options.html">
+ Enabling Background Playback</a>
+ </li>
</ul>
</li>
@@ -1569,6 +1573,10 @@
Developing Accessibility Services
</a>
</li>
+ <li><a href="<?cs var:toroot ?>training/accessibility/testing.html">
+ Accessibility Testing Checklist
+ </a>
+ </li>
</ul>
</li>
@@ -2085,58 +2093,48 @@
<li class="nav-section">
<div class="nav-section-header">
- <a href="<?cs var:toroot ?>training/testing.html">
+ <a href="<?cs var:toroot ?>training/best-permissions-ids.html">
+ <span class="small">Best Practices for</span><br/>
+ Permissions & Identifiers
+ </a>
+ </div>
+ <ul>
+ <li>
+ <a href="<?cs var:toroot ?>training/articles/user-data-overview.html"
+ description=
+ "Overview of app permissions on Android and how they affect your users."
+ >Permissions and User Data</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/articles/user-data-permissions.html"
+ description=
+ "How to manage permissions the right way for users."
+ >Best Practices for App Permissions</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/articles/user-data-ids.html"
+ description=
+ "Unique identifiers available and how to choose the right one for your use case."
+ >Best Practices for Unique Identifiers</a>
+ </li>
+ </ul>
+ </li>
+ <!-- End Permissions and identifiers -->
+
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/testing/index.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>
+ <li>
+ <a href="<?cs var:toroot ?>training/testing/start/index.html"
+ description="How to get started with testing your Android applications.">
+ Getting Started with Testing
</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>
-
- <li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>training/testing/ui-testing/index.html"
- description="How to automate your user interface tests for Android apps.">
- Automating UI Tests
- </a></div>
- <ul>
- <li><a href="<?cs var:toroot ?>training/testing/ui-testing/espresso-testing.html">
- <span class="en">Testing UI for a Single App</span>
- </a>
- </li>
- <li><a href="<?cs var:toroot ?>training/testing/ui-testing/uiautomator-testing.html">
- <span class="en">Testing UI for Multiple Apps</span>
- </a>
- </li>
- </ul>
- </li>
-
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot ?>training/testing/unit-testing/index.html"
description="How to build effective unit tests for Android apps.">
@@ -2153,10 +2151,36 @@
</li>
</ul>
</li>
-
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/testing/ui-testing/index.html"
+ description="How to automate your user interface tests for Android apps.">
+ Automating UI Tests
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/testing/ui-testing/espresso-testing.html">
+ <span class="en">Testing UI for a Single App</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/testing/ui-testing/uiautomator-testing.html">
+ <span class="en">Testing UI for Multiple Apps</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>training/testing/integration-testing/index.html"
+ description="How to build effective integration tests for Android apps.">
+ Testing App Component Integrations
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/testing/integration-testing/service-testing.html">
+ <span class="en">Testing Your Service</span></a></li>
+ <li><a href="<?cs var:toroot ?>training/testing/integration-testing/content-provider-testing.html">
+ <span class="en">Testing Your Content Provider</span></a></li>
+ </ul>
+ </li>
<li><a href="<?cs var:toroot ?>training/testing/performance.html"
- description="How to automate UI performance testing.">
- Testing Display Performance</a>
+ description="How to automate UI performance testing.">Testing Display Performance</a>
</li>
</ul>
</li>
diff --git a/docs/html/training/tv/playback/index.jd b/docs/html/training/tv/playback/index.jd
index e39e34a..43c6d41 100644
--- a/docs/html/training/tv/playback/index.jd
+++ b/docs/html/training/tv/playback/index.jd
@@ -64,4 +64,7 @@
<dt><b><a href="now-playing.html">Displaying a Now Playing Card</a></b></dt>
<dd>Learn how to use a MediaSession to display a Now Playing card on the home screen.</dd>
+
+ <dt><b><a href="options.html">Enabling Background Playback</a></b></dt>
+ <dd>Learn how to continue playback when the user clicks on <strong>Home</strong>.</dd>
</dl>
diff --git a/docs/html/training/tv/playback/now-playing.jd b/docs/html/training/tv/playback/now-playing.jd
index ae5dd1c..2bb628a 100644
--- a/docs/html/training/tv/playback/now-playing.jd
+++ b/docs/html/training/tv/playback/now-playing.jd
@@ -30,6 +30,10 @@
<p>This lesson shows how to use the {@link android.media.session.MediaSession} class to implement
the <em>Now Playing</em> card.</p>
+<img src="{@docRoot}images/training/tv/playback/now-playing-screen.png" />
+<p class="img-caption"><strong>Figure 1.</strong> Display a <em>Now Playing</em> card when playing
+media in the background.</p>
+
<h2 id="session">Start a Media Session</h2>
<p>Create a
diff --git a/docs/html/training/tv/playback/options.jd b/docs/html/training/tv/playback/options.jd
new file mode 100644
index 0000000..c65343d
--- /dev/null
+++ b/docs/html/training/tv/playback/options.jd
@@ -0,0 +1,66 @@
+page.title=Enabling Background Playback
+page.tags=tv, play, playback, background
+helpoutsWidget=true
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#background">Request Background Playback</a></li>
+ </ol>
+</div>
+</div>
+
+<p>
+A user watching content on a TV device may decide to switch to the TV launcher at any time.
+If a user switches to the launcher while using a TV playback app, by default the app is paused.
+Since the user did not explicitly request to pause playback, the default behavior might seem
+abrupt and unexpected. This lesson describes how to enable background playback in your app,
+which provides a better user experience.
+</p>
+
+<h2 id="background">Request Background Playback</h2>
+
+<p>Normally, when the user clicks on <strong>Home</strong> to display the TV
+launcher, the activity pauses. However, your app can request background playback, in
+which the activity continues playing behind the TV launcher.</p>
+
+<p>To request background playback, call
+{@link android.app.Activity#requestVisibleBehind requestVisibleBehind()}.
+Be sure to clean up media resources if the activity stops being
+visible. For example, you should free media resources if
+{@link android.app.Activity#requestVisibleBehind requestVisibleBehind()}
+returns <code>false</code> to indicate that the request failed, or if the system calls
+your override of {@link android.app.Activity#onVisibleBehindCanceled onVisibleBehindCanceled()}.
+</p>
+
+<pre>
+@Override
+public void onPause() {
+ super.onPause();
+ if (mVideoView.isPlaying()) {
+ // Argument equals true to notify the system that the activity
+ // wishes to be visible behind other translucent activities
+ if (! requestVisibleBehind(true)) {
+ // App-specific method to stop playback and release resources
+ // because call to requestVisibleBehind(true) failed
+ stopPlayback();
+ }
+ } else {
+ // Argument equals false because the activity is not playing
+ requestVisibleBehind(false);
+ }
+}
+
+@Override
+public void onVisibleBehindCanceled() {
+ // App-specific method to stop playback and release resources
+ stopPlayback();
+ super.onVisibleBehindCanceled();
+}
+</pre>
+
diff --git a/docs/html/training/tv/start/start.jd b/docs/html/training/tv/start/start.jd
old mode 100644
new mode 100755
index 743b61b..0ed6e15
--- a/docs/html/training/tv/start/start.jd
+++ b/docs/html/training/tv/start/start.jd
@@ -367,7 +367,5 @@
For more information about using emulators see, <a href="{@docRoot}tools/devices/emulator.html">
Using the Emulator</a>. For more information on deploying apps from Android Studio to virtual
devices, see <a href="{@docRoot}sdk/installing/studio-debug.html">Debugging with Android
- Studio</a>. For more information about deploying apps to emulators from Eclipse with ADT, see
- <a href="{@docRoot}tools/building/building-eclipse.html">Building and Running from Eclipse with
- ADT</a>.
+ Studio</a>.
</p>
diff --git a/docs/html/training/volley/index.jd b/docs/html/training/volley/index.jd
old mode 100644
new mode 100755
index 2cefc90..6ee7d4e
--- a/docs/html/training/volley/index.jd
+++ b/docs/html/training/volley/index.jd
@@ -77,9 +77,9 @@
</pre>
</li>
-<li>Import the downloaded source into your app project as an Android library project
-(as described in <a href="{@docRoot}tools/projects/projects-eclipse.html">
-Managing Projects from Eclipse with ADT</a>, if you're using Eclipse) or make a
+<li>Import the downloaded source into your app project as an Android library module
+(as described in <a href="{@docRoot}sdk/installing/create-project.html#SettingUpLibraryModule">
+Managing Projects from Android Studio</a>, if you're using Android Studio) or make a
<a href="{@docRoot}guide/faq/commontasks.html#addexternallibrary"><code>.jar</code> file</a>.</li>
</ol>
diff --git a/docs/html/wear/images/partners/casio.png b/docs/html/wear/images/partners/casio.png
new file mode 100644
index 0000000..41f36d8
--- /dev/null
+++ b/docs/html/wear/images/partners/casio.png
Binary files differ
diff --git a/docs/html/wear/images/partners/mobvoi.png b/docs/html/wear/images/partners/mobvoi.png
new file mode 100644
index 0000000..9a2eb4d
--- /dev/null
+++ b/docs/html/wear/images/partners/mobvoi.png
Binary files differ
diff --git a/docs/html/wear/images/partners/nb.png b/docs/html/wear/images/partners/nb.png
new file mode 100644
index 0000000..224b27e
--- /dev/null
+++ b/docs/html/wear/images/partners/nb.png
Binary files differ
diff --git a/docs/html/wear/index.jd b/docs/html/wear/index.jd
index e18ada4..ec2c509 100644
--- a/docs/html/wear/index.jd
+++ b/docs/html/wear/index.jd
@@ -213,6 +213,9 @@
<div class="col-4">
<img src="/wear/images/partners/broadcom.png" alt="Broadcom">
</div>
+ <div class="col-4">
+ <img src="/wear/images/partners/casio.png" alt="Casio">
+ </div>
<div class="col-4">
<img src="/wear/images/partners/fossil.png" alt="Fossil">
</div>
@@ -234,9 +237,15 @@
<div class="col-4">
<img src="/wear/images/partners/mips.png" alt="MIPS">
</div>
+ <div class="col-4">
+ <img src="/wear/images/partners/mobvoi.png" alt="Mobvoi">
+ </div>
<div class="col-4">
<img src="/wear/images/partners/motorola.png" alt="Motorola">
</div>
+ <div class="col-4">
+ <img src="/wear/images/partners/nb.png" alt="New Balance">
+ </div>
<div class="col-4">
<img src="/wear/images/partners/qualcomm.png" alt="Qualcomm">
</div>
@@ -249,6 +258,7 @@
<div class="col-4">
<img src="/wear/images/partners/tagheuer.png" alt="Tag Heuer">
</div>
+
</div>
</div> <!-- end .wrap -->
</div>