【最新版】FlutterにPatrolのテスト導入・環境構築

目次
- Patrolとは
- patrol_cliをインストール
- エラー① Program ideviceinstaller not found
- エラー② Env var $ANDROID_HOME is not set.エラー
- patrolパッケージの依存関係を追加
- pubspec.yamlにpatrolセクションを作成
- Androidの統合設定 (Groovy ビルド構成ファイルを使用するプロジェクト)
- MainActivityTest.java の作成
- build.gradleファイルの修正
- iOSの統合設定
- Targetsの作成
- iOS デプロイメント ターゲットの確認
- RunnerUITests.mの修正
- Podファイルの修正
- ビルドフェーズの追加
- User Script SandboxingをNoにしておく
- 簡単な統合テストを作成する
- patrol testに失敗する解決方法5選
- pubspec.yamlにintegration_testを追加する
- podとXcodeのキャッシュ削除・再インストール
- Parallelizationを無効にする
- Xcodeのフォーマットを最新にする
- Build Phase Scriptの修正
- まとめ
Patrolとは
Patrolは、Flutterアプリ専用に設計され、2022年 9 月にリリースされた強力なオープンソースのUIテストフレームワークです。
特に、Flutterテスト内でネイティブプラットフォーム機能を活用できることや、直感的なテスト作成ができることから選ばれる理由が多いようです。
- 権限ダイアログ通知WebViewを操作
- デバイス設定Wi-Fi のの変更、切り替えなど
それでは早速導入していきましょう。
patrol_cliをインストール
% flutter pub global activate patrol_cli
インストールが成功し、環境が適切に設定されていることを確認します。
% patrol doctor
プラットフォームのすべてのチェックが緑色になっている必要があり、以下のように赤色の部分は解消する必要があります。
エラー① Program ideviceinstaller not found

以下コマンドで解決しましょう。
% brew install ideviceinstaller
エラー② Env var $ANDROID_HOME is not set.エラー
• Env var $ANDROID_HOME is not set. (See the link: <https://developer.android.com/tools/variables#set>)
.zshrcファイルに以下を追加して、source ~/.zshrcで反映してください。
export ANDROID_HOME=$HOME/Library/Android/sdk
export ANDROID_SDK_ROOT=$ANDROID_HOME
export PATH="$PATH:$ANDROID_SDK_ROOT/platform-tools"
全てのエラーが解消できて緑になったらOKです。

patrolパッケージの依存関係を追加
パッケージへの依存関係を追加します。
注意点:パッケージには、Android SDK バージョン21以上が必要です。
% fvm flutter pub add patrol --dev
今回は、patrol: ^3.15.2を使用しています。
pubspec.yamlにpatrolセクションを作成
Androidではパッケージ名、iOSではバンドルIDを設定します。
dependencies:
# ...
dev_dependencies:
# ...
patrol:
app_name: My App
android:
package_name: com.example.myapp
ios:
bundle_id: com.example.myapp
Androidの統合設定 (Groovy ビルド構成ファイルを使用するプロジェクト)
ここからはAndroidとiOSで別々の設定が必要になります。
まずは簡単なAndroidから設定していきます。
MainActivityTest.java の作成
プロジェクトディレクトリのandroid/app/src/androidTest/java/com/example/myapp/に移動しましょう。
該当するフォルダがない場合は作成してください。(myappなどはアプリのパッケージ名に置き換えてください。)
そして、**MainActivityTest.java**という名前のファイルを作成し、そこに以下のコードをコピーします。
package com.example.myapp; // replace "com.example.myapp" with your app's package
import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import pl.leancode.patrol.PatrolJUnitRunner;
@RunWith(Parameterized.class)
public class MainActivityTest {
@Parameters(name = "{0}")
public static Object[] testCases() {
PatrolJUnitRunner instrumentation = (PatrolJUnitRunner) InstrumentationRegistry.getInstrumentation();
instrumentation.setUp(MainActivity.class);
instrumentation.waitForPatrolAppService();
return instrumentation.listDartTests();
}
public MainActivityTest(String dartTestName) {
this.dartTestName = dartTestName;
}
private final String dartTestName;
@Test
public void runDartTest() {
PatrolJUnitRunner instrumentation = (PatrolJUnitRunner) InstrumentationRegistry.getInstrumentation();
instrumentation.runDartTest(dartTestName);
}
}
build.gradleファイルの修正
プロジェクト ディレクトリのandroid/appフォルダーにあるbuild.gradle.ktsファイルに移動します。
なければ新しくファイルを作成しましょう。
以下のコードを書くセクションに対して追加してください。
- testOptions:
execution = "ANDROIDX_TEST_ORCHESTRATOR" - defaultConfig:
testInstrumentationRunner "pl.leancode.patrol.PatrolJUnitRunner"、testInstrumentationRunnerArguments clearPackageData: "true" - dependencies:
androidTestUtil "androidx.test:orchestrator:1.5.1"
...
android {
...
testOptions {
execution = "ANDROIDX_TEST_ORCHESTRATOR"
}
defaultConfig {
...
testInstrumentationRunner "pl.leancode.patrol.PatrolJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: "true"
}
}
dependencies {
...
androidTestUtil "androidx.test:orchestrator:1.5.1"
}
iOSの統合設定
ios/Runner.xcworkspace をXcodeで開きます。
Targetsの作成
Targetsの左下の+ボタンからRunnerUITestsという名前で作成します。
.png?w=1428&fit=max&fm=webp)
Organization Identifierなどを入力してLanguegeに関しては、Objective-Cで作成するようにしましょう。
作成すると、以下2つのファイルが作成されます。
RunnerUITests.mRunnerUITestsLaunchTests.m
ここで、RunnerUITestsLaunchTests.m は使わないので削除しておきます。
iOS デプロイメント ターゲットの確認
ビルド設定セクションの iOS デプロイメント ターゲットがプロジェクトと同じであることを確認してください。
サポートされている最小のiOS デプロイメント ターゲットは13.0です。
.png?w=1428&fit=max&fm=webp)
RunnerUITests.mの修正
先ほど生成されたRunnerUITests.mを以下のコードにします。
@import XCTest;
@import patrol;
@import ObjectiveC.runtime;
PATROL_INTEGRATION_TEST_IOS_RUNNER(RunnerUITests)
Podファイルの修正
新しく作成したターゲットを**ios/Podfile**に埋め込みましょう。
target 'Runner' do
...
target 'RunnerUITests' do
inherit! :complete
end
end
ビルドフェーズの追加
RunnerUITests > Build Phasesに移動し、2つの新しい「Run Script Phase」ビルドフェーズを追加します。
それぞれにxcode_backend build、xcode_backend embed_and_thin と命名してください。
xcode_backend build
/bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
xcode_backend embed_and_thin
/bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed_and_thin
また、以下の順番になるように配置を修正しましょう。
.png?w=1428&fit=max&fm=webp)
User Script SandboxingをNoにしておく
RunnerUITestsのUser Script SandboxingをNoに設定しましょう。
.png?w=1428&fit=max&fm=webp)
簡単な統合テストを作成する
Patrolが正しく設定されていることを確認するために、ダミーのFlutter統合テストを作成してみましょう。
プロジェクト配下(integration_test/example_test.dart)に次のコードを貼り付けます。
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol/patrol.dart';
void main() {
patrolTest(
'counter state is the same after going to home and switching apps',
($) async {
// Replace later with your app's main widget
await $.pumpWidgetAndSettle(
MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('app')),
backgroundColor: Colors.blue,
),
),
);
expect($('app'), findsOneWidget);
if (!Platform.isMacOS) {
await $.native.pressHome();
}
},
);
}
以下コマンドを実行してテストします。
% patrol test -t integration_test/example_test.dart -d デバイスID
デバイスIDは% flutter devicesコマンドで使用したいシミュレーターなどのIDを入れてください。
テストが成功するとこのようになります。

