blob: 5a26ddfbb7c902a7133ae1d0bd7f2f3c416c1cc5 [file] [log] [blame] [view]
Mike Baxley47db7d82017-11-16 15:57:171# Automated testing for Chrome for iOS
2
3See the [instructions] for how to check out and build Chromium for iOS.
4
5Automated testing is a crucial part of ensuring the quality of Chromium.
6
7## Unit testing
8
9Unit testing is done via gtests. To run a unit test, simply run the test
10target (ending in _unittest).
11
12## Integration testing
13
Zhaoyang Li270020462020-10-27 23:07:2914[EarlGrey] (EG2) is the integration testing framework used by Chromium for iOS.
15
16### Writing EarlGrey tests
17
18#### Before you start
19
20* Just write a unit test if the purpose of your test does not involve UI.
21* Learn about EarlGrey test framework principles and APIs in [EarlGrey].
22* Learn about [Defining Test Cases and Test Methods] from Apple.
23
24#### Creating test files and writing EG2 tests
25
261. EG2 test files are ended with _egtest.mm, and usually located within the same
27directory of the UI code you wish to test.
282. Basic imports of a EG2 test file:
29
30 * Youll have to include:
31 ```
32 #import "ios/chrome/test/earl_grey/chrome_test_case.h
33 ```
34 * Youll most likely find util functions in these files helpful.
35 ```
36 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
37 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
38 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
39 ```
40 * Beside these, directly import an EG2 header for an EG2 API you are using.
41
423. TestCase/testMethods definitions. Create `SomeGreatTestCase` as a subclass of
43`ChromeTestCase`. Create test methods, eg `-(void)testMyGreatUIFeature {...}`,
44and put UI actions within the test methods.
45 * Put your setup and tear down code for the *TestCase* in
46`+(void)setUpForTestCase` and `+tearDown`. These will run once before and
47after all tests for the test class.
48 * Put your setup and tear down code for each *test method* in `-(void)setUp`
49and `-(void)tearDown`. These will run before and after every
50`-(void)testMethod` in the file.
514. Writing test contents. See the chrome helpers (imports in 2.) as well as
52[EarlGrey APIs] to write a UI action/assertion in your testMethod.
53
54#### Interacting with the app in a test
55
56##### Relaunch app with different flags
57
58In EG2 tests, the test process launches the host app process at the beginning,
59then runs UI actions/assertions in the app. To pass args or feature flags to the
60app at initial launching, or relaunch the app in the middle of your test, see
61[this AppLaunchManager API].
62
63##### Accessing app internals
64
65EG2 test targets are built with test-related code but without app code.
66
67To access anything from the app side, use an "app interface". App interface is
68implemented as a class that lives in the app process, but can be accessed in the
69test process through [eDO]. You can include the header in your test side code
70and call class methods of the interface class. The methods will execute code in
71the app process and can return basic Objective-C types. See this [Example of App
72 Interface].
73
74See `eg_test_support+eg2` (test side utilities) and `eg_app_support+eg2` (app
75side utilities) targets in `BUILD.gn` files to learn how test utilities are
76organized in targets. If you added an app side helper (app interface), youll
77also need to include your new `eg_app_support+eg2` target in
78`//ios/chrome/test/earl_grey/BUILD.gn`s `eg_app_support+eg2` target. ([Example
79 CL adding App Interface]).
80
81Note that if you create an App interface, you cant build the app interface
Sylvain Defresnea852434c2021-10-15 07:53:3982class in your eg2_tests target, but you need to include and refer to it. To
83satisfy the linker, you'll need to create a `my_test_app_interface_stub.mm`
84file with the following content in it and build it as a dependency of your
85tests that use the app interface.
86
87```objc
88#import "ios_internal/chrome/test/earl_grey2/my_test_app_interface.h"
89
90#import <TestLib/EarlGreyImpl/EarlGrey.h>
91
92#if !defined(__has_feature) || !__has_feature(objc_arc)
93#error "This file requires ARC support."
94#endif
95
96GREY_STUB_CLASS_IN_APP_MAIN_QUEUE(MyTestAppInterface)
97
Zhaoyang Li270020462020-10-27 23:07:2998```
Sylvain Defresnea852434c2021-10-15 07:53:3999
100If you don't you'll get linker errors that read like “Undefined symbols for
101architecture… MyTestAppInterface”
Zhaoyang Li270020462020-10-27 23:07:29102
103#### Creating test targets and adding the target to test suites
104
1051. Create a test target. Add a target(`source_set`) named "eg2_tests" into the
106closest `BUILD.gn` file. Put the test file into the `sources` array and put the
107targets containing headers used in your test file into `deps` array. This is to
108organize test source files and dependencies so that the GN build system can
109correctly build the test module. The skeleton of the target:
110```
111source_set("eg2_tests") {
112 configs += [
113 "//build/config/compiler:enable_arc",
114 "//build/config/ios:xctest_config",
115 ]
116 testonly = true
117 sources = [
118 "some_egtest.mm"
119 ]
120 deps = [
121 "//ios/chrome/test/earl_grey:eg_test_support+eg2",
122 "//ios/testing/earl_grey:eg_test_support+eg2",
123 "//ios/third_party/earl_grey2:test_lib",
124 ]
125 libs = [ "UIKit.framework" ]
126}
127```
1282. Include your test target in the `deps` array of a suitable suite in
129`//src/ios/chrome/test/earl_grey2/BUILD.gn`.
1303. Optional: If you feel like your new test should be in a new suite, or you
131want to delete an existing suite to make tests better organized, you’ll need to
132change the suites in `//src/ios/chrome/test/earl_grey2/BUILD.gn` in the format
133of existing ones. (Do not forget to [config the bots] so the new suite can run
134in infra.)
1354. Ensure your dependencies are correct.
136```
137$ gn gen --check out/Debug-iphonesimulator
138```
Mike Baxley47db7d82017-11-16 15:57:17139
140### Running EarlGrey tests
141
142EarlGrey tests are based on Apple's [XCUITest].
143
144#### Running tests from Xcode
145
Zhaoyang Li270020462020-10-27 23:07:291461. If you added a new test file / suite, run `gclient runhooks` to sync for the
147list of tests in Xcode.
1482. Change the scheme to "ios_chrome_eg2test". Create and select the simulator
149you wish to use.
1503. You may run a test suite(module), TestCase or testMethod in test navigator.
151Xcode will build the targets and run the test(s) you choose. Alternatively,
152use ⌘+U to run all the tests. See Apple's [Running Tests and Viewing Results].
Mike Baxley47db7d82017-11-16 15:57:17153
154#### Running from the command-line
155
Zhaoyang Li270020462020-10-27 23:07:29156EG2 tests can run in the command line with test runner scripts. You’ll need to
157build the targets before running tests in cmd. This is used by continuous
158integration infra and thus not user friendly. Running UI tests directly in Xcode
159is recommended.
160
161Important notes:
162* The test runner can invoke mac_toolchain to install a new Xcode of the version
163specified to the path specified. You may want to choose a different path from
164your daily use Xcode.
165* If test_cases is empty in --args-json, all tests will run. Specifying a
166testMethod to run is currently not supported in the test runner.
167
Mike Baxley47db7d82017-11-16 15:57:17168Example:
169```
Zhaoyang Li270020462020-10-27 23:07:29170src/ios/build/bots/scripts/run.py
171 --app
172 src/out/Debug-iphonesimulator/ios_chrome_ui_eg2tests_module-Runner.app
173 --host-app
174 src/out/Debug-iphonesimulator/ios_chrome_eg2tests.app
175 --args-json
176 {"test_args": [], "xctest": false, "test_cases": ["ReadingListTestCase"],
177 "restart": false, "xcode_parallelization": true, "xcodebuild_device_runner":
178 false}
179 --out-dir
180 path/to/output/dir
181 --retries
182 3
183 --shards
184 1
185 --xcode-build-version
186 11c29
187 --mac-toolchain-cmd
188 path/to/mac_toolchain
189 --xcode-path
190 path/to/Xcode.app
191 --wpr-tools-path
192 NO_PATH
193 --replay-path
194 NO_PATH
195 --iossim
196 src/out/Debug-iphonesimulator/iossim
197 --platform
198 iPad (6th generation)
199 --version
200 13.3
Mike Baxley47db7d82017-11-16 15:57:17201```
Zhaoyang Li270020462020-10-27 23:07:29202The invocation args are logged. You can find the latest arg format at the
203beginning of stdout from an infra test shard if the above doesn't work.
Mike Baxley47db7d82017-11-16 15:57:17204
205
John Palmer046f9872021-05-24 01:24:56206[config the bots]: https://chromium.googlesource.com/chromium/src/testing/+/refs/heads/main/buildbot/README.md#buildbot-testing-configuration-files
Zhaoyang Li270020462020-10-27 23:07:29207[Defining Test Cases and Test Methods]: https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods?language=objc
208[EarlGrey]: https://github.com/google/EarlGrey/tree/earlgrey2
209[EarlGrey APIs]: https://github.com/google/EarlGrey/blob/master/docs/api.md
210[eDO]: https://github.com/google/eDistantObject
211[Example of App Interface]: https://cs.chromium.org/chromium/src/ios/chrome/browser/metrics/metrics_app_interface.h
212[Example CL adding App Interface]: https://chromium-review.googlesource.com/c/chromium/src/+/1919147
Mike Baxley47db7d82017-11-16 15:57:17213[instructions]: ./build_instructions.md
Zhaoyang Li270020462020-10-27 23:07:29214[Running Tests and Viewing Results]: https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/testing_with_xcode/chapters/05-running_tests.html
John Palmer046f9872021-05-24 01:24:56215[this AppLaunchManager API]: https://source.chromium.org/chromium/chromium/src/+/main:ios/testing/earl_grey/app_launch_manager.h;drc=d0889865de20c5b3bc59d58674eb2dcc02dd2269;l=47
Mike Baxley47db7d82017-11-16 15:57:17216[XCUITest]: https://developer.apple.com/documentation/xctest