blob: ac1d21fc1fc07b1304f7d2bac856ddaba4d0a141 [file] [log] [blame] [view]
Kent Tamura59ffb022018-11-27 05:30:561# Web Tests Tips
pwnall59aadcb2017-01-26 23:27:212
3The recommendations here are intended to help you write new tests that go
4through code review with a minimal number of round trips, remain useful as Blink
5evolves, and serve as an asset (rather than a liability) for the team.
6
Kent Tamura59ffb022018-11-27 05:30:567While reading existing web tests, please keep in mind that they represent
pwnall59aadcb2017-01-26 23:27:218snapshots taken over many years of an ever-evolving collective opinion of what
9good Web pages and solid tests should look like. Thus, it should not come as a
Kent Tamura59ffb022018-11-27 05:30:5610surprise that most existing web tests are not consistent with these
pwnall59aadcb2017-01-26 23:27:2111recommendations, and are not even consistent with each other.
12
13*** note
14This document intentionally uses _should_ a lot more than _must_, as defined in
Kent Tamura59ffb022018-11-27 05:30:5615[RFC 2119](https://www.ietf.org/rfc/rfc2119.txt). Writing web tests is a
pwnall59aadcb2017-01-26 23:27:2116careful act of balancing many concerns, and this humble document cannot possibly
17capture the context that rests in the head of an experienced Blink engineer.
18***
19
20## General Principles
21
22This section contains guidelines adopted from
Philip Jägenstedt3a3d5b82018-05-31 15:25:3523[web-platform-tests documentation](https://web-platform-tests.org/writing-tests/general-guidelines.html)
pwnall59aadcb2017-01-26 23:27:2124and
25[WebKit's Wiki page on Writing good test cases](https://trac.webkit.org/wiki/Writing%20Layout%20Tests%20for%20DumpRenderTree),
26with Blink-specific flavoring.
27
28### Concise
29
30Tests should be **concise**, without compromising on the principles below. Every
31element and piece of code on the page should be necessary and relevant to what
32is being tested. For example, don't build a fully functional signup form if you
33only need a text field or a button.
34
35Content needed to satisfy the principles below is considered necessary. For
36example, it is acceptable and desirable to add elements that make the test
37self-describing (see below), and to add code that makes the test more reliable
38(see below).
39
40Content that makes test failures easier to debug is considered necessary (to
41maintaining a good development speed), and is both acceptable and desirable.
42
43*** promo
44Conciseness is particularly important for reference tests and pixel tests, as
45the test pages are rendered in an 800x600px viewport. Having content outside the
46viewport is undesirable because the outside content does not get compared, and
47because the resulting scrollbars are platform-specific UI widgets, making the
48test results less reliable.
49***
50
51### Fast
52
53Tests should be as **fast** as possible, without compromising on the principles
Kent Tamura59ffb022018-11-27 05:30:5654below. Blink has several thousand web tests that are run in parallel, and
pwnall59aadcb2017-01-26 23:27:2155avoiding unnecessary delays is crucial to keeping our Commit Queue in good
56shape.
57
58Avoid
59[window.setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout),
60as it wastes time on the testing infrastructure. Instead, use specific event
61handlers, such as
62[window.onload](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload),
63to decide when to advance to the next step in a test.
64
65### Reliable
66
67Tests should be **reliable** and yield consistent results for a given
68implementation. Flaky tests slow down your fellow developers' debugging efforts
69and the Commit Queue.
70
71`window.setTimeout` is again a primary offender here. Asides from wasting time
72on a fast system, tests that rely on fixed timeouts can fail when on systems
73that are slower than expected.
74
Kent Tamura59ffb022018-11-27 05:30:5675When adding or significantly modifying a web test, use the command below to
pwnall59aadcb2017-01-26 23:27:2176assess its flakiness. While not foolproof, this approach gives you some
77confidence, and giving up CPU cycles for mental energy is a pretty good trade.
78
79```bash
Kent Tamuraa045a7f2018-04-25 05:08:1180third_party/blink/tools/run_web_tests.py path/to/test.html --repeat-each=100
pwnall59aadcb2017-01-26 23:27:2181```
82
83The
Kent Tamura59ffb022018-11-27 05:30:5684[PSA on writing reliable web tests](https://docs.google.com/document/d/1Yl4SnTLBWmY1O99_BTtQvuoffP8YM9HZx2YPkEsaduQ/edit).
pwnall59aadcb2017-01-26 23:27:2185also has good guidelines for writing reliable tests.
86
87### Self-Describing
88
89Tests should be **self-describing**, so that a project member can recognize
90whether a test passes or fails without having to read the specification of the
91feature being tested.
92
93`testharness.js` makes a test self-describing when used correctly. Other types
94of tests, such as reference tests and
Kent Tamura59ffb022018-11-27 05:30:5695[tests with manual fallback](./web_tests_with_manual_fallback.md),
Philip Jägenstedt3a3d5b82018-05-31 15:25:3596[must be carefully designed](https://web-platform-tests.org/writing-tests/manual.html#requirements-for-a-manual-test)
pwnall59aadcb2017-01-26 23:27:2197to be self-describing.
98
99### Minimal
100
101Tests should require a **minimal** amount of cognitive effort to read and
102maintain.
103
104Avoid depending on edge case behavior of features that aren't explicitly covered
105by the test. For example, except where testing parsing, tests should contain
106valid markup (no parsing errors).
107
108Tests should provide as much relevant information as possible when failing.
109`testharness.js` tests should prefer
Philip Jägenstedt3a3d5b82018-05-31 15:25:35110[rich assert_ functions](https://web-platform-tests.org/writing-tests/testharness-api.html#list-of-assertions)
pwnall59aadcb2017-01-26 23:27:21111to combining `assert_true()` with a boolean operator. Using appropriate
112`assert_` functions results in better diagnostic output when the assertion
113fails.
114
115### Cross-Platform
116
117Tests should be as **cross-platform** as reasonably possible. Avoid assumptions
118about device type, screen resolution, etc. Unavoidable assumptions should be
119documented.
120
121When possible, tests should only use Web platform features, as specified
122in the relevant standards. When the Web platform's APIs are insufficient,
123tests should prefer to use WPT extended testing APIs, such as
124`wpt_automation`, over Blink-specific testing APIs.
125
126Test pages should use the HTML5 doctype (`<!doctype html>`) unless they
127specifically cover
128[quirks mode](https://developer.mozilla.org/docs/Quirks_Mode_and_Standards_Mode)
129behavior.
130
131Tests should avoid using features that haven't been shipped by the
132actively-developed major rendering engines (Blink, WebKit, Gecko, Edge). When
133unsure, check [caniuse.com](http://caniuse.com/). By necessity, this
134recommendation does not apply to the feature targeted by the test.
135
136*** note
137It may be tempting have a test for a bleeding-edge feature X depend on feature
138Y, which has only shipped in beta / development versions of various browsers.
139The reasoning would be that all browsers that implement X will have implemented
140Y. Please keep in mind that Chrome has un-shipped features that made it to the
141Beta channel in the past.
142***
143
144*** aside
145[ES2015](http://benmccormick.org/2015/09/14/es5-es6-es2016-es-next-whats-going-on-with-javascript-versioning/)
146is shipped by all major browsers under active development (except for modules),
147so using ES2015 features is acceptable.
148
149At the time of this writing, ES2016 is not fully shipped in all major browsers.
150***
151
152### Self-Contained
153
154Tests must be **self-contained** and not depend on external network resources.
155
156Unless used by multiple test files, CSS and JavaScript should be inlined using
157`<style>` and `<script>` tags. Content shared by multiple tests should be
158placed in a `resources/` directory near the tests that share it. See below for
159using multiple origins in a test.
160
161### File Names
162
163Test **file names** should describe what is being tested.
164
165File names should use `snake-case`, but preserve the case of any embedded API
166names. For example, prefer `document-createElement.html` to
167`document-create-element.html`.
168
169### Character Encoding
170
171Tests should use the UTF-8 **character encoding**, which should be declared by
172`<meta charset=utf-8>`. A `<meta>` tag is not required (but is acceptable) for
173tests that only contain ASCII characters. This guideline does not apply when
174specifically testing encodings.
175
176The `<meta>` tag must be the first child of the document's `<head>` element. In
177documents that do not have an explicit `<head>`, the `<meta>` tag must follow
178the doctype.
179
180## Coding Style
181
Kent Tamura59ffb022018-11-27 05:30:56182No coding style is enforced for web tests. This section highlights coding
183style aspects that are not consistent across our web tests, and suggests some
184defaults for unopinionated developers. When writing web tests for a new part
pwnall59aadcb2017-01-26 23:27:21185of the codebase, you can minimize review latency by taking a look at existing
186tests, and pay particular attention to these issues. Also beware of per-project
187style guides, such as the
188[ServiceWorker Tests Style guide](https://www.chromium.org/blink/serviceworker/testing).
189
190### Baseline
191
192[Google's JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html)
193and
194[Google's HTML/CSS Style Guide](https://google.github.io/styleguide/htmlcssguide.xml)
Kent Tamura59ffb022018-11-27 05:30:56195are a reasonable baseline for coding style defaults, with the caveat that web
pwnall59aadcb2017-01-26 23:27:21196tests do not use Google Closure or JSDoc.
197
198### == vs ===
199
200JavaScript's
201[== operator](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality_())
202performs some
203[type conversion](http://www.ecma-international.org/ecma-262/6.0/#sec-abstract-equality-comparison).
204on its arguments, which might be surprising to readers whose experience centers
205around C++ or Java. The
206[=== operator](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Identity_strict_equality_())
207is much more similar to `==` in C++.
208
209Using `===` everywhere is an easy default that saves you, your reviewer, and any
210colleague that might have to debug test failures, from having to reason about
211[special cases for ==](http://dorey.github.io/JavaScript-Equality-Table/). At
212the same time, some developers consider `===` to add unnecessary noise when `==`
213would suffice. While `===` should be universally accepted, be flexible if your
214reviewer expresses a strong preference for `==`.
215
216### Let and Const vs Var
217
218JavaScript variable declarations introduced by
219[var](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/var)
220are hoisted to the beginning of their containing function, which may be
221surprising to C++ and Java developers. By contrast,
222[const](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/const)
223and
224[let](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/let)
225declarations are block-scoped, just like in C++ and Java, and have the added
226benefit of expressing mutability intent.
227
228For the reasons above, a reasonable default is to prefer `const` and `let` over
229`var`, with the same caveat as above.
230
231### Strict Mode
232
233JavaScript's
234[strict mode](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Strict_mode),
235activated by adding `'use strict';` to the very top of a script, helps catch
236some errors, such as mistyping a variable name, forgetting to declare a
237variable, or attempting to change a read-only property.
238
239Given that strict mode gives some of the benefits of using a compiler, adding it
240to every test is a good default. This does not apply when specifically testing
241sloppy mode behavior.
242
243Some developers argue that adding the `'use strict';` boilerplate can be
244difficult to remember, weighs down smaller tests, and in many cases running a
245test case is sufficient to discover any mistyped variable names.
246
247### Promises
248
249[Promises](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)
250are a mechanism for structuring asynchronous code. When used correctly, Promises
251avoid some of the
252[issues of callbacks](http://colintoh.com/blog/staying-sane-with-asynchronous-programming-promises-and-generators).
253For these reasons, a good default is to prefer promises over other asynchronous
254code structures.
255
256When using promises, be aware of the
257[execution order subtleties](https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/)
258associated with them. Here is a quick summary.
259
260* The function passed to `Promise.new` is executed synchronously, so it finishes
261 before the Promise is created and returned.
262* The functions passed to `then` and `catch` are executed in
263 _separate microtasks_, so they will be executed after the code that resolved
264 or rejected the promise finishes, but before any other event handler.
265
266### Classes
267
268[Classes](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Classes)
269are syntactic sugar for JavaScript's
270[prototypal inheritance](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain).
271Compared to manipulating prototypes directly, classes offer a syntax that is
272more familiar to developers coming from other programming languages.
273
274A good default is to prefer classes over other OOP constructs, as they will make
275the code easier to read for many of your fellow Chrome developers. At the same
Kent Tamura59ffb022018-11-27 05:30:56276time, most web tests are simple enough that OOP is not justified.
pwnall59aadcb2017-01-26 23:27:21277
278### Character Encoding
279
280When HTML pages do not explicitly declare a character encoding, browsers
281determine the encoding using an
282[encoding sniffing algorithm](https://html.spec.whatwg.org/multipage/syntax.html#determining-the-character-encoding)
283that will surprise most modern Web developers. Highlights include a default
284encoding that depends on the user's locale, and non-standardized
285browser-specific heuristics.
286
287The easiest way to not have to think about any of this is to add
288`<meta charset="utf-8">` to all your tests. This is easier to remember if you
Kent Tamura59ffb022018-11-27 05:30:56289use a template for your web tests, rather than writing them from scratch.
pwnall59aadcb2017-01-26 23:27:21290
291## Tests with Manual Feedback
292
293Tests that rely on the testing APIs exposed by WPT or Blink will not work when
294loaded in a standard browser environment. When writing such tests, default to
295having the tests gracefully degrade to manual tests in the absence of the
296testing APIs.
297
298The
Kent Tamura59ffb022018-11-27 05:30:56299[document on web tests with manual feedback](./web_tests_with_manual_fallback.md)
pwnall59aadcb2017-01-26 23:27:21300describes the approach in detail and highlights the trade-off between added test
301weight and ease of debugging.