patrol testに失敗する解決方法5選
ここでは実際に、% patrol testを実行してこけて解消したエラーを紹介します。
pubspec.yamlにintegration_testを追加する
自分の実行環境では、integration_testを追加しないと実行できませんでした。
patrol: ^3.15.2
integration_test:
sdk: flutter
podとXcodeのキャッシュ削除・再インストール
Xcodeを開いている場合は一旦閉じて以下コマンドをプロジェクトのルートで実行します。
% rm -rf ios/Pods ios/Podfile.lock pubspec.lock \\
&& rm -rf ~/Library/Developer/Xcode/DerivedData \\
&& cd ios && pod cache clean --all && pod install --repo-update \\
&& cd .. && fvm flutter clean && fvm flutter pub get
Parallelizationを無効にする
Product > schema > edit schemaを開き、RunnerUITestのOptionからParallelizationをDisabledにしましょう。
.png?w=1428&fit=max&fm=webp)
Xcodeのフォーマットを最新にする
ここが古いと、ArgumentError - [Xcodeproj] Unable to find compatibility version string for object version 70.エラーのようなものが出るので、最新にしましょう。
.png?w=1428&fit=max&fm=webp)
Build Phase Scriptの修正
以下のようにコードの修正を行いました。
xcode_backend build
#!/bin/sh
set -e
export FLUTTER_BUILD_DIR=${FLUTTER_BUILD_DIR:-build}
"/bin/sh" "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
xcode_backend embed_and_thin
#!/bin/sh
set -e
export FLUTTER_BUILD_DIR=${FLUTTER_BUILD_DIR:-build}
"/bin/sh" "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed_and_thin
まとめ
意外とネイティブ統合のための設定が複雑かつ情報も少なかったたエラーに悩まされ、苦労しました。
まだちゃんとテストをかけていないので、次回Patrolの記事を出す際は、テストについて書こうと思います。
Anycloudでは一緒に働くメンバーを募集しています!
Anycloudは、ユーザーの心を動かす体験を届けることを大切にしています。フルリモート・フルフレックスの環境のもと、ライフスタイルに合わせた働き方を実現しながら挑戦したい方を歓迎します。詳細はこちらをご覧ください。




