dart-add-unit-test について
Dart と Flutter アプリのテスト作成と実行を支援するスキルです。テストファイルの構成、アサーション、非同期テスト、セットアップと後処理、Mockito によるモックを扱います。
主な機能
- 01テストファイルとディレクトリの規約
- 02グループ、ケース、マッチャー
- 03非同期テストのパターン
- 04セットアップと後処理のコールバック
- 05Mockito によるモックの手順
活用シーン
- 01Dart のユニットテスト構成
- 02非同期関数のテスト
- 03モックを使った依存注入コードのテスト
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ flutter/ agent-plugins --skill dart-add-unit-testインストール後、Claude Code で/dart-add-unit-testを入力して読み込まれたか確認します。
詳細
Dart および Flutter アプリケーションのテスト
目次
テストファイルの構成
予測しやすい構成を維持するため、テストファイルは lib ディレクトリの構造に合わせて整理します。
- すべてのテストコードは、パッケージのルートにある
testディレクトリに配置します。 - すべてのテストファイル名の末尾に
_test.dartを付けます(例:lib/src/utils.dartのテストはtest/src/utils_test.dartに配置します)。 - 統合テストを書く場合は、パッケージのルートにある
integration_testディレクトリに配置します。
テストの作成
Dart アプリケーションの標準テストライブラリとして package:test を使用します。
package:test/test.dart(Flutter の場合はpackage:flutter_test/flutter_test.dart)をインポートします。group()関数を使って関連するテストをグループ化し、共通のコンテキストを設定します。test()関数を使って個々のテストケースを定義します。- マッチャー(例:
equals()、isTrue、throwsA())とともにexpect()関数を使って結果を検証します。 - 標準の
async/await構文を使って非同期テストを書きます。テストランナーはFutureの完了を自動的に待機します。 setUp()とtearDown()のコールバックを使って、テストのセットアップと後処理を管理します。- 依存性注入に依存するコードをテストする場合は、
package:testとともにpackage:mockitoを使い、モックオブジェクトを生成し、固定のシナリオを設定して、やり取りを検証します。
テストの実行
プロジェクトの種類とテストの場所に応じて、適切なテストランナーを選択します。
- 純粋な Dart プロジェクトでは、
dart testコマンドを使ってテストを実行します。 - Flutter プロジェクトでは、
flutter testコマンドを使ってテストを実行します。 - 統合テストを実行する場合、デフォルトのテストランナーは統合テストを無視するため、ディレクトリのパスを明示的に指定します:
dart test integration_testまたはflutter test integration_test。
テスト実装のワークフロー
新しいテストスイートを実装する際は、次の手順に従います。進捗を追跡するには、チェックリストをコピーしてください。
タスクの進捗
- 1.
test/ディレクトリにテストファイルを作成し、末尾を_test.dartにします。 - 2.
package:test/test.dartと対象のライブラリをインポートします。 - 3.
main()関数を定義します。 - 4.
setUp()を使って共通のリソースまたはモックを初期化します。 - 5.
group()を使って機能ごとにグループ化し、test()ケースを作成します。 - 6. 適切な CLI コマンドを使ってテストスイートを実行します。
- 7. フィードバックループ:テストを実行 -> 失敗した場合はスタックトレースを確認 -> 実装またはアサーションを修正 -> 成功するまで再実行します。
例
標準的なユニットテストスイート
グループ化、セットアップ、同期テスト、非同期テストの例を示します。
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));
});
});
}
Mockito によるモック
依存性注入のテスト用にモックオブジェクトを設定する例を示します。
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);
});
});
}
コメント
Markdown 対応