【Flutter】ユニットテストで使用するメソッド集
はじめに
Flutter でユニットテストを書く際には、様々なテストメソッドやアサーションメソッドが用意されています。これらのメソッドを適切に使いこなすことで、より効果的なテストを書くことができます。この記事では、ユニットテストで使用するメソッドをメモとして記しておきます。
サンプルコード
基本的なテスト構造メソッド
まずは、テストの基本構造を作るために使用するメソッドを見ていきましょう。
test
メソッド
test
メソッドは最も基本的なテスト単位を定義します。
// 基本的なテストの書き方
test('テストケースの説明', () {
// テストの内容
});
group
メソッド
group
メソッドは関連するテストをグループ化します。
group('テストグループの説明', () {
// 複数のテストケース
test('テストケース1', () {
// テスト内容1
});
test('テストケース2', () {
// テスト内容2
});
});
setUp
とtearDown
メソッド
setUp
はグループ内の各テスト前に実行される共通の準備処理、tearDown
は各テスト後のクリーンアップ処理を定義します。
group('テストグループ', () {
// テストの前に実行される
setUp(() {
// 共通の準備処理
});
// テストの後に実行される
tearDown(() {
// 共通のクリーンアップ処理
});
test('テストケース', () {
// テスト内容
});
});
setUpAll
とtearDownAll
メソッド
setUpAll
はグループ内の全テスト実行前に一度だけ実行され、tearDownAll
は全テスト完了後に一度だけ実行されます。
group('テストグループ', () {
// グループ内の全テスト実行前に一度だけ実行
setUpAll(() {
// 初期化処理(データベース接続など)
});
// グループ内の全テスト完了後に一度だけ実行
tearDownAll(() {
// 終了処理(データベース切断など)
});
// テストケース
});
基本的なアサーションメソッド
テスト結果を検証するためのアサーションメソッドを見ていきましょう。
expect
メソッド
expect
は実際の値と期待する値を比較する最も基本的なアサーションです。
test('基本的な比較', () {
final actual = 1 + 1;
expect(actual, 2); // actualが2であることを検証
});
equals
マッチャー
equals
は値の等価性を検証します(デフォルトで使用されるため、通常は省略可能)。
expect(actual, equals(2)); // expect(actual, 2)と同じ
isTrue
とisFalse
マッチャー
ブール値の検証に使用します。
test('ブール値のテスト', () {
expect(2 > 1, isTrue);
expect(2 < 1, isFalse);
});
isNull
とisNotNull
マッチャー
null かどうかを検証します。
test('nullチェック', () {
var value;
expect(value, isNull);
value = 'not null';
expect(value, isNotNull);
});
コレクション関連のマッチャー
リストや配列などのコレクションを検証するためのマッチャーです。
contains
マッチャー
コレクションに特定の要素が含まれているかをチェックします。
test('コレクションに要素が含まれているか', () {
final list = [1, 2, 3];
expect(list, contains(2));
});
containsAll
マッチャー
コレクションに複数の要素がすべて含まれているかをチェックします。
test('コレクションに複数要素が含まれているか', () {
final list = [1, 2, 3, 4];
expect(list, containsAll([2, 4]));
});
hasLength
マッチャー
コレクションの長さを検証します。
test('コレクションの長さ', () {
final list = [1, 2, 3];
expect(list, hasLength(3));
});
isEmpty
とisNotEmpty
マッチャー
コレクションが空かどうかを検証します。
test('コレクションの空チェック', () {
expect([], isEmpty);
expect([1, 2], isNotEmpty);
});
文字列関連のマッチャー
文字列を検証するためのマッチャーです。
startsWith
とendsWith
マッチャー
文字列の先頭や末尾を検証します。
test('文字列の先頭と末尾', () {
final str = 'Hello, World!';
expect(str, startsWith('Hello'));
expect(str, endsWith('World!'));
});
contains
マッチャー(文字列版)
文字列に特定の部分文字列が含まれているかをチェックします。
test('文字列に部分文字列が含まれているか', () {
final str = 'Hello, World!';
expect(str, contains(', '));
});
matches
マッチャー
正規表現パターンにマッチするかをチェックします。
test('正規表現のマッチ', () {
final email = 'test@example.com';
expect(email, matches(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$'));
});
数値関連のマッチャー
数値を検証するためのマッチャーです。
greaterThan
とlessThan
マッチャー
大小関係を検証します。
test('数値の大小関係', () {
expect(5, greaterThan(3));
expect(3, lessThan(5));
});
greaterThanOrEqualTo
とlessThanOrEqualTo
マッチャー
以上・以下の関係を検証します。
test('数値の以上・以下関係', () {
expect(5, greaterThanOrEqualTo(5));
expect(3, lessThanOrEqualTo(3));
});
inClosedOpenRange
マッチャー
指定した範囲内にあるかをチェックします。
test('数値の範囲チェック', () {
// 1 <= value < 5 の範囲
expect(3, inClosedOpenRange(1, 5));
});
例外のテスト
例外が正しく発生するかをテストするためのメソッドです。
throwsA
マッチャー
特定の例外が発生することを検証します。
test('例外のテスト', () {
expect(() => throw Exception('Error'), throwsA(isA<Exception>()));
});
この例では、関数が Exception 型の例外をスローすることを検証しています。
特定の例外クラスのテスト
特定の例外クラスが発生することを検証します。
test('特定の例外クラスのテスト', () {
expect(() => throw FormatException(), throwsFormatException);
expect(() => throw ArgumentError(), throwsArgumentError);
});
様々な種類のエラーマッチャーが用意されています。
マッチャー名 | 確認するエラー | 用途 |
---|---|---|
throwsArgumentError | ArgumentError | 引数の問題をチェック |
throwsRangeError | RangeError | 範囲外のアクセスをチェック |
throwsStateError | StateError | 不正な状態をチェック |
throwsException | Exception | 一般的な例外をチェック |
throwsFormatException | FormatException | フォーマットエラーをチェック |
throwsNoSuchMethodError | NoSuchMethodError | 存在しないメソッド呼び出しをチェック |
throwsUnsupportedError | UnsupportedError | サポートされていない操作をチェック |
非同期テスト
非同期処理をテストするためのメソッドです。
async/await
を使用したテスト
非同期処理を普通にテストする場合は、テスト関数をasync
にしてawait
を使用します。
test('非同期テスト', () async {
// 非同期処理を行う関数
Future<int> fetchNumber() async {
await Future.delayed(Duration(milliseconds: 100));
return 42;
}
final result = await fetchNumber();
expect(result, 42);
});
expectLater
メソッド
将来の値(Future)に対する検証を行います。
test('Futureの検証', () async {
Future<int> fetchNumber() async {
await Future.delayed(Duration(milliseconds: 100));
return 42;
}
await expectLater(fetchNumber(), completion(equals(42)));
});
completion
マッチャー
Future が完了したときの値を検証します。
test('Futureの完了値', () {
Future<String> fetchString() async {
await Future.delayed(Duration(milliseconds: 100));
return 'Hello';
}
expect(fetchString(), completion('Hello'));
});
emits
マッチャー
ストリームから発行される値を検証します。
test('ストリームのテスト', () {
final controller = StreamController<int>();
// 値を発行
controller.add(1);
controller.add(2);
controller.close();
expect(controller.stream, emitsInOrder([1, 2, emitsDone]));
});
emits 関連であれば、以下のマッチャーが用意されています。
emits - ストリームが特定のイベントを発行するかテスト
emitsDone - ストリームが「完了」イベントを発行するかテスト
emitsError - ストリームがエラーイベントを発行するかテスト
emitsInOrder - 複数のイベントが特定の順序で発行されるかテスト
まとめ
Flutter のユニットテストでは、様々なメソッドとマッチャーを組み合わせることで、効果的なテストを書くことができます。
基本的なテスト構造(test
、group
、setUp
など)と、様々な検証メソッド(expect
とそれに関連するマッチャー)を適切に組み合わせることで、様々なシナリオのテストが可能になります。
サンプルコード
Discussion