🙆
Flutter Golden Test / VRT の環境を合わせ、完全一致で比較する
はじめに
Flutter の Golden Test / VRT を行うことで、Widget の崩れや UI の変更を検知できます。
ただし、Flutter の Golden Test / VRT は、実行する環境によって差分が発生してしまうことがあります。
そのため、ローカルと CI で環境を合わせることで、完全一致で比較できると考えました。
環境
- ローカル
- macOS
- CI
- GitHub Actions
- Ubuntu
なぜ環境によって差分が発生するのか
ローカルでは macOS、CI では Ubuntu という異なる OS を使用しているため、フォントなどの違いにより生成される画像に微妙なズレが発生します。
関連 Issue: https://github.com/flutter/flutter/issues/56383
環境を合わせ、完全一致で比較する
環境によって差分が発生する場合、どのように対処すればよいでしょうか。
その方法として、ローカルでは Docker を利用し、CI と同じ Ubuntu 環境を再現する方法を試してみました。
Dockerfile
docker/flutter_golden_test/Dockerfile
FROM ubuntu:24.04
ARG FLUTTER_VERSION=3.29.2
ENV FLUTTER_VERSION=$FLUTTER_VERSION
RUN apt-get update && apt-get install -y \
curl \
git \
unzip \
xz-utils \
zip \
libglu1-mesa \
&& rm -rf /var/lib/apt/lists/*
RUN curl -o flutter.tar.xz https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_$FLUTTER_VERSION-stable.tar.xz \
&& mkdir -p /usr/local/flutter \
&& tar -xf flutter.tar.xz -C /usr/local/flutter --strip-components=1 \
&& git config --global --add safe.directory /usr/local/flutter \
&& rm flutter.tar.xz
ENV PATH="/usr/local/flutter/bin:$PATH"
RUN flutter doctor --android-licenses || true && flutter doctor || true
CMD ["flutter", "--version"]
実行コマンド
FLUTTER_VERSION=$(< .fvmrc jq -r .flutter) \
PREFIX=$(basename $(pwd))_ && \
docker buildx build \
--platform linux/x86_64 \
--build-arg FLUTTER_VERSION=${FLUTTER_VERSION} \
-t ${PREFIX}flutter_golden_test \
docker/flutter_golden_test && \
docker volume create \
${PREFIX}flutter_golden_test_dart_tool && \
docker run \
--rm -v $(pwd):/app \
-v ${PREFIX}flutter_golden_test_dart_tool:/app/.dart_tool \
--platform linux/x86_64 \
-it \
${PREFIX}flutter_golden_test flutter test --tags golden
※ ゴールデンファイルを更新する場合は --update-goldens
を付けて実行します。
-
FLUTTER_VERSION=〜
で FVM で管理している Flutter のバージョンを取得 -
PREFIX=〜
で Docker イメージやコンテナなどのプレフィックスを設定 -
docker buildx build
で Docker イメージをビルド- プラットフォームは
linux/x86_64
を指定 -
FLUTTER_VERSION
をビルド引数として渡す
- プラットフォームは
-
docker volume create
で.dart_tool
を保存するボリュームを作成 -
docker run
でコンテナを起動-
-v $(pwd):/app
でカレントディレクトリをマウント -
-v ${PREFIX}flutter_golden_test_dart_tool:/app/.dart_tool
で.dart_tool
をマウント -
--platform linux/x86_64
でプラットフォームを指定
-
VSCode 向け tasks.json
.vscode/tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "flutter test --tags golden",
"detail": "golden タグのテストを実行",
"type": "shell",
"command": "sh",
"args": [
"-c",
"FLUTTER_VERSION=$(< .fvmrc jq -r .flutter) PREFIX=$(basename $(pwd))_ && docker buildx build --platform linux/x86_64 --build-arg FLUTTER_VERSION=${FLUTTER_VERSION} -t ${PREFIX}flutter_golden_test docker/flutter_golden_test && docker volume create ${PREFIX}flutter_golden_test_dart_tool && docker run --rm -v $(pwd):/app -v ${PREFIX}flutter_golden_test_dart_tool:/app/.dart_tool --platform linux/x86_64 -it ${PREFIX}flutter_golden_test flutter test --tags golden"
]
},
{
"label": "flutter test --update-goldens --tags golden",
"detail": "golden タグのテストを実行してゴールデンファイルを更新",
"type": "shell",
"command": "sh",
"args": [
"-c",
"FLUTTER_VERSION=$(< .fvmrc jq -r .flutter) PREFIX=$(basename $(pwd))_ && docker buildx build --platform linux/x86_64 --build-arg FLUTTER_VERSION=${FLUTTER_VERSION} -t ${PREFIX}flutter_golden_test docker/flutter_golden_test && docker volume create ${PREFIX}flutter_golden_test_dart_tool && docker run --rm -v $(pwd):/app -v ${PREFIX}flutter_golden_test_dart_tool:/app/.dart_tool --platform linux/x86_64 -it ${PREFIX}flutter_golden_test flutter test --update-goldens --tags golden"
]
}
]
}
まとめ
ローカルと CI で Docker を利用し環境を合わせることで、Golden Test / VRT を完全一致で比較できるようになりました。
これにより、Widget の崩れや UI の変更をわずかな差分でも検知できるようになります。
最後まで読んでいただきありがとうございます。この記事が少しでも役に立ったと思ったら、Like♥ を押していただけると励みになります。
Discussion