mcpField
D
dart-add-unit-test

dart-add-unit-test

github.com/dart-langテスト・品質53219.4k 回インストール2 週間前に更新
リポジトリ

dart-add-unit-test について

Dart・Flutterプロジェクトでテストを書く開発者向けのガイドです。テストファイルの配置、テスト構成、非同期処理、モック、単体テストと統合テストの実行方法を扱います。

主な機能

  1. 01lib構成に沿ったテスト配置
  2. 02group、test、expectの利用
  3. 03非同期テストとライフサイクルフック
  4. 04Mockitoによる依存関係のモック
  5. 05単体・統合テストの実行

活用シーン

  1. 01Dartパッケージの単体テスト作成
  2. 02Flutterアプリのテスト作成
  3. 03依存性注入のシナリオ検証
  4. 04統合テストスイートの実行

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dart-lang/skills --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);
    });
  });
}

コメント