このドキュメントは、Flutter Advent Calendar 2021 のカレンダー2の day15 です。
DevFest Kyoto 2021 - Flutterテスト講座 の
セッション テスト設計できるようになろう の
Widget testで状態プロパティを参照する - エクストリームテスト の サンプルプロジェクト をベースに、
GitHub Actions を使い、Pull requestイベントで flutter test test/
を実行するようにしたレポートです。
セッション内容については、スライド資料を御参照ください。
Flutterプロジェクト-リポジトリの GitHub Actions 対応については、
flutter github actions でググれば、既に多くの方々が資料を公開されていますので、
レポートでは、主に nektos/act を使ったローカルでの GitHub Actions ワークフロー実行について紹介します。
act によるローカル GitHub Actions ワークフロー実行例
Quickstart for GitHub Actions - GitHub Docs に従い、GitHub Actions ワークフローを作ります。
GitHubのリポジトリに .github/workflows
ディレクトリを作成します。
yaml 形式でタスクを記述する任意名のワークフローファイル
を追加します。
Widget testを実行させるので extreme_widget_test.yml
としました。
ワークフローファイルに CI/CD ⇒ 継続的インテグレーション/継続的デリバリーのタスクを記述します。
Pull Requestイベントで、flutter環境を構築してflutter test test/
を実行するタスクを記述しました。
その他、GitHub Actionsの詳細については、Learn GitHub Actions - GitHub Docs を参照下さい。
flutter test test/
を実行します。
steps:
の設定は、subosito/flutter-action の README.md にある Usage サンプルを参考にしました。name: extreme widget test
on:
pull_request:
types: [opened, synchronize]
jobs:
extreme_widget_test:
name: flutter extreme widget test
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: set up repository
uses: actions/checkout@v2
- name: set up java
uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: '11'
- name: set up flutter
uses: subosito/flutter-action@v1
with:
channel: 'stable'
flutter-version: '2.8.0'
- name: flutter pub get
run: flutter pub get
# 全てのエクストリームWidgetテストを実行
- name: flutter exstreme widget test
run: flutter test test/
flutter test test/
が実行されるかチェックPull Request イベントとともにテストが実行されるようになり
テスト成功で Merge 可能になりました。
.github/Workflows/
から GitHub Actions のワークフロー yml を読み込みんでタスクを実行します。 docker
に依存しています。macOS への Docker Desktop インストール
Docker.dmg
ファイルをダウンロードして、Applications
にインストールするだけです。
Install Docker Engine(Docker Community Edition)
https://docs.docker.com/engine/install
Install Docker Engine on Ubuntu
https://docs.docker.com/engine/install/ubuntu/
上記の資料に従った、Ubuntuへの docker-ce インストール手順
1. Uninstall old versions
$ sudo apt-get remove docker docker-engine docker.io containerd runc
2. Set up the repository
$ sudo apt-get update
$ sudo apt-get install ca-certificates curl gnupg lsb-release
3. Add Docker’s official GPG key:
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
4. 安定版リポジトリを選択
$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
5. Install Docker Engine
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
6. インストール確認
$ docker --version
Docker version 20.10.11, build dea9396
$ brew install act
$ curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
$ curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
を実行すると、/usr/local/bin/
に act
実行ファイルがインストールされます。
/usr/local/bin/
に、実行ファイル act
がインストールされる。# インストール確認
$ act --version
act version 0.2.25
$ which act
/usr/local/bin/act
act コマンドでの引数について
act コマンドは、act [<event>] [options]
のフォーマットを取り、
event には、yml ファイル(ワークフロー)の on:
で定義した、push:
や pull_request:
などの GitHub イベントを与えます。
options には、act ーl
⇒ デフォルトアクション一覧や、act -j test
⇒ test jobを実行などがあります。
イベントやオプションがない場合、デフォルト値として push イベントが割り当てられます。
詳細については、Example commands ⇒ https://github.com/nektos/act#example-commands を参照下さい。
ちなみに本件のワークフローでは、$ act pull_request
コマンドでテストが実行されます。
act 実行時には、以下のような WARN警告や 選択を促されることがあります。
⚠ You are using Apple M1 chip and you have not specified container architecture, you might encounter issues while running act.
If so, try running it with ‘–container-architecture linux/amd64’. ⚠
M1 macで問題がある場合は、下記例のように linux/amd64 コンテナアーキテクチャを強制指定してみてください。
$ act pull_request --container-architecture linux/amd64
Please choose the default image you want to use with act:
デフォルトのイメージサイズの選択を要求されるので Medium を選択します。
~/.actrc
に保管されます。~/.actrc
に選択したイメージサイズが設定されます。~/.actrc
ファイルの設定例
-P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest
-P ubuntu-20.04=ghcr.io/catthehacker/ubuntu:act-20.04
-P ubuntu-18.04=ghcr.io/catthehacker/ubuntu:act-18.04
unix /var/run/docker.sock: connect: permission denied
となる場合の対処# グループへのユーザー所属のない状況で、sudo なしで実行
$ docker images
# permission denied とされてエラーになる。
# docker グループ確認(ユーザーの所属なし)
$ getent group docker
docker:x:998:
# docker グループにユーザー(robo)を所属させる。(実行時にパスワード入力が求められます)
$ sudo gpasswd -a robo docker
# docker グループ確認(ユーザー所属あり)
$ getent group docker
docker:x:998:robo
# PC再起動後に実行
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
# 注意)docker グループに自分を所属させるためセキュリティ的に問題があります。
# gpasswd コマンドの詳細や、ユーザーをグループから外すには下記を参照下さい。
#【 gpasswd 】コマンド――ユーザーが所属するグループを管理する
# https://atmarkit.itmedia.co.jp/ait/articles/1612/12/news016.html
flutter pub get
タスクでエラーが発生して終了するため、pull_request:
イベントをトリガーに指定していますので、$ act pull_request
のようにオプションでイベントを指定すれば、flutter exstreme widget test
タスクの 起動Run
〜 テスト成功Success
までが出力されています。
[extreme widget test/flutter extreme widget test] ⭐ Run flutter exstreme widget test
[extreme widget test/flutter extreme widget test] 🐳 docker exec cmd=[bash --noprofile --norc -e -o pipefail /home/rie/development/workspaces/github_actions/flutter_extreme_test_sample/workflow/4] user= workdir=
00:10 +0: /home/rie/development/workspaces/github_actions/flutter_extreme_test_sample/test/widget_extreme_test.dart: Counter increments extreme smoke test
| before increment - counter = 0
| after increment - counter = 1
| test end
00:10 +1: /home/rie/development/workspaces/github_actions/flutter_extreme_test_sample/test/widget_test.dart: Counter increments smoke test
| test end
00:10 +2: All tests passed!
[extreme widget test/flutter extreme widget test] ✅ Success - flutter exstreme widget test
エクストリームテストとは、テスト設計できるようになろう での独自用語です。
アプリコード内に「テスト中にコンポーネントツリー内の任意オブジェクトを
外部参照可能なオブジェクトに差し替えられる」独自Factory を導入することで、
Widget test や Integration test の中で、テストダブルの注入やコンポーネント状態の
確認ができるようにした Extreme ⇒ 極端なテストを表します。
Riverpodを使っているのでしたら、
当該テスト用のウィジェットツリーとして、ProviderScope()の overrides: オプション引数で
クロージャ内の必要なproviderオブジェクトを上書きしたルートウィジェットを作っても良いでしょう。
See Overriding the behavior of a provider during tests.
flutter test integration_test/app_extreme2_test.dart
⇒ エミュレータでの integration test 実行状況。
integration test 起動画面から一覧画面が表示され、リスト上端の appleを選択して、詳細画面に遷移するかを確認しています。
main2.dart
の Integration test と Widget test は、同じテストコードにしていますので御確認下さい。
【留意事項】エクストリームテストで、integration test と widget test で同一内容のテストが行わることの確認。
main2.dart
の Integration test と Widget test で同じテストが行われていることは、ログ出力の一致で確認できます。
勿論制限がありますが、エミュレータ起動を伴わないコンテナサーバ上での CI/CD テストへの応用を考えたいですね。
main2.dart
Integration test のログ出力
main2.dart
Widget test のログ出力push
や pull request
なしに、CI/CD ワークフローを試せそうです。セッション テスト設計できるようになろう の
Widget testで状態プロパティを参照する - エクストリームテスト の サンプルプロジェクト をベースに、
GitHub Actions と nektos/act を使い、Pull requestイベントで flutter test test/
を実行するようにしたレポートは以上です。