blob: e761bd928f33c545032a0374df1406a3097b99e8 [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
82class in your eg2_tests target, but you need to include and refer to it. If you
83see a Undefined symbols for architecture MyTestAppInterface”, add
84```
85#if defined(CHROME_EARL_GREY_2)
86// TODO(crbug.com/1015113) The EG2 macro is breaking indexing for some reason
87// without the trailing semicolon. For now, disable the extra semi warning
88// so Xcode indexing works for the egtest.
89#pragma clang diagnostic push
90#pragma clang diagnostic ignored "-Wc++98-compat-extra-semi"
91GREY_STUB_CLASS_IN_APP_MAIN_QUEUE(HandoffManagerAppInterface);
92#pragma clang diagnostic pop
93#endif // defined(CHROME_EARL_GREY_2)
94```
95to the top of your foo_egtest.mm file.
96
97#### Creating test targets and adding the target to test suites
98
991. Create a test target. Add a target(`source_set`) named "eg2_tests" into the
100closest `BUILD.gn` file. Put the test file into the `sources` array and put the
101targets containing headers used in your test file into `deps` array. This is to
102organize test source files and dependencies so that the GN build system can
103correctly build the test module. The skeleton of the target:
104```
105source_set("eg2_tests") {
106 configs += [
107 "//build/config/compiler:enable_arc",
108 "//build/config/ios:xctest_config",
109 ]
110 testonly = true
111 sources = [
112 "some_egtest.mm"
113 ]
114 deps = [
115 "//ios/chrome/test/earl_grey:eg_test_support+eg2",
116 "//ios/testing/earl_grey:eg_test_support+eg2",
117 "//ios/third_party/earl_grey2:test_lib",
118 ]
119 libs = [ "UIKit.framework" ]
120}
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, youll 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.
1422. Change the scheme to "ios_chrome_eg2test". Create and select the simulator
143you wish to use.
1443. You may run a test suite(module), TestCase or testMethod in test navigator.
145Xcode will build the targets and run the test(s) you choose. Alternatively,
146use ⌘+U to run all the tests. See Apple's [Running Tests and Viewing Results].
Mike Baxley47db7d82017-11-16 15:57:17147
148#### Running from the command-line
149
Zhaoyang Li270020462020-10-27 23:07:29150EG2 tests can run in the command line with test runner scripts. Youll need to
151build the targets before running tests in cmd. This is used by continuous
152integration infra and thus not user friendly. Running UI tests directly in Xcode
153is recommended.
154
155Important notes:
156* The test runner can invoke mac_toolchain to install a new Xcode of the version
157specified to the path specified. You may want to choose a different path from
158your daily use Xcode.
159* If test_cases is empty in --args-json, all tests will run. Specifying a
160testMethod to run is currently not supported in the test runner.
161
Mike Baxley47db7d82017-11-16 15:57:17162Example:
163```
Zhaoyang Li270020462020-10-27 23:07:29164src/ios/build/bots/scripts/run.py
165 --app
166 src/out/Debug-iphonesimulator/ios_chrome_ui_eg2tests_module-Runner.app
167 --host-app
168 src/out/Debug-iphonesimulator/ios_chrome_eg2tests.app
169 --args-json
170 {"test_args": [], "xctest": false, "test_cases": ["ReadingListTestCase"],
171 "restart": false, "xcode_parallelization": true, "xcodebuild_device_runner":
172 false}
173 --out-dir
174 path/to/output/dir
175 --retries
176 3
177 --shards
178 1
179 --xcode-build-version
180 11c29
181 --mac-toolchain-cmd
182 path/to/mac_toolchain
183 --xcode-path
184 path/to/Xcode.app
185 --wpr-tools-path
186 NO_PATH
187 --replay-path
188 NO_PATH
189 --iossim
190 src/out/Debug-iphonesimulator/iossim
191 --platform
192 iPad (6th generation)
193 --version
194 13.3
Mike Baxley47db7d82017-11-16 15:57:17195```
Zhaoyang Li270020462020-10-27 23:07:29196The invocation args are logged. You can find the latest arg format at the
197beginning of stdout from an infra test shard if the above doesn't work.
Mike Baxley47db7d82017-11-16 15:57:17198
199
Zhaoyang Li270020462020-10-27 23:07:29200[config the bots]: https://chromium.googlesource.com/chromium/src/testing/+/refs/heads/master/buildbot/README.md#buildbot-testing-configuration-files
201[Defining Test Cases and Test Methods]: https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods?language=objc
202[EarlGrey]: https://github.com/google/EarlGrey/tree/earlgrey2
203[EarlGrey APIs]: https://github.com/google/EarlGrey/blob/master/docs/api.md
204[eDO]: https://github.com/google/eDistantObject
205[Example of App Interface]: https://cs.chromium.org/chromium/src/ios/chrome/browser/metrics/metrics_app_interface.h
206[Example CL adding App Interface]: https://chromium-review.googlesource.com/c/chromium/src/+/1919147
Mike Baxley47db7d82017-11-16 15:57:17207[instructions]: ./build_instructions.md
Zhaoyang Li270020462020-10-27 23:07:29208[Running Tests and Viewing Results]: https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/testing_with_xcode/chapters/05-running_tests.html
209[this AppLaunchManager API]: https://source.chromium.org/chromium/chromium/src/+/master:ios/testing/earl_grey/app_launch_manager.h;drc=d0889865de20c5b3bc59d58674eb2dcc02dd2269;l=47
Mike Baxley47db7d82017-11-16 15:57:17210[XCUITest]: https://developer.apple.com/documentation/xctest