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

Unified Diff: README.md

Issue 987513005: Rewrite the README. (Closed) Base URL: git@github.com:dart-lang/unittest@master
Patch Set: Created 5 years, 9 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: README.md
diff --git a/README.md b/README.md
index f9ff2f96a748421b70485c90d598389bc693d3bf..4dc8c02e38f8731fd2b2e36e8a27cfd87e882ff6 100644
--- a/README.md
+++ b/README.md
@@ -1,141 +1,176 @@
-Support for writing unit tests in Dart.
+`unittest` provides a standard way of writing and running tests in Dart.
-**See also:**
-[Unit Testing with Dart]
-(http://www.dartlang.org/articles/dart-unit-tests/)
+## Writing Tests
-##Concepts
+Tests are specified using the top-level [`test()`][test] function, and test
+assertions are made using [`expect()`][expect]:
- * __Tests__: Tests are specified via the top-level function [test], they can be
- organized together using [group].
+[test]: http://www.dartdocs.org/documentation/unittest/latest/index.html#unittest/unittest@id_test
+[expect]: http://www.dartdocs.org/documentation/unittest/latest/index.html#unittest/unittest@id_expect
- * __Checks__: Test expectations can be specified via [expect]
-
- * __Matchers__: [expect] assertions are written declaratively using the
- [Matcher] class.
+```dart
+import "package:unittest/unittest.dart";
- * __Configuration__: The framework can be adapted by setting
- [unittestConfiguration] with a [Configuration]. See the other libraries
- in the `unittest` package for alternative implementations of
- [Configuration] including `compact_vm_config.dart`, `html_config.dart`
- and `html_enhanced_config.dart`.
+void main() {
+ test("String.split() splits the string on the delimiter", () {
+ var string = "foo,bar,baz";
+ expect(string.split(","), equals(["foo", "bar", "baz"]));
+ });
-##Examples
+ test("String.trim() removes surrounding whitespace", () {
+ var string = " foo ";
+ expect(string.trim(), equals("foo"));
+ });
+}
+```
-A trivial test:
+Tests can be grouped together using the [`group()`] function. Each group's
+description is added to the beginning of its test's descriptions.
```dart
-import 'package:unittest/unittest.dart';
+import "package:unittest/unittest.dart";
void main() {
- test('this is a test', () {
- int x = 2 + 3;
- expect(x, equals(5));
+ group("String", () {
+ test(".split() splits the string on the delimiter", () {
+ var string = "foo,bar,baz";
+ expect(string.split(","), equals(["foo", "bar", "baz"]));
+ });
+
+ test(".trim() removes surrounding whitespace", () {
+ var string = " foo ";
+ expect(string.trim(), equals("foo"));
+ });
+ });
+
+ group("int", () {
+ test(".remainder() returns the remainder of division", () {
+ expect(11.remainder(3), equals(2));
+ });
+
+ test(".toRadixString() returns a hex string", () {
+ expect(11.toRadixString(16), equals("b"));
+ });
});
}
```
-Multiple tests:
+Any matchers from the [`matcher`][matcher] package can be used with `expect()`
+to do complex validations:
+
+[matcher]: http://www.dartdocs.org/documentation/matcher/latest/index.html#matcher/matcher
```dart
-import 'package:unittest/unittest.dart';
+import "package:unittest/unittest.dart";
void main() {
- test('this is a test', () {
- int x = 2 + 3;
- expect(x, equals(5));
- });
- test('this is another test', () {
- int x = 2 + 3;
- expect(x, equals(5));
+ test(".split() splits the string on the delimiter", () {
+ expect("foo,bar,baz", allOf([
+ contains("foo"),
+ isNot(startsWith("bar")),
+ endsWith("baz")
+ ]));
});
}
```
-Multiple tests, grouped by category:
+## Running Tests
+
+A single test file can be run just using `dart path/to/test.dart`.
+
+![Tests being run via "dart path/to/test.dart".](https://raw.githubusercontent.com/dart-lang/unittest/master/image/test1.gif)
+
+Many tests can be run at a time using `pub run unittest:unittest path/to/dir`.
+
+![Directory being run via "pub run".](https://raw.githubusercontent.com/dart-lang/unittest/master/image/test2.gif)
+
+`unittest` considers any file that ends with `_test.dart` to be a test file. If
+you don't pass any paths, it will run all the test files in your `test/`
+directory, making it easy to test your entire application at once.
+
+By default, tests are run in the Dart VM, but you can run them in the browser as
+well by passing `pub run unittest:unittest -p chrome path/to/test.dart`.
+`unittest` will take care of starting the browser and loading the tests, and all
+the results will be reported on the command line just like for VM tests. In
+fact, you can even run tests on both platforms with a single command: `pub run
+unittest:unittest -p chrome -p vm path/to/test.dart`.
+
+## Asynchronous Tests
+
+Tests written with `async`/`await` will work automatically. The test runner
+won't consider the test finished until the returned `Future` completes.
```dart
-import 'package:unittest/unittest.dart';
+import "dart:async";
+
+import "package:unittest/unittest.dart";
void main() {
- group('group A', () {
- test('test A.1', () {
- int x = 2 + 3;
- expect(x, equals(5));
- });
- test('test A.2', () {
- int x = 2 + 3;
- expect(x, equals(5));
- });
- });
- group('group B', () {
- test('this B.1', () {
- int x = 2 + 3;
- expect(x, equals(5));
- });
+ test("new Future.value() returns the value", () async {
+ var value = await new Future.value(10);
+ expect(value, equals(10));
});
}
```
-Asynchronous tests: if callbacks expect between 0 and 6 positional
-arguments, [expectAsync] will wrap a function into a new callback and will
-not consider the test complete until that callback is run. A count argument
-can be provided to specify the number of times the callback should be called
-(the default is 1).
+There are also a number of useful functions and matchers for more advanced
+asynchrony. The [`completion()`][completion] matcher can be used to test
+`Futures`; it ensures that the test doesn't finish until the `Future` completes,
+and runs a matcher against that `Future`'s value.
+
+[completion]: http://www.dartdocs.org/documentation/unittest/latest/index.html#unittest/unittest@id_completion
```dart
-import 'dart:async';
-import 'package:unittest/unittest.dart';
+import "dart:async";
-void main() {
- test('callback is executed once', () {
- // wrap the callback of an asynchronous call with [expectAsync] if
- // the callback takes 0 arguments...
- Timer.run(expectAsync(() {
- int x = 2 + 3;
- expect(x, equals(5));
- }));
- });
+import "package:unittest/unittest.dart";
- test('callback is executed twice', () {
- var callback = expectAsync(() {
- int x = 2 + 3;
- expect(x, equals(5));
- }, count: 2); // <-- we can indicate multiplicity to [expectAsync]
- Timer.run(callback);
- Timer.run(callback);
+void main() {
+ test("new Future.value() returns the value", () {
+ expect(new Future.value(10), completion(equals(10)));
});
}
```
-There may be times when the number of times a callback should be called is
-non-deterministic. In this case a dummy callback can be created with
-expectAsync((){}) and this can be called from the real callback when it is
-finally complete.
-
-A variation on this is [expectAsyncUntil], which takes a callback as the
-first parameter and a predicate function as the second parameter. After each
-time the callback is called, the predicate function will be called. If it
-returns `false` the test will still be considered incomplete.
+The [`throwsA()`][throwsA] matcher and the various `throwsExceptionType`
+matchers work with both synchronous callbacks and asynchronous `Future`s. They
+ensure that a particular type of exception is thrown:
-Test functions can return [Future]s, which provide another way of doing
-asynchronous tests. The test framework will handle exceptions thrown by
-the Future, and will advance to the next test when the Future is complete.
+[completion]: http://www.dartdocs.org/documentation/unittest/latest/index.html#unittest/unittest@id_throwsA
```dart
-import 'dart:async';
-import 'package:unittest/unittest.dart';
+import "dart:async";
+
+import "package:unittest/unittest.dart";
void main() {
- test('test that time has passed', () {
- var duration = const Duration(milliseconds: 200);
- var time = new DateTime.now();
+ test("new Future.error() throws the error", () {
+ expect(new Future.error("oh no"), throwsA(equals("oh no")));
+ expect(new Future.error(new StateError("bad state")), throwsStateError);
+ });
+}
+```
- return new Future.delayed(duration).then((_) {
- var delta = new DateTime.now().difference(time);
+The [`expectAsync()`][expectAsync] function wraps another function and has two
+jobs. First, it asserts that the wrapped function is called a certain number of
+times, and will cause the test to fail if it's called too often; second, it
+keeps the test from finishing until the function is called the requisite number
+of times.
- expect(delta, greaterThanOrEqualTo(duration));
- });
+```dart
+import "dart:async";
+
+import "package:unittest/unittest.dart";
+
+void main() {
+ test("Stream.fromIterable() emits the values in the iterable", () {
+ var stream = new Stream.fromIterable([1, 2, 3]);
+
+ stream.listen(expectAsync((number) {
+ expect(number, inInclusiveRange(1, 3));
+ }, count: 3));
});
}
```
+
+[expectAsync]: http://www.dartdocs.org/documentation/unittest/latest/index.html#unittest/unittest@id_expectAsync
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698