blob: 0bac81ec1004a10b775e9184f276c254ded134ed [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
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",
Zhaoyang Li270020462020-10-27 23:07:29123 ]
Arthur Milchior54e9dc22022-09-21 13:41:52124 frameworks = [ "UIKit.framework" ]
Zhaoyang Li270020462020-10-27 23:07:29125}
126```
1272. Include your test target in the `deps` array of a suitable suite in
128`//src/ios/chrome/test/earl_grey2/BUILD.gn`.
1293. Optional: If you feel like your new test should be in a new suite, or you
130want to delete an existing suite to make tests better organized, you’ll need to
131change the suites in `//src/ios/chrome/test/earl_grey2/BUILD.gn` in the format
132of existing ones. (Do not forget to [config the bots] so the new suite can run
133in infra.)
1344. Ensure your dependencies are correct.
135```
136$ gn gen --check out/Debug-iphonesimulator
137```
Mike Baxley47db7d82017-11-16 15:57:17138
139### Running EarlGrey tests
140
141EarlGrey tests are based on Apple's [XCUITest].
142
143#### Running tests from Xcode
144
Zhaoyang Li270020462020-10-27 23:07:291451. If you added a new test file / suite, run `gclient runhooks` to sync for the
146list of tests in Xcode.
Victor Hugo Vianna Silva703246b2023-07-05 14:06:461472. Run a test suite(module), TestCase or testMethod in test navigator.
Zhaoyang Li270020462020-10-27 23:07:29148Xcode will build the targets and run the test(s) you choose. Alternatively,
149use ⌘+U to run all the tests. See Apple's [Running Tests and Viewing Results].
Victor Hugo Vianna Silva703246b2023-07-05 14:06:461503. You can pass extra arguments to the app process with `--extra-app-args`, e.g.
151`--extra-app-args='--enable-features=Foo'`.
152 * This might not work consistently as tests can re-launch the app with
153 arbitrary command-line arguments.
154
Mike Baxley47db7d82017-11-16 15:57:17155
156#### Running from the command-line
157
Zhaoyang Li270020462020-10-27 23:07:29158EG2 tests can run in the command line with test runner scripts. You’ll need to
159build the targets before running tests in cmd. This is used by continuous
160integration infra and thus not user friendly. Running UI tests directly in Xcode
161is recommended.
162
163Important notes:
164* The test runner can invoke mac_toolchain to install a new Xcode of the version
165specified to the path specified. You may want to choose a different path from
166your daily use Xcode.
167* If test_cases is empty in --args-json, all tests will run. Specifying a
168testMethod to run is currently not supported in the test runner.
169
Mike Baxley47db7d82017-11-16 15:57:17170Example:
171```
Zhaoyang Li270020462020-10-27 23:07:29172src/ios/build/bots/scripts/run.py
173 --app
174 src/out/Debug-iphonesimulator/ios_chrome_ui_eg2tests_module-Runner.app
175 --host-app
176 src/out/Debug-iphonesimulator/ios_chrome_eg2tests.app
177 --args-json
178 {"test_args": [], "xctest": false, "test_cases": ["ReadingListTestCase"],
179 "restart": false, "xcode_parallelization": true, "xcodebuild_device_runner":
180 false}
181 --out-dir
182 path/to/output/dir
183 --retries
184 3
185 --shards
186 1
187 --xcode-build-version
188 11c29
189 --mac-toolchain-cmd
190 path/to/mac_toolchain
191 --xcode-path
192 path/to/Xcode.app
193 --wpr-tools-path
194 NO_PATH
195 --replay-path
196 NO_PATH
197 --iossim
198 src/out/Debug-iphonesimulator/iossim
199 --platform
200 iPad (6th generation)
201 --version
202 13.3
Mike Baxley47db7d82017-11-16 15:57:17203```
Zhaoyang Li270020462020-10-27 23:07:29204The invocation args are logged. You can find the latest arg format at the
205beginning of stdout from an infra test shard if the above doesn't work.
Mike Baxley47db7d82017-11-16 15:57:17206
207
John Palmer046f9872021-05-24 01:24:56208[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:29209[Defining Test Cases and Test Methods]: https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods?language=objc
210[EarlGrey]: https://github.com/google/EarlGrey/tree/earlgrey2
211[EarlGrey APIs]: https://github.com/google/EarlGrey/blob/master/docs/api.md
212[eDO]: https://github.com/google/eDistantObject
213[Example of App Interface]: https://cs.chromium.org/chromium/src/ios/chrome/browser/metrics/metrics_app_interface.h
214[Example CL adding App Interface]: https://chromium-review.googlesource.com/c/chromium/src/+/1919147
Mike Baxley47db7d82017-11-16 15:57:17215[instructions]: ./build_instructions.md
Zhaoyang Li270020462020-10-27 23:07:29216[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:56217[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:17218[XCUITest]: https://developer.apple.com/documentation/xctest