Setup
# pubspec.yaml
dev_dependencies:
test: ^1.24.0
# Run tests:
dart test
dart test test/my_test.dart
dart test --coverage=coverage
Unit Tests
import 'package:test/test.dart';
int add(int a, int b) => a + b;
double divide(double a, double b) {
if (b == 0) throw ArgumentError('Division by zero');
return a / b;
}
void main() {
test('add returns sum of two numbers', () {
expect(add(2, 3), equals(5));
expect(add(-1, 1), equals(0));
expect(add(0, 0), equals(0));
});
test('divide throws ArgumentError on zero', () {
expect(() => divide(10, 0), throwsArgumentError);
});
test('divide returns correct result', () {
expect(divide(10, 2), closeTo(5.0, 0.001));
});
}
Test Groups
class Calculator {
int add(int a, int b) => a + b;
int subtract(int a, int b) => a - b;
int multiply(int a, int b) => a * b;
double divide(int a, int b) {
if (b == 0) throw ArgumentError('Cannot divide by zero');
return a / b;
}
}
void main() {
late Calculator calc;
setUp(() => calc = Calculator()); // runs before each test
tearDown(() => print('Test done')); // runs after each test
group('Calculator', () {
group('add', () {
test('positive numbers', () => expect(calc.add(2, 3), 5));
test('negative numbers', () => expect(calc.add(-1, -1), -2));
});
group('divide', () {
test('returns double', () => expect(calc.divide(10, 3), closeTo(3.333, 0.001)));
test('throws on zero', () => expect(() => calc.divide(5, 0), throwsArgumentError));
});
});
}
Matchers
expect(value, equals(42));
expect(value, isNull);
expect(value, isNotNull);
expect(value, isTrue);
expect(value, isFalse);
expect(value, isA<String>());
expect(value, contains('dart'));
expect(value, startsWith('Hello'));
expect(value, hasLength(5));
expect(value, inInclusiveRange(0, 100));
expect(value, closeTo(3.14, 0.01));
expect(list, containsAll([1, 2, 3]));
expect(fn, throwsA(isA<FormatException>()));
Async Tests
Future<String> fetchData() async {
await Future.delayed(Duration(milliseconds: 100));
return 'data';
}
void main() {
test('fetches data asynchronously', () async {
var result = await fetchData();
expect(result, equals('data'));
});
test('stream emits values', () async {
var stream = Stream.fromIterable([1, 2, 3]);
expect(stream, emitsInOrder([1, 2, 3, emitsDone]));
});
}
🧠 Quiz
1. Which function runs before each test in a group?
- A) beforeEach
- B) setUp ✅
- C) init
- D) prepare
2. How do you test that a function throws a specific exception?
- A) expect(fn(), throws)
- B) expect(() => fn(), throwsA(isA<ExceptionType>())) ✅
- C) try { fn() } catch ...
- D) assertThrows(fn)
Summary
Use the test package for Dart unit testing. Write tests with test(), group them with group(), and use setUp()/tearDown() for initialization. Assert with expect(value, matcher). Test async code with async/await in tests. Run with dart test.