dart-testing について
Dart パッケージや Flutter アプリのテスト作成を支援するスキルです。テストの選択、依存関係の分離、アサーション、コマンドラインでの実行手順を扱います。
主な機能
- 01ユニット・ウィジェット・統合テストの指針
- 02環境に応じたテストパッケージの選択
- 03Mockito による依存関係の分離
- 04命名・アサーション・非同期マッチャー
- 05テストの実行と絞り込みコマンド
活用シーン
- 01Dart パッケージや Flutter アプリのテスト方針の選択
- 02外部依存を含むコードの分離テスト作成
- 03パス・タグ・名前によるテスト実行
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ dart-lang/ skills --skill dart-testingインストール後、Claude Code で/dart-testingを入力して読み込まれたか確認します。
詳細
Dart アプリケーションのテスト
目次
テストの基本原則
対象環境と範囲に応じて、適切なテスト戦略を適用します。
- ユニットテスト: テスト可能なソフトウェアの最小単位(関数、メソッド、クラス)を検証します。この範囲のカバレッジを最大化します。
- コンポーネント/ウィジェットテスト: コンポーネント(複数のクラスまたは Flutter ウィジェット)が期待どおりに動作することを検証します。モックオブジェクトを使用して、ユーザー操作やイベントを再現します。
- 統合/エンドツーエンドテスト: シミュレーター/実機またはブラウザー上で、アプリ全体または大規模なサブシステムの動作を検証します。
テスト環境に応じた条件分岐:
- 純粋な Dart パッケージまたはサーバーアプリをテストする場合:
package:testを使用します。 - Flutter アプリをテストする場合: ユニット/ウィジェットテストには
package:testを基盤とするflutter_testを使用し、エンドツーエンドテストにはintegration_testまたはflutter_driverを使用します。
テスト実装ガイドライン
test パッケージの規約に従ってテストを構成し、記述します。
- わかりやすい命名: 関連するテストの分類には
group()を、個別のテストケースにはtest()を使用します。期待される動作を説明する、明確でわかりやすい名前を付けます。 - アサーション: アサーションには必ず
expect(actual, matcher)を使用します。 - 非同期マッチャー: Future の解決を検証するには
completion()を、例外を検証するにはthrowsA()を使用します。 - アノテーション: 特定の環境にテストを限定するには
@TestOn('browser')または@TestOn('vm')を使用します。カスタム設定用にテストを分類するには@Tag('name')を使用します。
モックと分離
決定論的かつ高速に実行できるよう、テスト対象システム(SUT)を分離します。
- モックとフェイクを優先する: ユニットテストでは、実際のネットワーク呼び出し、データベース、複雑な外部依存関係を使用しないでください。
package:mockitoを使用する: 複雑な依存関係には、モッククラスを生成します。固定のシナリオを定義し、SUT が期待どおりにモックオブジェクトとやり取りすることを検証します。- コード生成:
build_runnerを使用してモック実装を生成します(dart-code-generationを参照)。
テストの実行
フィードバックサイクルを最適化するには、対象を指定するフラグを使用してコマンドラインからテストを実行します。
- すべてのテストを実行:
dart test(またはflutter test) - 特定のディレクトリを実行:
dart test test/unit/またはdart test test/integration/ - 特定のファイルを実行:
dart test test/services/auth_test.dart - タグで絞り込む:
dart test --tags="integration"またはdart test --exclude-tags="slow" - 名前で絞り込む:
dart test --name="AuthService"
ワークフロー
ワークフロー:ユニットテストスイートの実装
新しいテストを実装する際は、このチェックリストをコピーして進捗を記録します。
- 1. テストするクラス/関数と、その外部依存関係を特定します。
- 2.
test/ディレクトリに対応する_test.dartファイルを作成します。 - 3.
package:mockitoまたは手動で作成したフェイクを使用して、すべての外部依存関係のモックオブジェクトを定義します。 - 4. わかりやすい名前を付けて、テストの
group()を定義します。 - 5.
setUp()ブロック内で SUT とモックを初期化します。 - 6. 成功、失敗、エッジケースを網羅する個別の
test()ケースを記述します。 - 7. 適切なマッチャー(
completion、throwsAなど)を使用してexpect()を呼び出します。 - 8. フィードバックサイクル:
dart test path/to/test.dartを実行 -> 失敗を確認 -> 実装またはテストロジックを修正 -> 合格するまで繰り返します。
例
高精度なユニットテストの例
import 'package:test/test.dart';
import 'package:mockito/mockito.dart';
import 'package:mockito/annotations.dart';
// Assume these are defined in your application code
import 'package:my_app/auth_service.dart';
import 'package:my_app/api_client.dart';
// Generate mocks using build_runner
@GenerateMocks([ApiClient])
import 'auth_service_test.mocks.dart';
void main() {
group('AuthService', () {
late AuthService authService;
late MockApiClient mockApiClient;
setUp(() {
mockApiClient = MockApiClient();
authService = AuthService(apiClient: mockApiClient);
});
test('login successfully returns a user token', () async {
// Arrange
when(mockApiClient.post('/login', any))
.thenAnswer((_) async => {'token': 'abc-123'});
// Act
final result = authService.login('user', 'password');
// Assert
await expectLater(result, completion(equals('abc-123')));
verify(mockApiClient.post('/login', any)).called(1);
});
test('login throws AuthException on invalid credentials', () async {
// Arrange
when(mockApiClient.post('/login', any))
.thenThrow(Exception('Unauthorized'));
// Act
final result = authService.login('user', 'wrong_password');
// Assert
await expectLater(result, throwsA(isA<AuthException>()));
});
});
}
関連スキル
dart-static-analysis:テスト品質を保証するリンティングルールの設定に使用します。dart-code-generation:build_runnerとmockitoによるモックオブジェクトの生成に使用します。
コメント
Markdown 対応