[Flutter] 統合テスト(Integration Test)

2021-06-06 hit count image

今回のブログポストではFlutterで統合テスト(Integration Test)をする方法を説明します。

概要

Flutterで開発したアプリの統合テスト(Integration Test)をする方法について説明しようかと思います。Flutterの公式とドキュメントでも使い方が詳しく乗せておりますので、ご参考してみてください。

今回のブログポストでは公式ドキュメントの内容を参考して、統合テストするための内容をまとめてみました。ここで紹介するソースコードは下記のリンクで確認できます。

integration_testパッケージインストール

Flutterで統合テストをするためには、integration_testパッケージを使う必要があります。Flutter SDKをインストールすると、このパッケージも一緒にインストールされるので、別にインストールする必要はありません。

しかし、このパッケージを使うためpubspec.yamlファイルを次のように修正する必要があります。

...
dev_dependencies:
  flutter_test:
    sdk: flutter
  integration_test:
    sdk: flutter
...

設定

統合テストは、アンドロイドのエミュレーターやiOSのシミュレーター、またはデバイスで実際アプリを起動した後、テストシナリオによってテストを実行します。したがって、integration_testパッケージを使ってFlutterで統合テストをするためには、各OSに合った設定をする必要があります。

アンドロイド設定

次はintegration_testパッケージを使ってFlutterで統合テストをするため、アンドロイドを設定する方法について説明します。

  1. ./android/app/build.gradleファイルを開いて下記のように修正します。
  ...
  defaultConfig {
      ...
      testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
  }
  ...
  dependencies {
      ...
      // For integration test
      testImplementation 'junit:junit:4.12'
      // https://developer.android.com/jetpack/androidx/releases/test/#1.2.0
      androidTestImplementation 'androidx.test:runner:1.2.0'
      androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
  }
  ...
  1. ./android/app/src/androidTest/java/com/example/[Project Name]/MainActivityTest.javaファイルを生成して次のように修正します。(Project Nameの部分を自分のFlutterプロジェクトの名前で変更します。)
  package com.example.[Project Name];

  import androidx.test.rule.ActivityTestRule;
  import dev.flutter.plugins.integration_test.FlutterTestRunner;
  import org.junit.Rule;
  import org.junit.runner.RunWith;

  @RunWith(FlutterTestRunner.class)
  public class MainActivityTest {
    @Rule
    public ActivityTestRule<MainActivity> rule = new ActivityTestRule<>(MainActivity.class, true, false);
  }

iOSの設定

  1. ios/Runner.xcworkspaceファイルを実行してXcodeを実行します。(次のコマンドを使ってXcodeを実行することができます。)
  open ./ios/Runner.xcworkspace
  1. File > New > Target...を選択します。

Flutter integration test - create new target

  1. Unit Testing Bundleを検索してNextボタンを選択します。

Flutter integration test - unit testing bundle

  1. Product NameRunnerTestsを入力します。Organization Identifierを入力します。LanguageObjective-Cで変更します。そして、Finishを選択してUnit Testing Bundleを生成します。

Flutter integration test - unit testing

  1. Runner > Info > Configurationsを選択してDebug/Release/Profileの項目でRunnerRunnerTestsの設定を同じ値で設定します。

Flutter integration test - info configurations

  1. Runner > Build SettingsiOS Deployment TargetRunnerTests > Build SettingsiOS Deployment Targetを同じバージョンで合わせます。

Flutter integration test - info configurationsFlutter integration test - info configurations

  1. ./ios/Podfileファイルを開いて下記のように修正します。
  platform :ios, '10.0'
  ...
  target 'Runner' do
    ...
    # For integration test
    target 'RunnerTests' do
      inherit! :search_paths
    end
  end
  ...
  1. 次のコマンドを実行します。
  flutter build ios
  or
  flutter build ios --no-codesign
  1. XcodeでRunnerTests.mファイルを開いて全ての内容を消して、次の内容を追加します。
  @import XCTest;
  @import integration_test;

  INTEGRATION_TEST_IOS_RUNNER(RunnerTests)

Flutter integration test - modify RunnerTests.m

  1. Product > Testを選択してテストを実行してみます。

Flutter integration test - product test

問題なければ、ビルドが成功して、シミュレーターが実行されることが確認できます。

テストコード作成

各OSでテストをする準備が終わりました。次は実際テストコードを作成してみましょう。

ドライバー

Flutterで統合テスト(Integration Test)をするためにはドライバー(Driver)が必要です。./test_driver/integration_test.dartファイルを生成して次のように修正します。

import 'package:integration_test/integration_test_driver.dart';

Future<void> main() => integrationDriver();

テストコード

Flutterで統合テスト(Integration Test)を作成するため、integration_testと言うフォルダを生成する必要があり、ユニットテストと同じように_test.dartの形式でテストファイルを生成する必要があります。ここではまず、./integration_test/main_test.dartファイルを生成して次と同じように修正します。

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';

import 'package:integration_test_example/main.dart' as app;

void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

  testWidgets("successful test example", (WidgetTester tester) async {
    app.main();
    await tester.pumpAndSettle();

    expect(find.text('0'), findsOneWidget);

    await tester.tap(find.byType(FloatingActionButton));
    await tester.pumpAndSettle();

    expect(find.text('1'), findsOneWidget);
  });
}

スクロール

スクロールがある画面で統合テストをする時、画面に見えないウィジェットを押すと、エラーが発生します。したがって、該当ウィジェットが画面に見えるまで、画面をスクロールする必要があります。

統合テストで画面をスクロールする時、次のようなコードを使います。

...
await tester.scrollUntilVisible(find.text('Cancel'), -40);
...

上の統合テストコードはCancelと言う文字が見えるまで、スクロールを40pxづつ移動させます。

テストコードの実行

次はこのように作成したテストコードを実行してみましょう。

アンドロイドの統合テスト

アンドロイドで統合テストをするためにはアンドロイドエミュレーターを実行する必要があります。次のコマンドを使って実行可能なアンドロイドのエミュレーターを確認します。

emulator -list-avds

次のコマンドを実行してエミュレーターを実行します。&マークはコマンドをバックグラウンドで実行するためのオプションです。

emulator -avd [Emulator ID] &

エミュレーターが実行されたら、次のコマンドを実行して作成した統合テストを実行します。

flutter test integration_test/

そしたら、エミュレーターで私たちが作成した統合テストが実行されることが確認できます。全てのテストが無事成功したら、次のコマンドを実行してエミュレーターを終了します。

adb emu kill

iOSの統合テスト

次のコマンドを実行して最近実行されたiOSシミュレーターを実行します。

open -a Simulator.app

シミュレーターが実行されたら、次のコマンドを実行して統合テストを実行します。

flutter test integration_test/

作成した統合テストが全て成功したら、次のコマンドを実行して、起動したシミュレーターを終了します。

killall "iOS Simulator"

完了

これでFlutterで統合テストをするための準備と統合テストを作成する方法、そして統合テストを実行する方法についてみてみました。今後、皆さんも実際の環境で皆さんのアプリをテストしてみてください。

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

Posts