diff options
Diffstat (limited to 'en/compatibility/tests/development/instr-app-e2e.md')
-rw-r--r-- | en/compatibility/tests/development/instr-app-e2e.md | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/en/compatibility/tests/development/instr-app-e2e.md b/en/compatibility/tests/development/instr-app-e2e.md new file mode 100644 index 00000000..b61d6644 --- /dev/null +++ b/en/compatibility/tests/development/instr-app-e2e.md @@ -0,0 +1,291 @@ +Project: /_project.yaml +Book: /_book.yaml + +{% include "_versions.html" %} + +<!-- + Copyright 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +# Targeting an Application Example + +This category of instrumentation test isn't that different from those targeting +the regular Android applications. It's worth noting that the test application +that included the instrumentation needs to be signed with the same certificate +as the application that it's targeting. + +Note that this guide assumes that you already have some knowledge in the +platform source tree workflow. If not, please refer to +https://source.android.com/source/requirements. The example +covered here is writing an new instrumentation test with target package set at +its own test application package. If you are unfamiliar with the concept, please +read through the [Platform testing introduction](../development/index.md). + +This guide uses the follow test to serve as an sample: + +* frameworks/base/packages/Shell/tests + +It's recommended to browse through the code first to get a rough impression +before proceeding. + +## Deciding on a source location + +Because the instrumentation test will be targeting an application, the convention +is to place the test source code in a `tests` directory under the root of your +component source directory in platform source tree. + +See more discussions about source location in the [end-to-end example for +self-instrumenting tests](instr-self-e2e.md). + +## Manifest file + +Just like a regular application, each instrumentation test module needs a +manifest file. If you name the file as `AndroidManifest.xml` and provide it next +to `Android.mk` for your test tmodule, it will get included automatically by the +`BUILD_PACKAGE` core makefile. + +Before proceeding further, it's highly recommended to go through the external +[documentation on manifest file](https://developer.android.com/guide/topics/manifest/manifest-intro.html) +first. + +This gives an overview of basic components of a manifest file and their +functionalities. + +Latest version of the manifest file for the sample gerrit change can be accessed +at: +https://android.googlesource.com/platform/frameworks/base/+/master/packages/Shell/tests/AndroidManifest.xml + +A snapshot is included here for convenience: + +```xml +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.shell.tests"> + + <application> + <uses-library android:name="android.test.runner" /> + + <activity + android:name="com.android.shell.ActionSendMultipleConsumerActivity" + android:label="ActionSendMultipleConsumer" + android:theme="@android:style/Theme.NoDisplay" + android:noHistory="true" + android:excludeFromRecents="true"> + <intent-filter> + <action android:name="android.intent.action.SEND_MULTIPLE" /> + <category android:name="android.intent.category.DEFAULT" /> + <data android:mimeType="*/*" /> + </intent-filter> + </activity> + </application> + + <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.shell" + android:label="Tests for Shell" /> + +</manifest> +``` + +Some select remarks on the manifest file: + +```xml +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.shell.tests"> +``` + +The `package` attribute is the application package name: this is the unique +identifier that the Android application framework uses to identify an +application (or in this context: your test application). Each user in the system +can only install one application with that package name. + +Since this is a test application package, independent from the application +package under test, a different package name must be used: one common convention +is to add a suffix `.test`. + +Furthermore, this `package` attribute is the same as what +[`ComponentName#getPackageName()`](https://developer.android.com/reference/android/content/ComponentName.html#getPackageName\(\)) +returns, and also the same you would use to interact with various `pm` sub +commands via `adb shell`. + +Please also note that although the package name is typically in the same style +as a Java package name, it actually has very few things to do with it. In other +words, your application (or test) package may contain classes with any package +names, though on the other hand, you could opt for simplicity and have your top +level Java package name in your application or test identical to the application +package name. + +```xml +<uses-library android:name="android.test.runner" /> +``` + +This is required for all Instrumentation tests since the related classes are +packaged in a separate framework jar library file, therefore requires additional +classpath entries when the test package is invoked by application framework. + +```xml +android:targetPackage="com.android.shell" +``` + +This sets the target package of the instrumentation to `com.android.shell.tests`. +When the instrumentation is invoked via `am instrument` command, the framework +restarts `com.android.shell.tests` process, and injects instrumentation code into +the process for test execution. This also means that the test code will have +access to all the class instances running in the application under test and may +be able to manipulate state depends on the test hooks exposed. + +## Simple configuration file + +Each new test module must have a configuration file to direct +the build system with module metadata, compile-time dependencies and packaging +instructions. In most cases, the Soong-based, Blueprint file option is +sufficient. See [Simple Test Configuration](blueprints.md) for details. + +## Complex configuration file + +Important: The instructions in this section are needed only for CTS tests or those +that require special setup, such as disabling Bluetooth or collecting sample data. +All other cases can be covered through the +[Simple Test Configuration](blueprints.md). See the +[Complex Test Configuration](compatibility/tests/development/test-config) for +more details applicable to this section. + +For more complex tests, you also need write a test configuration +file for Android's test harness, [Trade Federation](https://source.android.com/devices/tech/test_infra/tradefed/). + +The test configuration can specify special device setup options and default +arguments to supply the test class. + +Latest version of the config file for the sample gerrit change can be accessed +at: +https://android.googlesource.com/platform/frameworks/base/+/master/packages/Shell/tests/AndroidTest.xml + +A snapshot is included here for convenience: + +```xml +<configuration description="Runs Tests for Shell."> + <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> + <option name="test-file-name" value="ShellTests.apk" /> + </target_preparer> + + <option name="test-suite-tag" value="apct" /> + <option name="test-tag" value="ShellTests" /> + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > + <option name="package" value="com.android.shell.tests" /> + <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + </test> +</configuration> +``` + +Some select remarks on the test configuration file: + +```xml +<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> + <option name="test-file-name" value="ShellTests.apk"/> +</target_preparer> +``` +This tells Trade Federation to install the ShellTests.apk onto the target +device using a specified target_preparer. There are many target preparers +available to developers in Trade Federation and these can be used to ensure +the device is setup properly prior to test execution. + +```xml +<test class="com.android.tradefed.testtype.AndroidJUnitTest"> + <option name="package" value="com.android.shell.tests"/> + <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/> +</test> +``` +This specifies the Trade Federation test class to use to execute the test and +passes in the package on the device to be executed and the test runner +framework which is JUnit in this case. + +Look here for more information on [Test Module Configs](test-config.md) + +## JUnit4 features + +Using `android-support-test` library as test runner enables adoptation of new +JUnit4 style test classes, and the sample gerrit change contains some very basic +use of its features. + +Latest source code for the sample gerrit change can be accessed at: +frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.javast.java + +While testing patterns are usually specific to component teams, there are some +generally useful usage patterns. + +```java +@SmallTest +@RunWith(AndroidJUnit4.class) +public final class FeatureFactoryImplTest { +``` + +A significant difference in JUnit4 is that tests are no longer required to +inherit from a common base test class; instead, you write tests in plain Java +classes and use annotation to indicate certain test setup and constraints. In +this example, we are instructing that this class should be run as an Android +JUnit4 test. + +The `@SmallTest` annotation specified a test size for the entire test class: all +test methods added into this test class inherit this test size annotation. +pre test class setup, post test tear down, and post test class tear down: +similar to `setUp` and `tearDown` methods in JUnit4. +`Test` annotation is used for annotating the actual test. + +Important: the test methods themselves are annotated with `@Test` +annotation; and note that for tests to be executed via APCT, they must be +annotated with test sizes. Such annotation may be applied at method scope, or +class scope. + +```java + @Before + public void setup() { + ... + @Test + public void testGetProvider_shouldCacheProvider() { + ... +``` + +The `@Before` annotation is used on methods by JUnit4 to perform pre test setup. +Although not used in this example, there's also `@After` for post test teardown. +Similarly, the `@BeforeClass` and `@AfterClass` annotations are can be used on +methods by JUnit4 to perform setup before executing all tests in a test class, +and teardown afterwards. Note that the class-scope setup and teardown methods +must be static. + +As for the test methods, unlike in earlier version of JUnit, they no longer need +to start the method name with `test`, instead, each of them must be annotated +with `@Test`. As usual, test methods must be public, declare no return value, +take no parameters, and may throw exceptions. + +```java + Context context = InstrumentationRegistry.getTargetContext(); +``` + +Because the JUnit4 tests no longer require a common base class, it's no longer +necessary to obtain `Context` instances via `getContext()` or +`getTargetContext()` via base class methods; instead, the new test runner +manages them via [`InstrumentationRegistry`](https://developer.android.com/reference/android/support/test/InstrumentationRegistry.html) +where contextual and environmental setup created by instrumentation framework is +stored. Through this class, you can also call: + +* `getInstrumentation()`: the instance to the `Instrumentation` class +* `getArguments()`: the command line arguments passed to `am instrument` via + `-e <key> <value>` + +## Build and test locally + +For the most common use cases, employ +[Atest](https://android.googlesource.com/platform/tools/tradefederation/+/master/atest/README.md). + +For more complex cases requiring heavier customization, follow the +[instrumentation instructions](instrumentation.md). |