OLD | NEW |
---|---|
(Empty) | |
1 # How GTests work on Android | |
2 | |
3 gtests are [googletest](https://github.com/google/googletest)-based C++ tests. | |
4 On Android, they run on a device. In most cases, they're packaged as APKs, but | |
5 there are a few cases where they're run as raw executables. The latter is | |
6 necessary in a few cases, particularly when manipulating signal handlers, but | |
7 isn't possible when the suite needs to call back through the JNI into Java code. | |
8 | |
9 [TOC] | |
10 | |
11 ## APKs | |
12 | |
13 ### GN | |
14 | |
15 Gtest APKs are built by default by the | |
16 [test](https://codesearch.chromium.org/chromium/src/testing/test.gni?type=cs&q=f ile:%5Esrc%5C/testing%5C/test.gni$+template%5C("test"%5C)&sq=package:chromium) | |
17 template, e.g. | |
18 | |
19 ```python | |
20 test("sample_gtest") { | |
21 # ... | |
22 } | |
23 ``` | |
24 | |
25 This uses gn's native | |
26 [shared_library](https://chromium.googlesource.com/chromium/src/+/master/tools/g n/docs/reference.md#shared_library_Declare-a-shared-library-target) | |
27 target type along with the | |
28 [unittest_apk](https://codesearch.chromium.org/chromium/src/build/config/android /rules.gni?type=cs&q=file:%5Esrc%5C/build%5C/config%5C/android%5C/rules.gni$+tem plate%5C(%5C"unittest_apk%5C"%5C)&sq=package:chromium) | |
29 template to build an APK containing: | |
30 | |
31 - One or more .so files containing the native code on which the test suite | |
32 depends | |
33 - One or more .dex files containing the Java code on which the test suite | |
34 depends | |
35 - A [manifest](https://developer.android.com/guide/topics/manifest/manifest-int ro.html) | |
36 file that contains `<instrumentation>` and `<activity>` elements (among others). | |
37 | |
38 ### Harness | |
39 | |
40 GTest APKs are packaged with a harness that consists of: | |
41 | |
42 - [NativeTestInstrumentationTestRunner], an instrumentation entry point that | |
43 handles running one or more sequential instances of a test Activity. Typically, | |
44 unit test suites will only use one instance of the Activity and will run all of | |
45 the specified tests in it, while browser test suites will use multiple instances | |
46 and will only run one test per instance. | |
47 - Three [Activity](https://developer.android.com/reference/android/app/Activit y.html)-based | |
48 classes | |
49 ([NativeUnitTestActivity](https://codesearch.chromium.org/chromium/src/testing/a ndroid/native_test/java/src/org/chromium/native_test/NativeUnitTestActivity.java ), | |
50 [NativeUnitTestNativeActivity](https://codesearch.chromium.org/chromium/src/test ing/android/native_test/java/src/org/chromium/native_test/NativeUnitTestNativeAc tivity.java), | |
51 and | |
52 [NativeBrowserTestActivity](https://codesearch.chromium.org/chromium/src/testing /android/native_test/java/src/org/chromium/native_test/NativeBrowserTestActivity .java)) | |
53 that primarily act as process entry points for individual test shards. | |
54 Only one is used in any given suite. | |
55 - [NativeTest] and [NativeUnitTest], | |
56 which handle formatting arguments for googletest and transferring control across | |
57 the JNI. | |
58 - [testing::android::RunTests](https://codesearch.chromium.org/chromium/src/te sting/android/native_test/native_test_launcher.cc?q=file:%5Esrc%5C/testing%5C/an droid%5C/native_test%5C/native_test_launcher.cc$+RunTests&sq=package:chromium), | |
59 the function on the native side, which initializes the native command-line, | |
60 redirects stdout either to a FIFO or a regular file, optionally waits for a | |
61 debugger to attach to the process, sets up the test data directories, and then | |
62 dispatches to googletest's `main` function. | |
63 | |
64 ### Runtime | |
65 | |
66 1. The test runner calls `am instrument` with a bunch of arguments, | |
67 includes several extras that are arguments to either | |
68 [NativeTestInstrumentationTestRunner] or [NativeTest]. This results in an | |
69 intent being sent to [NativeTestInstrumentationTestRunner]. | |
70 2. [NativeTestInstrumentationTestRunner] is created. In its onCreate, it | |
71 parses its own arguments from the intent and retains all other arguments | |
72 to be passed to the Activities it'll start later. It also creates a | |
73 temporary file in the external storage directory for stdout. It finally | |
74 starts itself. | |
75 3. [NativeTestInstrumentationTestRunner] is started. In its onStart, it prepare s | |
76 to receive notifications about the start and end of the test run from the | |
77 Activities it's about to start. It then creates [ShardStarter] | |
78 that will start the first test shard and adds that to the current | |
79 [Handler](https://developer.android.com/reference/android/os/Handler.html). | |
80 4. The [ShardStarter] is executed, starting the test Activity. | |
81 5. The Activity starts, possibly doing some process initialization, and hands | |
82 off to the [NativeTest]. | |
83 6. The [NativeTest] handles some initialization and informs the | |
84 [NativeTestInstrumentationTestRunner] that it has started. On hearing this, | |
85 the [NativeTestInstrumentationTestRunner] creates a [ShardMonitor] | |
86 that will monitor the execution of the test Activity. | |
87 7. The [NativeTest] hands off to testing::android::RunTests. The tests run. | |
88 8. The [NativeTest] informs the [NativeTestInstrumentationTestRunner] that is h as | |
89 completed. On hearing this, the [ShardMonitor] creates a [ShardEnder]. | |
90 9. The [ShardEnder] is executed, killing the child process (if applicable), | |
91 parsing the results from the stdout file, and either launching the next | |
92 shard via [ShardStarter] (in which case the process returns to #4) or sendin g | |
93 the results out to the test runner and finishing the instrumentation. | |
94 | |
95 ## Executables | |
96 | |
97 ### GN | |
98 | |
99 Gtest executables are built by passing | |
100 `use_raw_android_executable = True` to the | |
101 [test](https://codesearch.chromium.org/chromium/src/testing/test.gni?type=cs&q=f ile:%5Esrc%5C/testing%5C/test.gni$+template%5C("test"%5C)&sq=package:chromium) | |
102 template, e.g. | |
103 | |
104 ```python | |
105 test("sample_gtest_executable") { | |
106 if (is_android) { | |
107 use_raw_android_executable = true | |
108 } | |
109 # ... | |
110 } | |
111 ``` | |
112 | |
113 This uses gn's native | |
114 [executable](https://chromium.googlesource.com/chromium/src/+/master/tools/gn/do cs/reference.md#executable_Declare-an-executable-target) | |
115 target type, then copies the resulting executable and any requisite shared libra ries | |
116 to ```${root_out_dir}/${target_name}__dist``` (e.g. ```out/Debug/breakpad_unitte sts__dist```). | |
117 | |
118 ### Harness | |
119 | |
120 Unlike APKs, gtest suites built as executables require no Android-specific harne sses. | |
121 | |
122 ### Runtime | |
123 | |
124 The test runner simply executes the binary directly and parses the stdout on | |
mikecase (-- gone --)
2016/09/07 18:55:23
question (kinda for me). Is the binary executed on
jbudorick
2016/09/08 00:32:56
On the device. Clarified here.
| |
125 its own. | |
126 | |
127 [NativeTest]: https://codesearch.chromium.org/chromium/src/testing/android/nativ e_test/java/src/org/chromium/native_test/NativeTest.java | |
128 [NativeTestInstrumentationTestRunner]: https://codesearch.chromium.org/chromium/ src/testing/android/native_test/java/src/org/chromium/native_test/NativeTestInst rumentationTestRunner.java | |
129 [NativeUnitTest]: https://codesearch.chromium.org/chromium/src/testing/android/n ative_test/java/src/org/chromium/native_test/NativeUnitTest.java | |
130 [ShardEnder]: https://codesearch.chromium.org/chromium/src/testing/android/nativ e_test/java/src/org/chromium/native_test/NativeTestInstrumentationTestRunner.jav a?q=file:NativeTestInstrumentationTestRunner.java+class:ShardEnder&sq=package:ch romium | |
131 [ShardMonitor]: https://codesearch.chromium.org/chromium/src/testing/android/nat ive_test/java/src/org/chromium/native_test/NativeTestInstrumentationTestRunner.j ava?q=file:NativeTestInstrumentationTestRunner.java+class:ShardMonitor&sq=packag e:chromium | |
132 [ShardStarter]: https://codesearch.chromium.org/chromium/src/testing/android/nat ive_test/java/src/org/chromium/native_test/NativeTestInstrumentationTestRunner.j ava?q=file:NativeTestInstrumentationTestRunner.java+class:ShardStarter&sq=packag e:chromium | |
OLD | NEW |