Flutterでインテグレーションテストした時につまづいた事


Flutterでインテグレーションテストを行った時に詳しく書かれていなくてちょっと困った事をまとめてみました。
まだまだ、調べ中でちゃんとは書けていないですが、とりあえず今はここで一旦公開！

また、ちょくちょく更新していきます。

Integration Testの基本的なことについては[こちら](https://qiita.com/HisakoIsaka/items/1fb052fb2eccdc2876ac)にまとめました。

## 複数の開発環境の場合のテスト方法
複数の開発環境を`flavor`にて設定した上で開発をしている場合のテスト方法です。
サンプルでは開発(Develop)環境にて書いています。

### development環境の場合

`●●●.dart`の設定を`flavor`にて設定しているDevelopに設定します。
`main_test.dart`に変更はありません。

- `main.dart`の設定
Develop用のmain.dartをインポートする。

```
import 'package:flutter_driver/driver_extension.dart';
// Develop用の main.dartをインポート
import 'package:sample/main_develop.dart' as app;

void main() {
  // Flutter driver機能をONにする
  enableFlutterDriverExtension();
  // メインアプリを起動する
  app.main();
}
```

- 使用するコマンド

オプションで`--flavor develop --debug`をつけて実行します。

```
flutter drive --target=test_driver/main.dart --flavor develop --debug
```

### iOSのみ必要な設定

こちら現在検証中です。
検証が終わり次第、記述したいと思います。

## Screenshot

driverにscreenshot()メソッドが実装されています。
スクリーンショットはPNG形式で保存されます。
保存用のフォルダーが必要ですので、`./test_driver`配下に`screenshots`というフォルダーを作成してください。
そこにスクリーンショットの画像を保存します。

```
lib
test
test_driver
|____screenshot
|____●●●.dart
|____●●●_test.dart
```

画像が保存されるドライバーインスタンスとパスを取得するカスタムメソッドを作成します。

```
import 'package:flutter_driver/flutter_driver.dart';

import 'dart:io';
import 'package:test/test.dart';

void main() {
  group('WebView Test', () {

    final openPageFinder = find.byValueKey('openPage');

    FlutterDriver driver;

    setUpAll(() async {
      driver = await FlutterDriver.connect();
    });

    tearDownAll(() async {
      if (driver != null) {
        driver.close();
      }
    });

    Future<void> takeScreenshot(FlutterDriver driver, String path) async {
      print('will take screenshot $path');
      // スクリーンショットを撮る前など、アプリケーションが「安定」するまでを待つ必要がある時に使うコールバックメソッド
      await driver.waitUntilNoTransientCallbacks();
      final pixels = await driver.screenshot();
      final file = File(path);
      await file.writeAsBytes(pixels);
      print('wrote $file');
    }

    test('check flutter driver extension', () async {
      final health = await driver.checkHealth();
      print(health.status);
    });

    test('Shown WebView Screen', () async {

      await driver.tap(openPageFinder);
      // 保存先のパスをパラメーターとして渡します。
      await takeScreenshot(driver, './test_driver/screenshots/web_view.png');
    });
  });
}
```

## その他調べた事

### タイムアウトは30秒。
テストにはタイムアウトが設定されています。デフォルトは30秒です。
以下のようにすればタイムアウト時間を変更できます。

```
   test('View Tilte', () async {
        expect(await driver.getText(titleText), isNotEmpty);
    },
    // タイムアウトを2分に変更
    timeout: Timeout(
    Duration(minutes: 2),
    )
    );
```

### プッシュ通知や認証を行なった後からテストスタートのさせるコマンド

- `--no-build`

ビルドせずにアプリを立ち上げるのでプッシュ通知などの許可後からテスト開始が可能です。
一度、ビルドしてプッシュ通知などの許可後にこのコマンドを使用してテストを行ってください。

```
flutter drive --no-build --target=test_driver/browser.dart --flavor develop --debug
```

### WebviewScaffoldに関して

`flutter_webview_plugin`ライブラリを使用してWebViewを作成しましたがAppBarや戻るボタンなのどのタップのテストなどが以下の内容ができませんでした。
（原因は不明です。これで正しい動作なのかもしれません。）

- `tap()`メソッド
- `screenshot()`メソッド --- スクリーンショットは撮れていますがWebの表示はありません
- `waitUntilNoTransientCallbacks()`のコールバックメソッド


## 参考文献

- [flutter_driver library](https://api.flutter.dev/flutter/flutter_driver/flutter_driver-library.html#classes)

- [Flutterのテストについて調べた](https://qiita.com/yujikawa/items/fe509b160df5ab9eb74e)

- [Flutterの3種類のソースコードテスト(Unit Test, Widget Test, Integration Test)についてのまとめ](https://qiita.com/tez/items/755f340e84e87cfd7609)

- [Integration Test を書く時の 7 つのポイント](https://qiita.com/sensuikan1973/items/c8b56dfaf780e61af567)

- [running integration tests with option --flavor development returns timeout](https://github.com/flutter/flutter/issues/26968)

- [Hot Reload For Flutter Integration Tests](https://medium.com/flutter-community/hot-reload-for-flutter-integration-tests-e0478b63bd54)
※ インテグレーションテスト中にHot Reloadやブレイクポイントを使用可能にする設定
※ こちらまだ設定して試しておりません。後日試して別記事を書きたいと思います。

- [Testing Flutter UI with Flutter Driver](https://morioh.com/p/a180c249a56c)