FlutterのIntegrationTestでUserAgentの指定で困った時の解消方法


久々の更新になってしまいました。
(Qiitaは技術領域毎に読まれるものだろうからこういった前置きはいらない気がするけど、自分への言い訳ということで...)

Flutterのテスト

これはもう語り尽くされているので、Flutterのテストについて調べたをご参照ください。

今回はその中で少しだけ詰まったFlutterのIntegrationTestの実施について記載します。

前提:FireBaseが追加されたアプリを使用

アプリの認証機能の使用などにFirebaseを使用しています。
画面を構築するだけの場合には特に求められなかったので、以下に記載するのはFirebase使用時特有の物だと思われます。

エラー:'UserAgent.h' file not found

IntegrationTest(今回だとflutter diriver)でのテスト実行時に以下のようなエラーが表示されました

flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.4+2/darwin/Classes/FLTFirebaseCorePlugin.m:6:9: fatal error: 'UserAgent.h' file not found #import "UserAgent.h"

=== BUILD TARGET cloud_firestore OF PROJECT Pods WITH CONFIGURATION Debug-development ===
               ~/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.12.6/ios/Classes/CloudFirestorePlugin.m:6:9: fatal error: 'UserAgent.h' file not found
               #import "UserAgent.h"
                       ^~~~~~~~~~~~~
               1 error generated.

該当のパスを見てみると確かにUserAgent.hなんてファイルは存在しない。
無理に作っても、その中に何を記載すれば良いのか分からない。
ということで、調べると同じ事象にハマっている方を見つけました。
まとめると解決策は以下の2つ

①以下のコマンドを実行
1. cd ios
2. pod deintegrate
3. pod install

pubspec.yamlを以下のように修正

pubspec.yaml
dependencies:
  test: any
  flutter:
    sdk: flutter
  flutter_driver:
    sdk: flutter


  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  meta: ^1.1.6
  equatable: ^0.2.3
  flutter_bloc: ^0.12.0
  firebase_core: 0.4.4 //ココを変更
  firebase_auth: ^0.11.1
  cloud_firestore: ^0.11.0+2
  firebase_storage: ^3.0.0
  google_sign_in: ^4.0.1+3
  image_picker: ^0.6.0+3

自分は①だけでは解決せず、②まで実行することで問題なく動作するようになりました。

実行結果

それぞれのテストを実行するシェルを作成して、最後まで完了したらSucceedを表示するようにして実行。

test.sh
set -e
echo 'Test start!'
flutter test test/models/user_test.dart
flutter test test/main_test.dart
flutter drive --target=test_driver/app.dart
echo 'Test Succeed!'

実行結果

Test start!
00:01 +0: 生成されたUserインスタンスの値が正しい                                00:01 +1: 生成されたUserインスタンスの値が正しい                                00:01 +1: Userインスタンスの名前をリネームした結果が正しい。                    00:01 +2: Userインスタンスの名前をリネームした結果が正しい。                    00:01 +2: All tests passed!                                                    
00:01 +0: 起動画面のテスト                                                      00:02 +0: 起動画面のテスト                                                      00:02 +1: 起動画面のテスト                                                      00:02 +1: All tests passed!                                                    
Using device iPhone 11.
Starting application: test_driver/app.dart
Running pod install...                                              7.8s
Running Xcode build...                                                  

 ├─Assembling Flutter resources...                           9.8s
 └─Compiling, linking and signing...                        10.0s
Xcode build done.                                           68.3s
    path: satisfied (Path is satisfied), interface: en0
Configuring the default Firebase app...
Configured the default Firebase app __FIRAPP_DEFAULT.
flutter: Observatory listening on http://127.0.0.1:60669/9ryP_dKd-rw=/
    path: satisfied (Path is satisfied), interface: en0
    path: satisfied (Path is satisfied), interface: en0
00:00 +0: AwaseAppの起動テスト (setUpAll)

[info ] FlutterDriver: Connecting to Flutter application at http://127.0.0.1:60669/9ryP_dKd-rw=/
[trace] FlutterDriver: Isolate found with number: 30424320606371
[trace] FlutterDriver: Isolate is paused at start.
[trace] FlutterDriver: Attempting to resume isolate
[trace] FlutterDriver: Waiting for service extension
    path: satisfied (Path is satisfied), interface: en0
[info ] FlutterDriver: Connected to Flutter application.
00:00 +0: AwaseAppの起動テスト 検索ページを開くテスト

00:01 +1: AwaseAppの起動テスト ログイン画面を開くテスト

[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: Bad state: Cannot add new
events after calling close
#0      _BroadcastStreamController.add
(dart:async/broadcast_stream_controller.dart:251:24)
#1      Subject._add (package:rxdart/src/subjects/subject.dart:135:16)
#2      Subject.add (package:rxdart/src/subjects/subject.dart:129:5)
#3      Bloc._bindStateSubject.<anonymous closure>
(package:bloc/src/bloc.dart:120:23)
#4      Stream.forEach.<anonymous closure>.<anonymous closure>
(dart:async/stream.dart:897:45)
#5      _runUserCode (dart:async/stream_pipe.dart:13:23)
#6      Stream.forEach.<anonymous closure> (dart:async/stream.dart:897:11)
#7      _rootRunUnary (dart:async/zone.dart:1134:38)
#8      _CustomZone.runUnary (dart:async/zone.dart:1031:19)
#9      _CustomZone.runUnaryGuarded (dart:async/zone.dart:933:7)
#10     _BufferingStreamSubscription._sendData
(dart:async/stream_impl.dart:338:11)
#11     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:265:7)
#12     _SyncBroadcas<…>
00:01 +2: AwaseAppの起動テスト (tearDownAll)

00:01 +2: All tests passed!

Stopping application instance.
Test Succeed!

途中で出ているエラーが気になりますが一旦時間が無いのでスルーします。
次回はいよいよGitLabCIを実施していく予定です。

ソースコード

こちらの参考書をベースに使用しています。