環境
- M2 Mac mini
- macOS 13.5
- Android Studio Giraffe
- Xcode 15.0.1
- Flutter 3.13.9
はじめに
最近Mac miniを購入して、Flutterで新しいアプリを作成しました。環境依存部は--dart-define-from-fileで実装したのですが、Firebase Test Labで動かすのに色々と苦労したので記事にします。
尚、ここでは Integration Test を作成してローカル環境での実行まではできているものとします。
Android インストルメンテーションテスト
Flutter との統合テストの「Androidの設定」を行います。リンク先のページにgradlewで--dart-defineを使用する場合の説明も書かれており、key=valueをbase64エンコードした値をカンマ区切りで-Pdart-definesオプションに渡せば良いことが分かります。ですが、環境変数を一つずつbase64エンコードしていくのは大変なので、下記のコマンドを実行します。
flutter build apk --dart-define-from-file=dart_defines.json --verbose | grep gradlew
すると、Flutterでビルドする時にgradlewを実行しているコマンドが表示され、-Pdart-definesを渡していることが分かります。これをコピペして下記のようにgradlewコマンドを実行してみます。
./gradlew app:assembleAndroidTest -Pdart-defines="***,[...]"
ここでもしbuild.gradle内で環境変数を使用していると、Could not get unknown property '{環境変数名}'のようなエラーが表示されると思います。先ほどのflutter buildコマンドの結果を見てもらうと分かるのですが、-Pdart-definesとは別に各環境変数の生値もオプションとしてgradlewコマンドに渡しており、build.gradle内ではそちらの値を参照しているようです。そのため、gradlewコマンドに渡すオプションは下記のようになります。
./gradlew app:assembleAndroidTest -Pdart-defines="***,[...]" -Pkey1=value1 [...]
これで作成されたapp用のapkファイルとtest用のapkファイルを Test Lab にアップロードすればインストルメンテーションテストが実行できます。
iOS XCTest
Flutter との統合テストの「iOSの設定」を行います。こちらには--dart-defineを使用する場合の説明が書かれていませんが、リンク先のページに提示されているスクリプトのflutter buildコマンド実行時に--dart-define-from-fileを指定すれば環境変数を取り込めます。尚、スクリプト内で定義しているdev_targetにはXcodeにインストールされている最新の iOS Deployment target のバージョンを指定する必要があるようです。(不明な場合はスクリプトを実行した後にbuild/ios_integ/Build/Productsディレクトリ内のRunner_iphoneos{dev_target}-arm64.xctestrunファイルを確認してください。)
これで作成されたzipファイルを Test Lab にアップロードすれば XCTest が実行できるのですが、Integration Testでtester.enterTextを実行している場合には注意が必要です。
上の記事によると、ProfileまたはReleaseモードで作成された Integration Test ではtester.enterTextが機能しないとのことです。これを回避するには Integration Test を下記のように修正します。
// IntegrationTestWidgetsFlutterBinding.ensureInitialized();
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
binding.testTextInput.register();
ただし、この修正を行うと、テストを実行している間はキー入力を受け付けなくなるため、注意してください。
さいごに
Test Labで動かすまでは大変でしたが、一度動けば手軽に色々な実機でテストができる恩恵は大きいです。この記事が誰かの役に立てば幸いです。