• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..--

example/14-Jan-2024-260147

testrule/15-Dec-2024-463312

testrunner/15-Dec-2024-222166

textexecutor/15-Dec-2024-11243

OWNERSD15-Dec-202435 32

README.mdD15-Dec-20249.1 KiB286232

README.md

1# SDK Sandbox Test Scenario Test Utilities
2
3## Overview
4
5This directory contains utilities that allow you to run tests inside of an SDK.
6
7[design](http://go/sandbox-webview-cts-tests) (*only visible to Googlers)
8
9Three public class are provided:
10- SdkSandboxScenarioRule: This is a custom JUnit rule used for creating a test environment
11and invoking test methods
12- SdkSandboxTestScenarioRunner: This is a custom SandboxedSdkProvider that manages test
13invocations and reporting the results from within a SDK Sandbox
14
15## Creating new SDK Runtime tests
16
17A simple example of using SDK Runtime testscenario utilities can be found in
18//packages/modules/AdServices/sdksandbox/tests/testutils/testscenario/example.
19
20If you need to add an entirely new JUnit test suite, you need to add both a JUnit test
21suite, and a new testable SDK.
22
23### Create a new Test SDK
24
25You will first need to define a new Sandbox SDK with your
26test cases. Create a new module for your sdk side tests.
27Inside it, create three new files:
28- AndroidManifest.xml
29- Android.bp
30- src/<package/path>/\<TestName>TestSdk.java
31
32Write to the `Android.bp`:
33
34```soong
35android_test_helper_app {
36    name: "<TestName>TestSdk",
37    manifest: "AndroidManifest.xml",
38    // This is a certificate provided by the
39    // sandbox test utilities that will be used
40    // by your JUnit test suite to load
41    // this sdk.
42    certificate: ":sdksandbox-test",
43    srcs: [
44       "src/**/*.java",
45    ],
46    platform_apis: true,
47    // This runner is used to execute SDK side tests.
48    static_libs: ["CtsSdkSandboxTestRunner"],
49    libs: ["android.test.base"],
50}
51```
52
53Write to the `AndroidManifest.xml`:
54
55```xml
56<!-- This is all normal configuration for a Sandbox SDK provider -->
57<manifest xmlns:android="http://schemas.android.com/apk/res/android"
58          package="<your.test.package>">
59
60    <application>
61        <sdk-library android:name="<your.test.package>"
62                     android:versionMajor="1" />
63        <property android:name="android.sdksandbox.PROPERTY_SDK_PROVIDER_CLASS_NAME"
64                  android:value="<your.test.package>.<TestName>TestSdk" />
65    </application>
66</manifest>
67```
68
69Finally define a test within \<TestName>Sdk.java (eg: ExampleSandboxTestSdk):
70
71```java
72import com.android.sdkSandboxTestUtils.SdkSandboxTestScenarioRunner;
73
74// The SdkSandboxTestScenarioRunner will be responsible
75// for listening for commands to execute tests from
76// the JUnit test suite and returning results.
77public class ExampleSandboxTestSdk extends SdkSandboxTestScenarioRunner {
78    @Override
79    public View beforeEachTest(Context windowContext, Bundle params, int width, int height) {
80        // You can optionally override this method to return a view
81        // that should be added to the sandbox before each test.
82        // ...
83    }
84
85    @Test
86    public void testExample() {
87        // You write tests as you normally would.
88        // These test failures will be propagated back to the JUnit
89        // test suite.
90        assertTrue(true);
91    }
92
93    // You can optionally expect parameters
94    // as part of the test definitions.
95    // This is useful for when tests require
96    // setup externally and need configuration.
97    // For example, a local host server is set up
98    // outside this test and this test needs to know
99    // what port it's running on.
100    @Test
101    public void testExampleWithParam(Bundle params) {
102        params.getString("someParameter");
103    }
104}
105```
106
107These tests will not execute on their own.
108They need to be invoked from a JUnit test suite.
109We will add this in the next section.
110
111### Invoke from a JUnit test suite
112
113This guide will skip over defining a new JUnit test suite,
114as this is the same as any other JUnit test suite in CTS.
115
116Within the `AndroidManifest.xml`, specify that the
117JUnit test suite APK relies on the SDK you defined:
118
119```xml
120<application>
121    <!-- Note the certificate should be what is defined here - this is sdksandbox-test -->
122    <uses-sdk-library android:name="<your.test.sdk.package>"
123        android:versionMajor="1"
124        android:certDigest="0B:44:2D:88:FA:A7:B3:AD:23:8D:DE:29:8A:A1:9B:D5:62:03:92:0B:BF:D8:D3:EB:C8:99:33:2C:8E:E1:15:99" />
125</application>
126```
127
128In `AndroidTest.xml`, specify that your test needs to install
129the SDK you created:
130
131```xml
132<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
133    <option name="test-file-name" value="<TestName>Sdk" />
134</target_preparer>
135```
136
137Finally, define that your SDK should
138be built and your JUnit test suite relies on
139CtsSdkSandboxTestScenario in your `Android.bp`:
140
141```soong
142...
143static_libs: [
144    // This will be used to invoke test methods
145    // from within the test Sandbox SDK.
146    "CtsSdkSandboxTestScenario",
147],
148data: [
149    // Define your test SDK as a data
150    // dependency so that it is built before
151    // this JUnit test suite is built.
152    ":<TestName>TestSdk",
153],
154...
155```
156
157You can now invoke tests from your JUnit test suite as shown. Note that
158SdkSandboxScenarioRule, when annotated as a @ClassRule, will create a new
159activity for each test, but persist the same test SDK for all tests. If for some
160reason the SDK is not found by a test, it will attempt to reload it.
161
162If you wish to run your tests in a way such that the test SDK is reloaded after
163each test, you can simply annotate the SdkSandboxScenarioRule as a @Rule and
164everything else remains the same.
165
166```java
167import android.app.sdksandbox.testutils.testscenario.SdkSandboxScenarioRule;
168
169public class ExampleSandboxTest {
170    // This rule will automatically create a new test activity
171    // and for each test but persist the Sdk.
172    @ClassRule
173    public static final SdkSandboxScenarioRule sdkTester = new SdkSandboxScenarioRule(
174        "your.test.sdk.package");
175
176    @Test
177    public void testExample() throws Throwable {
178        // This method will invoke a test and assert the results.
179        sdkTester.assertSdkTestRunPasses("testExample");
180
181        // You can optionally provide parameters to your
182        // tests for setup.
183        Bundle params = new Bundle();
184        params.put("someParameter", "A value");
185        sdkTester.assertSdkTestRunPasses("testExampleWithParam", params);
186    }
187}
188```
189
190## Custom test instances
191
192The `SdkSandboxTestScenarioRunner` supports invoking tests on different
193test instances from the class running your tests inside the test SDK.
194For example, you may have tests you wish to also run in a non SDK context.
195
196```java
197// You can define tests inside a separate class.
198public class ActuallyHasTests {
199    @Test
200    public void someTest() {
201        assertTrue(true);
202    }
203}
204
205public class ExampleSandboxTestSdk extends SdkSandboxTestScenarioRunner {
206    // And then optionally override the onLoadSdk method and use
207    // the API setTestInstance to set an instance to invoke tests from.
208    @Override
209    public SandboxedSdk onLoadSdk(Bundle params) {
210        setTestInstance(new ActuallyHasTests());
211        return super.onLoadSdk(params);
212    }
213}
214```
215
216## Custom setup
217
218There may be times when you need to pass through custom setup information to your sdk.
219
220You can optionally provide a Bundle
221(https://developer.android.com/reference/android/os/Bundle) to SdkSandboxScenarioRule
222that can be retrieved and used from inside test SDKs via the onLoadSdk method.
223
224One example is if you want to reuse an sdk in order to test multiple test instances. For this you
225could pass setup information to determine the specific test instance to use:
226
227```java
228public class ExampleSandboxTestSdk extends SdkSandboxTestScenarioRunner {
229
230    private ExampleParentTestClass mTestInstance;
231
232    @Override
233    public SandboxedSdk onLoadSdk(Bundle params) {
234        Bundle setupParams = params.getBundle(ISdkSandboxTestExecutor.TEST_SETUP_PARAMS);
235        if (setupParams != null) {
236            //logic for setting mTestInstance based on params
237            mTestInstance = new ExampleChildTestClass();
238        }
239
240        setTestInstance(mTestInstance);
241        return super.onLoadSdk(params);
242    }
243}
244```
245
246## Custom test binders
247
248There may be times where you want your tests to invoke behavior outside of
249the SDK. For example, you may want to perform a tap event using the instrumentation.
250
251You can optionally provide a custom [IBinder]
252(https://developer.android.com/reference/android/os/IBinder) to SdkSandboxScenarioRule
253that can be retrieved and used from inside test SDKs.
254
255In the example below, the following custom aidl will be used:
256
257```aidl
258interface SharedCustomBinder {
259    void doesSomethingOutsideSdk();
260}
261```
262
263```java
264public class ExampleSandboxTest {
265    // Provide a stub to the SdkSandboxScenarioRule.
266    @Rule
267    public final SdkSandboxScenarioRule sdkTester = new SdkSandboxScenarioRule(
268        "your.test.sdk.package", new SharedCustomBinder.Stub() {
269            public void doesSomethingOutsideSdk() {
270            }
271        });
272}
273
274public class ExampleSandboxTestSdk extends SdkSandboxTestScenarioRunner {
275    @Test
276    public void exampleTest() throws Exception {
277        // The IBinder can be retrieved inside SDK tests using the API
278        // getCustomInterface().
279        SharedCustomBinder binder = SharedCustomBinder.Stub.asInterface(getCustomInterface());
280        //
281        binder.doesSomethingOutsideSdk();
282        // ...
283    }
284}
285```
286