Unit Testing in Dart
Unit Testing in Dart
Testing is a critical part of professional software development. Writing tests ensures that your code works as expected today, and continues to work as expected as you add new features or refactor existing code.
In this lesson, we will cover how to write unit tests using Dart's official test package.
1. Setting Up the Test Environment
To write tests, you need to add the test package to your dev_dependencies inside your pubspec.yaml file.
yamlname: my_dart_project description: A sample command-line application. version: 1.0.0 environment: sdk: '>=3.0.0 <4.0.0' dependencies: # App dependencies go here dev_dependencies: test: ^1.24.0
Run dart pub get to download and install the package.
2. Writing Your First Test
By convention, all test files must:
- Be located inside a top-level directory named
test/. - End with the suffix
_test.dart(e.g.,calculator_test.dart).
Here is a simple calculator class and its corresponding unit test:
Implementation: lib/calculator.dart
dartclass Calculator { int add(int a, int b) => a + b; int subtract(int a, int b) => a - b; }
Test File: test/calculator_test.dart
dartimport 'package:test/test.dart'; import 'package:my_dart_project/calculator.dart'; void main() { group('Calculator Tests', () { final calculator = Calculator(); test('Addition should return the sum of two integers', () { final result = calculator.add(10, 5); expect(result, equals(15)); }); test('Subtraction should return the difference of two integers', () { final result = calculator.subtract(10, 5); expect(result, equals(5)); }); }); }
3. Key Testing Functions
group()
Used to group related tests together. This helps organize output logs and makes it easy to apply common setup logic to a batch of tests.
test()
Defines a single test case. It takes a description string and an execution body.
expect()
An assertion check. It compares the actual value returned by your code against the expected matcher value.
4. Lifecycle Hooks: Setup and Teardown
If your tests require setting up database connections, creating mock profiles, or cleaning up filesystem changes, use Dart's lifecycle hooks:
setUp(): Runs a block of code before every test in the group.tearDown(): Runs a block of code after every test in the group.setUpAll(): Runs once before any tests in the group start.tearDownAll(): Runs once after all tests in the group complete.
dartvoid main() { late DatabaseConnection db; setUp(() { db = DatabaseConnection(); db.open(); }); tearDown(() { db.close(); }); test('Query user returns valid profile', () { var user = db.getUser(1); expect(user.name, equals("Admin")); }); }
5. Running Your Tests
Run the test suite from your terminal:
bash# Run all tests in the project dart test # Run a specific test file dart test test/calculator_test.dart
Summary
- Unit tests verify the smallest testable parts (methods/functions) of your application.
- Put all tests in the
test/directory, naming files with the_test.dartsuffix. - Use
group()to organize tests,test()to define cases, andexpect()with matchers to assert results. - Leverage
setUp()andtearDown()lifecycle hooks to manage test state.