blob: f6d3920fcaad04832d2d9bb34145e4559587aef4 [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 ```
Ernesto Izquierdo Cluaab3923fd2022-03-01 20:42:1532 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
Zhaoyang Li270020462020-10-27 23:07:2933 ```
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
Cameron Higgins0e350192023-03-21 17:43:4590#import "ios/testing/earl_grey/earl_grey_test.h"
Sylvain Defresnea852434c2021-10-15 07:53:3991
Sylvain Defresnea852434c2021-10-15 07:53:3992GREY_STUB_CLASS_IN_APP_MAIN_QUEUE(MyTestAppInterface)
93
Zhaoyang Li270020462020-10-27 23:07:2994```
Sylvain Defresnea852434c2021-10-15 07:53:3995
96If you don't you'll get linker errors that read like “Undefined symbols for
97architecture… MyTestAppInterface”
Zhaoyang Li270020462020-10-27 23:07:2998
99#### Creating test targets and adding the target to test suites
100
1011. Create a test target. Add a target(`source_set`) named "eg2_tests" into the
102closest `BUILD.gn` file. Put the test file into the `sources` array and put the
103targets containing headers used in your test file into `deps` array. This is to
104organize test source files and dependencies so that the GN build system can
105correctly build the test module. The skeleton of the target:
106```
107source_set("eg2_tests") {
108 configs += [
Zhaoyang Li270020462020-10-27 23:07:29109 "//build/config/ios:xctest_config",
110 ]
111 testonly = true
112 sources = [
113 "some_egtest.mm"
114 ]
115 deps = [
116 "//ios/chrome/test/earl_grey:eg_test_support+eg2",
117 "//ios/testing/earl_grey:eg_test_support+eg2",
Zhaoyang Li270020462020-10-27 23:07:29118 ]
Arthur Milchior54e9dc22022-09-21 13:41:52119 frameworks = [ "UIKit.framework" ]
Zhaoyang Li270020462020-10-27 23:07:29120}
121```
1222. Include your test target in the `deps` array of a suitable suite in
123`//src/ios/chrome/test/earl_grey2/BUILD.gn`.
1243. Optional: If you feel like your new test should be in a new suite, or you
125want to delete an existing suite to make tests better organized, you’ll need to
126change the suites in `//src/ios/chrome/test/earl_grey2/BUILD.gn` in the format
127of existing ones. (Do not forget to [config the bots] so the new suite can run
128in infra.)
1294. Ensure your dependencies are correct.
130```
131$ gn gen --check out/Debug-iphonesimulator
132```
Mike Baxley47db7d82017-11-16 15:57:17133
134### Running EarlGrey tests
135
136EarlGrey tests are based on Apple's [XCUITest].
137
138#### Running tests from Xcode
139
Zhaoyang Li270020462020-10-27 23:07:291401. If you added a new test file / suite, run `gclient runhooks` to sync for the
141list of tests in Xcode.
Victor Hugo Vianna Silva703246b2023-07-05 14:06:461422. Run a test suite(module), TestCase or testMethod in test navigator.
Zhaoyang Li270020462020-10-27 23:07:29143Xcode will build the targets and run the test(s) you choose. Alternatively,
144use ⌘+U to run all the tests. See Apple's [Running Tests and Viewing Results].
Victor Hugo Vianna Silva703246b2023-07-05 14:06:461453. You can pass extra arguments to the app process with `--extra-app-args`, e.g.
146`--extra-app-args='--enable-features=Foo'`.
147 * This might not work consistently as tests can re-launch the app with
148 arbitrary command-line arguments.
149
Mike Baxley47db7d82017-11-16 15:57:17150
151#### Running from the command-line
152
Zhaoyang Li270020462020-10-27 23:07:29153EG2 tests can run in the command line with test runner scripts. You’ll need to
154build the targets before running tests in cmd. This is used by continuous
155integration infra and thus not user friendly. Running UI tests directly in Xcode
156is recommended.
157
158Important notes:
159* The test runner can invoke mac_toolchain to install a new Xcode of the version
160specified to the path specified. You may want to choose a different path from
161your daily use Xcode.
162* If test_cases is empty in --args-json, all tests will run. Specifying a
163testMethod to run is currently not supported in the test runner.
164
Mike Baxley47db7d82017-11-16 15:57:17165Example:
166```
Zhaoyang Li270020462020-10-27 23:07:29167src/ios/build/bots/scripts/run.py
168 --app
169 src/out/Debug-iphonesimulator/ios_chrome_ui_eg2tests_module-Runner.app
170 --host-app
171 src/out/Debug-iphonesimulator/ios_chrome_eg2tests.app
172 --args-json
173 {"test_args": [], "xctest": false, "test_cases": ["ReadingListTestCase"],
174 "restart": false, "xcode_parallelization": true, "xcodebuild_device_runner":
175 false}
176 --out-dir
177 path/to/output/dir
178 --retries
179 3
180 --shards
181 1
182 --xcode-build-version
183 11c29
184 --mac-toolchain-cmd
185 path/to/mac_toolchain
186 --xcode-path
187 path/to/Xcode.app
188 --wpr-tools-path
189 NO_PATH
190 --replay-path
191 NO_PATH
192 --iossim
193 src/out/Debug-iphonesimulator/iossim
194 --platform
195 iPad (6th generation)
196 --version
197 13.3
Mike Baxley47db7d82017-11-16 15:57:17198```
Zhaoyang Li270020462020-10-27 23:07:29199The invocation args are logged. You can find the latest arg format at the
200beginning of stdout from an infra test shard if the above doesn't work.
Mike Baxley47db7d82017-11-16 15:57:17201
202
John Palmer046f9872021-05-24 01:24:56203[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:29204[Defining Test Cases and Test Methods]: https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods?language=objc
205[EarlGrey]: https://github.com/google/EarlGrey/tree/earlgrey2
206[EarlGrey APIs]: https://github.com/google/EarlGrey/blob/master/docs/api.md
207[eDO]: https://github.com/google/eDistantObject
Stepan Khapugind8ca0ad2023-11-28 12:49:06208[Example of App Interface]: https://cs.chromium.org/chromium/src/ios/chrome/browser/metrics/model/metrics_app_interface.h
Zhaoyang Li270020462020-10-27 23:07:29209[Example CL adding App Interface]: https://chromium-review.googlesource.com/c/chromium/src/+/1919147
Mike Baxley47db7d82017-11-16 15:57:17210[instructions]: ./build_instructions.md
Zhaoyang Li270020462020-10-27 23:07:29211[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:56212[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:17213[XCUITest]: https://developer.apple.com/documentation/xctest