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()関数を使用して個々のテストケースを定義します。expect()関数とマッチャー(例:equals()、isTrue、throwsA())を使用して結果を検証します。- 非同期テストは標準の
async/await構文を使用して記述します。テストランナーは自動的にFutureの完了を待機します。 setUp()およびtearDown()コールバックを使用してテストのセットアップとクリーンアップを管理します。- 依存性注入に依存するコードをテストする場合は、
package:mockitoをpackage:testと組み合わせて使用し、モックオブジェクトを生成し、固定シナリオを設定し、相互作用を検証します。
テストの実行
プロジェクトの種類とテストの場所に基づいて、適切なテストランナーを選択します。
- 純粋な 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('2つの数値を正しく加算する', () {
expect(calc.add(2, 3), equals(5));
});
test('非同期操作を処理する', () 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';
// 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('API呼び出しが成功した場合、パースされたデータを返す', () async {
// モックを設定
when(mockApiClient.get('/data')).thenAnswer((_) async => '{"id": 1}');
// テスト対象のシステムを実行
final result = await dataService.fetchData();
// 結果と相互作用を検証
expect(result.id, equals(1));
verify(mockApiClient.get('/data')).called(1);
});
});
}