Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(580)

Side by Side Diff: pkg/scheduled_test/README.md

Issue 812253002: Delete a bunch of packages that are now on GitHub. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Un-delete http Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/scheduled_test/LICENSE ('k') | pkg/scheduled_test/lib/descriptor.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 A package for writing readable tests of asynchronous behavior.
2
3 This package works by building up a queue of asynchronous tasks called a
4 "schedule", then executing those tasks in order. This allows the tests to
5 read like synchronous, linear code, despite executing asynchronously.
6
7 The `scheduled_test` package is built on top of `unittest`, and should be
8 imported instead of `unittest`. It provides its own version of [group],
9 [test], and [setUp], and re-exports most other APIs from unittest.
10
11 To schedule a task, call the [schedule] function. For example:
12
13 ```dart
14 import 'package:scheduled_test/scheduled_test.dart';
15
16 void main() {
17 test('writing to a file and reading it back should work', () {
18 schedule(() {
19 // The schedule won't proceed until the returned Future has
20 // completed.
21 return new File("output.txt").writeAsString("contents");
22 });
23
24 schedule(() {
25 return new File("output.txt").readAsString().then((contents) {
26 // The normal unittest matchers can still be used.
27 expect(contents, equals("contents"));
28 });
29 });
30 });
31 }
32 ```
33
34 ## Setting up and tearing down
35
36 The `scheduled_test` package defines its own [setUp] method that works just
37 like the one in `unittest`. Tasks can be scheduled in [setUp]; they'll be
38 run before the tasks scheduled by tests in that group. [currentSchedule] is
39 also set in the [setUp] callback.
40
41 This package doesn't have an explicit `tearDown` method. Instead, the
42 [currentSchedule.onComplete] and [currentSchedule.onException] task queues
43 can have tasks scheduled during [setUp]. For example:
44
45 ```dart
46 import 'package:scheduled_test/scheduled_test.dart';
47
48 void main() {
49 var tempDir;
50 setUp(() {
51 schedule(() {
52 return createTempDir().then((dir) {
53 tempDir = dir;
54 });
55 });
56
57 currentSchedule.onComplete.schedule(() => deleteDir(tempDir));
58 });
59
60 // ...
61 }
62 ```
63
64 ## Passing values between tasks
65
66 It's often useful to use values computed in one task in other tasks that are
67 scheduled afterwards. There are two ways to do this. The most
68 straightforward is just to define a local variable and assign to it. For
69 example:
70
71 ```dart
72 import 'package:scheduled_test/scheduled_test.dart';
73
74 void main() {
75 test('computeValue returns 12', () {
76 var value;
77
78 schedule(() {
79 return computeValue().then((computedValue) {
80 value = computedValue;
81 });
82 });
83
84 schedule(() => expect(value, equals(12)));
85 });
86 }
87 ```
88
89 However, this doesn't scale well, especially when you start factoring out
90 calls to [schedule] into library methods. For that reason, [schedule]
91 returns a [Future] that will complete to the same value as the return
92 value of the task. For example:
93
94 ```dart
95 import 'package:scheduled_test/scheduled_test.dart';
96
97 void main() {
98 test('computeValue returns 12', () {
99 var valueFuture = schedule(() => computeValue());
100 schedule(() {
101 valueFuture.then((value) => expect(value, equals(12)));
102 });
103 });
104 }
105 ```
106
107 ## Out-of-Band Callbacks
108
109 Sometimes your tests will have callbacks that don't fit into the schedule.
110 It's important that errors in these callbacks are still registered, though,
111 and that [Schedule.onException] and [Schedule.onComplete] still run after
112 they finish. When using `unittest`, you wrap these callbacks with
113 `expectAsyncN`; when using `scheduled_test`, you use [wrapAsync] or
114 [wrapFuture].
115
116 [wrapAsync] has two important functions. First, any errors that occur in it
117 will be passed into the [Schedule] instead of causing the whole test to
118 crash. They can then be handled by [Schedule.onException] and
119 [Schedule.onComplete]. Second, a task queue isn't considered finished until
120 all of its [wrapAsync]-wrapped functions have been called. This ensures that
121 [Schedule.onException] and [Schedule.onComplete] will always run after all
122 the test code in the main queue.
123
124 Note that the [completes], [completion], and [throws] matchers use
125 [wrapAsync] internally, so they're safe to use in conjunction with scheduled
126 tests.
127
128 Here's an example of a test using [wrapAsync] to catch errors thrown in the
129 callback of a fictional `startServer` function:
130
131 ```dart
132 import 'package:scheduled_test/scheduled_test.dart';
133
134 void main() {
135 test('sendRequest sends a request', () {
136 startServer(wrapAsync((request) {
137 expect(request.body, equals('payload'));
138 request.response.close();
139 }));
140
141 schedule(() => sendRequest('payload'));
142 });
143 }
144 ```
145
146 [wrapFuture] works similarly to [wrapAsync], but instead of wrapping a
147 single callback it wraps a whole [Future] chain. Like [wrapAsync], it
148 ensures that the task queue doesn't complete until the out-of-band chain has
149 finished, and that any errors in the chain are piped back into the scheduled
150 test. For example:
151
152 ```dart
153 import 'package:scheduled_test/scheduled_test.dart';
154
155 void main() {
156 test('sendRequest sends a request', () {
157 wrapFuture(server.nextRequest.then((request) {
158 expect(request.body, equals('payload'));
159 expect(request.headers['content-type'], equals('text/plain'));
160 }));
161
162 schedule(() => sendRequest('payload'));
163 });
164 }
165 ```
166
167 ## Timeouts
168
169 `scheduled_test` has a built-in timeout of 5 seconds (configurable via
170 [Schedule.timeout]). This timeout is aware of the structure of the schedule;
171 this means that it will reset for each task in a queue, when moving between
172 queues, or almost any other sort of interaction with [currentSchedule]. As
173 long as the [Schedule] knows your test is making some sort of progress, it
174 won't time out.
175
176 If a single task might take a long time, you can also manually tell the
177 [Schedule] that it's making progress by calling [Schedule.heartbeat], which
178 will reset the timeout whenever it's called.
179
180 [pub]: http://pub.dartlang.org
181 [pkg]: http://pub.dartlang.org/packages/scheduled_test
OLDNEW
« no previous file with comments | « pkg/scheduled_test/LICENSE ('k') | pkg/scheduled_test/lib/descriptor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698