skill: add dart skills
This commit is contained in:
122
.agents/skills/dart-add-unit-test/SKILL.md
Normal file
122
.agents/skills/dart-add-unit-test/SKILL.md
Normal file
@@ -0,0 +1,122 @@
|
||||
---
|
||||
name: dart-add-unit-test
|
||||
description: Write and organize unit tests for functions, methods, and classes using `package:test`. Use when creating new logic or fixing bugs to ensure code remains correct and regression-free.
|
||||
metadata:
|
||||
model: models/gemini-3.1-pro-preview
|
||||
last_modified: Fri, 24 Apr 2026 15:07:58 GMT
|
||||
---
|
||||
# Testing Dart and Flutter Applications
|
||||
|
||||
## Contents
|
||||
- [Structuring Test Files](#structuring-test-files)
|
||||
- [Writing Tests](#writing-tests)
|
||||
- [Executing Tests](#executing-tests)
|
||||
- [Test Implementation Workflow](#test-implementation-workflow)
|
||||
- [Examples](#examples)
|
||||
|
||||
## Structuring Test Files
|
||||
Organize test files to mirror the `lib` directory structure to maintain predictability.
|
||||
|
||||
* Place all test code within the `test` directory at the root of the package.
|
||||
* Append `_test.dart` to the end of all test file names (e.g., `lib/src/utils.dart` should be tested in `test/src/utils_test.dart`).
|
||||
* If writing integration tests, place them in an `integration_test` directory at the root of the package.
|
||||
|
||||
## Writing Tests
|
||||
Utilize `package:test` as the standard testing library for Dart applications.
|
||||
|
||||
* Import `package:test/test.dart` (or `package:flutter_test/flutter_test.dart` for Flutter).
|
||||
* Group related tests using the `group()` function to provide shared context.
|
||||
* Define individual test cases using the `test()` function.
|
||||
* Validate outcomes using the `expect()` function alongside matchers (e.g., `equals()`, `isTrue`, `throwsA()`).
|
||||
* Write asynchronous tests using standard `async`/`await` syntax. The test runner automatically waits for the `Future` to complete.
|
||||
* Manage test setup and teardown using `setUp()` and `tearDown()` callbacks.
|
||||
* If testing code that relies on dependency injection, use `package:mockito` alongside `package:test` to generate mock objects, configure fixed scenarios, and verify interactions.
|
||||
|
||||
## Executing Tests
|
||||
Select the appropriate test runner based on the project type and test location.
|
||||
|
||||
* If working on a pure Dart project, execute tests using the `dart test` command.
|
||||
* If working on a Flutter project, execute tests using the `flutter test` command.
|
||||
* If running integration tests, explicitly specify the directory path, as the default runner ignores it: `dart test integration_test` or `flutter test integration_test`.
|
||||
|
||||
## Test Implementation Workflow
|
||||
|
||||
Follow this sequential workflow when implementing new test suites. Copy the checklist to track your progress.
|
||||
|
||||
### Task Progress
|
||||
- [ ] 1. Create the test file in the `test/` directory, ensuring the `_test.dart` suffix.
|
||||
- [ ] 2. Import `package:test/test.dart` and the target library.
|
||||
- [ ] 3. Define a `main()` function.
|
||||
- [ ] 4. Initialize shared resources or mocks using `setUp()`.
|
||||
- [ ] 5. Write `test()` cases grouped by functionality using `group()`.
|
||||
- [ ] 6. Execute the test suite using the appropriate CLI command.
|
||||
- [ ] 7. **Feedback Loop**: Run test -> Review stack trace for failures -> Fix implementation or assertions -> Re-run until passing.
|
||||
|
||||
## Examples
|
||||
|
||||
### Standard Unit Test Suite
|
||||
Demonstrates grouping, setup, synchronous, and asynchronous testing.
|
||||
|
||||
```dart
|
||||
import 'package:test/test.dart';
|
||||
import 'package:my_package/calculator.dart';
|
||||
|
||||
void main() {
|
||||
group('Calculator', () {
|
||||
late Calculator calc;
|
||||
|
||||
setUp(() {
|
||||
calc = Calculator();
|
||||
});
|
||||
|
||||
test('adds two numbers correctly', () {
|
||||
expect(calc.add(2, 3), equals(5));
|
||||
});
|
||||
|
||||
test('handles asynchronous operations', () async {
|
||||
final result = await calc.fetchRemoteValue();
|
||||
expect(result, isNotNull);
|
||||
expect(result, greaterThan(0));
|
||||
});
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Mocking with Mockito
|
||||
Demonstrates configuring a mock object for dependency injection testing.
|
||||
|
||||
```dart
|
||||
import 'package:test/test.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:my_package/api_client.dart';
|
||||
import 'package:my_package/data_service.dart';
|
||||
|
||||
// Generate the mock using build_runner: dart run build_runner build
|
||||
@GenerateNiceMocks([MockSpec<ApiClient>()])
|
||||
import 'data_service_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
group('DataService', () {
|
||||
late MockApiClient mockApiClient;
|
||||
late DataService dataService;
|
||||
|
||||
setUp(() {
|
||||
mockApiClient = MockApiClient();
|
||||
dataService = DataService(apiClient: mockApiClient);
|
||||
});
|
||||
|
||||
test('returns parsed data on successful API call', () async {
|
||||
// Configure the mock
|
||||
when(mockApiClient.get('/data')).thenAnswer((_) async => '{"id": 1}');
|
||||
|
||||
// Execute the system under test
|
||||
final result = await dataService.fetchData();
|
||||
|
||||
// Verify outcomes and interactions
|
||||
expect(result.id, equals(1));
|
||||
verify(mockApiClient.get('/data')).called(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user