| OLD | NEW |
| (Empty) | |
| 1 <p><strong>TODO: Add more examples to cover all of the syntax.</strong></p> |
| 2 <p>This input was taken from the test package's README to get a representative |
| 3 sample of real-world markdown:</p> |
| 4 <h2>Writing Tests</h2> |
| 5 <p>Tests are specified using the top-level <a href="http://www.dartdocs.org/docu
mentation/test/latest/index.html#test/test@id_test"><code>test()</code></a> func
tion, and test |
| 6 assertions are made using <a href="http://www.dartdocs.org/documentation/test/la
test/index.html#test/test@id_expect"><code>expect()</code></a>:</p> |
| 7 <pre class="dart"><code>import "package:test/test.dart"; |
| 8 |
| 9 void main() { |
| 10 test("String.split() splits the string on the delimiter", () { |
| 11 var string = "foo,bar,baz"; |
| 12 expect(string.split(","), equals(["foo", "bar", "baz"])); |
| 13 }); |
| 14 |
| 15 test("String.trim() removes surrounding whitespace", () { |
| 16 var string = " foo "; |
| 17 expect(string.trim(), equals("foo")); |
| 18 }); |
| 19 } |
| 20 </code></pre> |
| 21 <p>Tests can be grouped together using the [`group()`] function. Each group's |
| 22 description is added to the beginning of its test's descriptions.</p> |
| 23 <pre class="dart"><code>import "package:test/test.dart"; |
| 24 |
| 25 void main() { |
| 26 group("String", () { |
| 27 test(".split() splits the string on the delimiter", () { |
| 28 var string = "foo,bar,baz"; |
| 29 expect(string.split(","), equals(["foo", "bar", "baz"])); |
| 30 }); |
| 31 |
| 32 test(".trim() removes surrounding whitespace", () { |
| 33 var string = " foo "; |
| 34 expect(string.trim(), equals("foo")); |
| 35 }); |
| 36 }); |
| 37 |
| 38 group("int", () { |
| 39 test(".remainder() returns the remainder of division", () { |
| 40 expect(11.remainder(3), equals(2)); |
| 41 }); |
| 42 |
| 43 test(".toRadixString() returns a hex string", () { |
| 44 expect(11.toRadixString(16), equals("b")); |
| 45 }); |
| 46 }); |
| 47 } |
| 48 </code></pre> |
| 49 <p>Any matchers from the <a href="http://www.dartdocs.org/documentation/matcher/
latest/index.html#matcher/matcher"><code>matcher</code></a> package can be used
with <code>expect()</code> |
| 50 to do complex validations:</p> |
| 51 <pre class="dart"><code>import "package:test/test.dart"; |
| 52 |
| 53 void main() { |
| 54 test(".split() splits the string on the delimiter", () { |
| 55 expect("foo,bar,baz", allOf([ |
| 56 contains("foo"), |
| 57 isNot(startsWith("bar")), |
| 58 endsWith("baz") |
| 59 ])); |
| 60 }); |
| 61 } |
| 62 </code></pre> |
| 63 <h2>Running Tests</h2> |
| 64 <p>A single test file can be run just using <code>pub run test:test path/to/test
.dart</code> |
| 65 (on Dart 1.10, this can be shortened to <code>pub run test path/to/test.dart</co
de>).</p> |
| 66 <p><a href="https://raw.githubusercontent.com/dart-lang/test/master/image/test1.
gif"><img alt="Single file being run via pub run"" src="https://raw.githubuserco
ntent.com/dart-lang/test/master/image/test1.gif"></img></a></p> |
| 67 <p>Many tests can be run at a time using <code>pub run test:test path/to/dir</co
de>.</p> |
| 68 <p><a href="https://raw.githubusercontent.com/dart-lang/test/master/image/test2.
gif"><img alt="Directory being run via "pub run"." src="https://raw.githubuserco
ntent.com/dart-lang/test/master/image/test2.gif"></img></a></p> |
| 69 <p>It's also possible to run a test on the Dart VM only by invoking it using <co
de>dart |
| 70 path/to/test.dart</code>, but this doesn't load the full test runner and will be |
| 71 missing some features.</p> |
| 72 <p>The test runner considers any file that ends with <code>_test.dart</code> to
be a test |
| 73 file. If you don't pass any paths, it will run all the test files in your |
| 74 <code>test/</code> directory, making it easy to test your entire application at
once.</p> |
| 75 <p>By default, tests are run in the Dart VM, but you can run them in the browser
as |
| 76 well by passing <code>pub run test:test -p chrome path/to/test.dart</code>. |
| 77 <code>test</code> will take care of starting the browser and loading the tests,
and all |
| 78 the results will be reported on the command line just like for VM tests. In |
| 79 fact, you can even run tests on both platforms with a single command: <code>pub
run |
| 80 test:test -p "chrome,vm" path/to/test.dart</code>.</p> |
| 81 <h3>Restricting Tests to Certain Platforms</h3> |
| 82 <p>Some test files only make sense to run on particular platforms. They may use |
| 83 <code>dart:html</code> or <code>dart:io</code>, they might test Windows' particu
lar filesystem |
| 84 behavior, or they might use a feature that's only available in Chrome. The |
| 85 <a href="#restricting-tests-to-certain-platforms"><code>@TestOn</code></a> annot
ation makes it easy to declare exactly which platforms |
| 86 a test file should run on. Just put it at the top of your file, before any |
| 87 <code>library</code> or <code>import</code> declarations:</p> |
| 88 <pre class="dart"><code>@TestOn("vm") |
| 89 |
| 90 import "dart:io"; |
| 91 |
| 92 import "package:test/test.dart"; |
| 93 |
| 94 void main() { |
| 95 // ... |
| 96 } |
| 97 </code></pre> |
| 98 <p>The string you pass to <code>@TestOn</code> is what's called a "platform sele
ctor", and it |
| 99 specifies exactly which platforms a test can run on. It can be as simple as the |
| 100 name of a platform, or a more complex Dart-like boolean expression involving |
| 101 these platform names.</p> |
| 102 <h3>Platform Selector Syntax</h3> |
| 103 <p>Platform selectors can contain identifiers, parentheses, and operators. When |
| 104 loading a test, each identifier is set to <code>true</code> or <code>false</code
> based on the current |
| 105 platform, and the test is only loaded if the platform selector returns <code>tru
e</code>. |
| 106 The operators <code>||</code>, <code>&&</code>, <code>!</code>, and <cod
e>? :</code> all work just like they do in Dart. The |
| 107 valid identifiers are:</p><ul><li> |
| 108 <p><code>vm</code>: Whether the test is running on the command-line Dart VM.</p>
</li><li> |
| 109 <p><code>dartium</code>: Whether the test is running on Dartium.</p></li><li> |
| 110 <p><code>content-shell</code>: Whether the test is running on the headless Darti
um content |
| 111 shell.</p></li><li> |
| 112 <p><code>chrome</code>: Whether the test is running on Google Chrome.</p></li><l
i> |
| 113 <p><code>phantomjs</code>: Whether the test is running on |
| 114 <a href="http://phantomjs.org/">PhantomJS</a>.</p></li><li> |
| 115 <p><code>firefox</code>: Whether the test is running on Mozilla Firefox.</p></li
><li> |
| 116 <p><code>safari</code>: Whether the test is running on Apple Safari.</p></li><li
> |
| 117 <p><code>ie</code>: Whether the test is running on Microsoft Internet Explorer.<
/p></li><li> |
| 118 <p><code>dart-vm</code>: Whether the test is running on the Dart VM in any conte
xt, |
| 119 including Dartium. It's identical to <code>!js</code>.</p></li><li> |
| 120 <p><code>browser</code>: Whether the test is running in any browser.</p></li><li
> |
| 121 <p><code>js</code>: Whether the test has been compiled to JS. This is identical
to |
| 122 <code>!dart-vm</code>.</p></li><li> |
| 123 <p><code>blink</code>: Whether the test is running in a browser that uses the Bl
ink |
| 124 rendering engine.</p></li><li> |
| 125 <p><code>windows</code>: Whether the test is running on Windows. If <code>vm</co
de> is false, this will |
| 126 be <code>false</code> as well.</p></li><li> |
| 127 <p><code>mac-os</code>: Whether the test is running on Mac OS. If <code>vm</code
> is false, this will |
| 128 be <code>false</code> as well.</p></li><li> |
| 129 <p><code>linux</code>: Whether the test is running on Linux. If <code>vm</code>
is false, this will be |
| 130 <code>false</code> as well.</p></li><li> |
| 131 <p><code>android</code>: Whether the test is running on Android. If <code>vm</co
de> is false, this will |
| 132 be <code>false</code> as well, which means that this <em>won't</em> be true if
the test is |
| 133 running on an Android browser.</p></li><li> |
| 134 <p><code>posix</code>: Whether the test is running on a POSIX operating system.
This is |
| 135 equivalent to <code>!windows</code>.</p></li></ul> |
| 136 <p>For example, if you wanted to run a test on every browser but Chrome, you wou
ld |
| 137 write <code>@TestOn("browser && !chrome")</code>.</p> |
| 138 <h3>Running Tests on Dartium</h3> |
| 139 <p>Tests can be run on <a href="https://www.dartlang.org/tools/dartium/">Dartium
</a> by passing the <code>-p dartium</code> flag. If you're |
| 140 using the Dart Editor, the test runner will be able to find Dartium |
| 141 automatically. On Mac OS, you can also <a href="https://github.com/dart-lang/hom
ebrew-dart">install it using Homebrew</a>. |
| 142 Otherwise, make sure there's an executable called <code>dartium</code> (on Mac O
S or Linux) |
| 143 or <code>dartium.exe</code> (on Windows) on your system path.</p> |
| 144 <p>Similarly, tests can be run on the headless Dartium content shell by passing
<code>-p |
| 145 content-shell</code>. The content shell is installed along with Dartium when usi
ng |
| 146 Homebrew. Otherwise, you can downloaded it manually <a href="http://gsdview.apps
pot.com/dart-archive/channels/stable/release/latest/dartium/">from this |
| 147 page</a>; if you do, make sure the executable named <code>content_shell</code> |
| 148 (on Mac OS or Linux) or <code>content_shell.exe</code> (on Windows) is on your s
ystem path.</p> |
| 149 <p><a href="https://github.com/dart-lang/test/issues/63">In the future</a>, ther
e will be a more explicit way to configure the |
| 150 location of both the Dartium and content shell executables.</p> |
| 151 <h2>Asynchronous Tests</h2> |
| 152 <p>Tests written with <code>async</code>/<code>await</code> will work automatica
lly. The test runner |
| 153 won't consider the test finished until the returned <code>Future</code> complete
s.</p> |
| 154 <pre class="dart"><code>import "dart:async"; |
| 155 |
| 156 import "package:test/test.dart"; |
| 157 |
| 158 void main() { |
| 159 test("new Future.value() returns the value", () async { |
| 160 var value = await new Future.value(10); |
| 161 expect(value, equals(10)); |
| 162 }); |
| 163 } |
| 164 </code></pre> |
| 165 <p>There are also a number of useful functions and matchers for more advanced |
| 166 asynchrony. The <a href="http://www.dartdocs.org/documentation/test/latest/index
.html#test/test@id_completion"><code>completion()</code></a> matcher can be used
to test |
| 167 <code>Futures</code>; it ensures that the test doesn't finish until the <code>Fu
ture</code> completes, |
| 168 and runs a matcher against that <code>Future</code>'s value.</p> |
| 169 <pre class="dart"><code>import "dart:async"; |
| 170 |
| 171 import "package:test/test.dart"; |
| 172 |
| 173 void main() { |
| 174 test("new Future.value() returns the value", () { |
| 175 expect(new Future.value(10), completion(equals(10))); |
| 176 }); |
| 177 } |
| 178 </code></pre> |
| 179 <p>The <a href="http://www.dartdocs.org/documentation/test/latest/index.html#tes
t/test@id_throwsA"><code>throwsA()</code></a> matcher and the various <code>thro
wsExceptionType</code> |
| 180 matchers work with both synchronous callbacks and asynchronous <code>Future</cod
e>s. They |
| 181 ensure that a particular type of exception is thrown:</p> |
| 182 <pre class="dart"><code>import "dart:async"; |
| 183 |
| 184 import "package:test/test.dart"; |
| 185 |
| 186 void main() { |
| 187 test("new Future.error() throws the error", () { |
| 188 expect(new Future.error("oh no"), throwsA(equals("oh no"))); |
| 189 expect(new Future.error(new StateError("bad state")), throwsStateError); |
| 190 }); |
| 191 } |
| 192 </code></pre> |
| 193 <p>The <a href="http://www.dartdocs.org/documentation/test/latest/index.html#tes
t/test@id_expectAsync"><code>expectAsync()</code></a> function wraps another fun
ction and has two |
| 194 jobs. First, it asserts that the wrapped function is called a certain number of |
| 195 times, and will cause the test to fail if it's called too often; second, it |
| 196 keeps the test from finishing until the function is called the requisite number |
| 197 of times.</p> |
| 198 <pre class="dart"><code>import "dart:async"; |
| 199 |
| 200 import "package:test/test.dart"; |
| 201 |
| 202 void main() { |
| 203 test("Stream.fromIterable() emits the values in the iterable", () { |
| 204 var stream = new Stream.fromIterable([1, 2, 3]); |
| 205 |
| 206 stream.listen(expectAsync((number) { |
| 207 expect(number, inInclusiveRange(1, 3)); |
| 208 }, count: 3)); |
| 209 }); |
| 210 } |
| 211 </code></pre> |
| 212 <h2>Running Tests with Custom HTML</h2> |
| 213 <p>By default, the test runner will generate its own empty HTML file for browser |
| 214 tests. However, tests that need custom HTML can create their own files. These |
| 215 files have three requirements:</p><ul><li> |
| 216 <p>They must have the same name as the test, with <code>.dart</code> replaced by
<code>.html</code>.</p></li><li> |
| 217 <p>They must contain a <code>link</code> tag with <code>rel="x-dart-test"</code>
and an <code>href</code> |
| 218 attribute pointing to the test script.</p></li><li> |
| 219 <p>They must contain <code><script src="packages/test/dart.js"></script
></code>.</p></li></ul> |
| 220 <p>For example, if you had a test called <code>custom_html_test.dart</code>, you
might write |
| 221 the following HTML file:</p> |
| 222 <pre class="html"><code><!doctype html> |
| 223 <!-- custom_html_test.html --> |
| 224 <html> |
| 225 <head> |
| 226 <title>Custom HTML Test</title> |
| 227 <link rel="x-dart-test" href="custom_html_test.dart"> |
| 228 <script src="packages/test/dart.js"></script> |
| 229 </head> |
| 230 <body> |
| 231 // ... |
| 232 </body> |
| 233 </html> |
| 234 </code></pre> |
| 235 <h2>Configuring Tests</h2> |
| 236 <h3>Skipping Tests</h3> |
| 237 <p>If a test, group, or entire suite isn't working yet and you just want it to s
top |
| 238 complaining, you can mark it as "skipped". The test or tests won't be run, and, |
| 239 if you supply a reason why, that reason will be printed. In general, skipping |
| 240 tests indicates that they should run but is temporarily not working. If they're |
| 241 is fundamentally incompatible with a platform, <a href="#restricting-tests-to-ce
rtain-platforms"><code>@TestOn</code>/<code>testOn</code></a> |
| 242 should be used instead.</p> |
| 243 <p>To skip a test suite, put a <code>@Skip</code> annotation at the top of the f
ile:</p> |
| 244 <pre class="dart"><code>@Skip("currently failing (see issue 1234)") |
| 245 |
| 246 import "package:test/test.dart"; |
| 247 |
| 248 void main() { |
| 249 // ... |
| 250 } |
| 251 </code></pre> |
| 252 <p>The string you pass should describe why the test is skipped. You don't have t
o |
| 253 include it, but it's a good idea to document why the test isn't running.</p> |
| 254 <p>Groups and individual tests can be skipped by passing the <code>skip</code> p
arameter. This |
| 255 can be either <code>true</code> or a String describing why the test is skipped.
For example:</p> |
| 256 <pre class="dart"><code>import "package:test/test.dart"; |
| 257 |
| 258 void main() { |
| 259 group("complicated algorithm tests", () { |
| 260 // ... |
| 261 }, skip: "the algorithm isn't quite right"); |
| 262 |
| 263 test("error-checking test", () { |
| 264 // ... |
| 265 }, skip: "TODO: add error-checking."); |
| 266 } |
| 267 </code></pre> |
| 268 <h3>Timeouts</h3> |
| 269 <p>By default, tests will time out after 30 seconds of inactivity. However, this |
| 270 can be configured on a per-test, -group, or -suite basis. To change the timeout |
| 271 for a test suite, put a <code>@Timeout</code> annotation at the top of the file:
</p> |
| 272 <pre class="dart"><code>@Timeout(const Duration(seconds: 45)) |
| 273 |
| 274 import "package:test/test.dart"; |
| 275 |
| 276 void main() { |
| 277 // ... |
| 278 } |
| 279 </code></pre> |
| 280 <p>In addition to setting an absolute timeout, you can set the timeout relative
to |
| 281 the default using <code>@Timeout.factor</code>. For example, <code>@Timeout.fact
or(1.5)</code> will |
| 282 set the timeout to one and a half times as long as the default—45 seconds.</p> |
| 283 <p>Timeouts can be set for tests and groups using the <code>timeout</code> param
eter. This |
| 284 parameter takes a <code>Timeout</code> object just like the annotation. For exam
ple:</p> |
| 285 <pre class="dart"><code>import "package:test/test.dart"; |
| 286 |
| 287 void main() { |
| 288 group("slow tests", () { |
| 289 // ... |
| 290 |
| 291 test("even slower test", () { |
| 292 // ... |
| 293 }, timeout: new Timeout.factor(2)) |
| 294 }, timeout: new Timeout(new Duration(minutes: 1))); |
| 295 } |
| 296 </code></pre> |
| 297 <p>Nested timeouts apply in order from outermost to innermost. That means that |
| 298 "even slower test" will take two minutes to time out, since it multiplies the |
| 299 group's timeout by 2.</p> |
| 300 <h3>Platform-Specific Configuration</h3> |
| 301 <p>Sometimes a test may need to be configured differently for different platform
s. |
| 302 Windows might run your code slower than other platforms, or your DOM |
| 303 manipulation might not work right on Safari yet. For these cases, you can use |
| 304 the <code>@OnPlatform</code> annotation and the <code>onPlatform</code> named pa
rameter to <code>test()</code> |
| 305 and <code>group()</code>. For example:</p> |
| 306 <pre class="dart"><code>@OnPlatform(const { |
| 307 // Give Windows some extra wiggle-room before timing out. |
| 308 "windows": const Timeout.factor(2) |
| 309 }) |
| 310 |
| 311 import "package:test/test.dart"; |
| 312 |
| 313 void main() { |
| 314 test("do a thing", () { |
| 315 // ... |
| 316 }, onPlatform: { |
| 317 "safari": new Skip("Safari is currently broken (see #1234)") |
| 318 }); |
| 319 } |
| 320 </code></pre> |
| 321 <p>Both the annotation and the parameter take a map. The map's keys are <a href=
"#platform-selector-syntax">platform |
| 322 selectors</a> which describe the platforms for which the |
| 323 specialized configuration applies. Its values are instances of some of the same |
| 324 annotation classes that can be used for a suite: <code>Skip</code> and <code>Tim
eout</code>. A value |
| 325 can also be a list of these values.</p> |
| 326 <p>If multiple platforms match, the configuration is applied in order from first
to |
| 327 last, just as they would in nested groups. This means that for configuration |
| 328 like duration-based timeouts, the last matching value wins.</p> |
| 329 <h2>Testing With <code>barback</code></h2> |
| 330 <p>Packages using the <code>barback</code> transformer system may need to test c
ode that's |
| 331 created or modified using transformers. The test runner handles this using the |
| 332 <code>--pub-serve</code> option, which tells it to load the test code from a <co
de>pub serve</code> |
| 333 instance rather than from the filesystem.</p> |
| 334 <p>Before using the <code>--pub-serve</code> option, add the <code>test/pub_serv
e</code> transformer to |
| 335 your <code>pubspec.yaml</code>. This transformer adds the necessary bootstrappin
g code that |
| 336 allows the test runner to load your tests properly:</p> |
| 337 <pre class="yaml"><code>transformers: |
| 338 - test/pub_serve: |
| 339 $include: test/**_test{.*,}.dart |
| 340 </code></pre> |
| 341 <p>Note that if you're using the test runner along with <a href="https://www.dar
tlang.org/polymer/"><code>polymer</code></a>, you |
| 342 have to make sure that the <code>test/pub_serve</code> transformer comes <em>aft
er</em> the |
| 343 <code>polymer</code> transformer:</p> |
| 344 <pre class="yaml"><code>transformers: |
| 345 - polymer |
| 346 - test/pub_serve: |
| 347 $include: test/**_test{.*,}.dart |
| 348 </code></pre> |
| 349 <p>Then, start up <code>pub serve</code>. Make sure to pay attention to which po
rt it's using |
| 350 to serve your <code>test/</code> directory:</p> |
| 351 <pre class="shell"><code>$ pub serve |
| 352 Loading source assets... |
| 353 Loading test/pub_serve transformers... |
| 354 Serving my_app web on http://localhost:8080 |
| 355 Serving my_app test on http://localhost:8081 |
| 356 Build completed successfully |
| 357 </code></pre> |
| 358 <p>In this case, the port is <code>8081</code>. In another terminal, pass this p
ort to |
| 359 <code>--pub-serve</code> and otherwise invoke <code>pub run test:test</code> as
normal:</p> |
| 360 <pre class="shell"><code>$ pub run test:test --pub-serve=8081 -p chrome |
| 361 "pub serve" is compiling test/my_app_test.dart... |
| 362 "pub serve" is compiling test/utils_test.dart... |
| 363 00:00 +42: All tests passed! |
| 364 </code></pre> |
| OLD | NEW |