My goldens fail on GithubActions, flutter test
run on Ubuntu
image, since MacOS renders UI a bit differently. We’re talking 0% < diff < 2%.
So I decided to generate the goldens on Ubuntu image, on my local machine, so that the tests pass.
Docker to the rescue! I’ve attached my Dockerfile and a Makefile.
tl;dr
-
Dockerfile downloads the flutter sdk and sets up env.
-
Makefile runs the docker container and then runs the test inside it
Fun part:
I’m trying to mount
my existing code dir, .pub_cache
dir into the Docker container to avoid pulling the code and running flutter pub get
But my tests are failing!
Note: This test pass when I run it on my local machine
make test_app test/common/cached_image_view_test.dart
developer@be8993ac66b3:~/wildr_flutter$ flutter test test/community/join_community_page_test.dart
00:37 +0 -1: loading /home/developer/wildr_flutter/test/community/join_community_page_test.dart [E]
Error: the Dart compiler exited unexpectedly.
package:flutter_tools/src/base/common.dart 10:3 throwToolExit
package:flutter_tools/src/compile.dart 885:13 DefaultResidentCompiler._compile.<fn>
dart:async/zone.dart 1391:47 _rootRun
dart:async/zone.dart 1301:19 _CustomZone.run
dart:async/zone.dart 1209:7 _CustomZone.runGuarded
dart:async/stream_impl.dart 392:13 _BufferingStreamSubscription._sendDone.sendDone
dart:async/stream_impl.dart 402:7 _BufferingStreamSubscription._sendDone
dart:async/stream_impl.dart 291:7 _BufferingStreamSubscription._close
dart:async/stream_transformers.dart 87:11 _SinkTransformerStreamSubscription._close
dart:async/stream_transformers.dart 21:11 _EventSinkWrapper.close
dart:convert/string_conversion.dart 241:11 _StringAdapterSink.close
dart:convert/line_splitter.dart 141:11 _LineSplitterSink.close
dart:async/stream_transformers.dart 132:24 _SinkTransformerStreamSubscription._handleDone
dart:async/zone.dart 1391:47 _rootRun
dart:async/zone.dart 1301:19 _CustomZone.run
dart:async/zone.dart 1209:7 _CustomZone.runGuarded
dart:async/stream_impl.dart 392:13 _BufferingStreamSubscription._sendDone.sendDone
dart:async/stream_impl.dart 402:7 _BufferingStreamSubscription._sendDone
dart:async/stream_impl.dart 291:7 _BufferingStreamSubscription._close
dart:async/stream_transformers.dart 87:11 _SinkTransformerStreamSubscription._close
dart:async/stream_transformers.dart 21:11 _EventSinkWrapper.close
dart:convert/string_conversion.dart 241:11 _StringAdapterSink.close
dart:convert/string_conversion.dart 295:20 _Utf8ConversionSink.close
dart:convert/chunked_conversion.dart 78:18 _ConverterStreamEventSink.close
dart:async/stream_transformers.dart 132:24 _SinkTransformerStreamSubscription._handleDone
dart:async/zone.dart 1391:47 _rootRun
dart:async/zone.dart 1301:19 _CustomZone.run
dart:async/zone.dart 1209:7 _CustomZone.runGuarded
dart:async/stream_impl.dart 392:13 _BufferingStreamSubscription._sendDone.sendDone
dart:async/stream_impl.dart 402:7 _BufferingStreamSubscription._sendDone
dart:async/stream_impl.dart 291:7 _BufferingStreamSubscription._close
dart:async/stream_controller.dart 792:19 _SyncStreamControllerDispatch._sendDone
dart:async/stream_controller.dart 647:7 _StreamController._closeUnchecked
dart:async/stream_controller.dart 640:5 _StreamController.close
dart:io-patch/socket_patch.dart 2454:21 _Socket._onData
dart:async/zone.dart 1415:13 _rootRunUnary
dart:async/zone.dart 1308:19 _CustomZone.runUnary
dart:async/zone.dart 1217:7 _CustomZone.runUnaryGuarded
dart:async/stream_impl.dart 339:11 _BufferingStreamSubscription._sendData
dart:async/stream_impl.dart 271:7 _BufferingStreamSubscription._add
dart:async/stream_controller.dart 784:19 _SyncStreamControllerDispatch._sendData
dart:async/stream_controller.dart 658:7 _StreamController._add
dart:async/stream_controller.dart 606:5 _StreamController.add
dart:io-patch/socket_patch.dart 1943:35 new _RawSocket.<fn>
dart:io-patch/socket_patch.dart 1372:18 _NativeSocket.issueReadEvent.issue
dart:async/schedule_microtask.dart 40:21 _microtaskLoop
dart:async/schedule_microtask.dart 49:5 _startMicrotaskLoop
dart:isolate-patch/isolate_patch.dart 118:13 _runPendingImmediateCallback
dart:isolate-patch/isolate_patch.dart 185:5 _RawReceivePort._handleMessage
Failed to load "/home/developer/wildr_flutter/test/community/join_community_page_test.dart": Compilation failed for testPath=/home/developer/wildr_flutter/test/community/join_community_page_test.dart
To run this test again: /home/developer/flutter/bin/cache/dart-sdk/bin/dart test /home/developer/wildr_flutter/test/community/join_community_page_test.dart -p vm --plain-name 'loading /home/developer/wildr_flutter/test/community/join_community_page_test.dart'
Dockerfile
# github actions ubuntu-latest is 22.04
FROM ubuntu:22.04
# Prerequisites
ARG DEBIAN_FRONTEND=noninteractive
RUN apt update && apt install -y curl git unzip xz-utils zip libglu1-mesa openjdk-11-jdk wget
# Set up new user
RUN useradd -ms /bin/bash developer
USER developer
WORKDIR /home/developer
# flutter_version=$(flutter --version | awk 'NR==1{print $2}')
ARG flutter_version
RUN git clone https://github.com/flutter/flutter.git -b ${flutter_version}
ENV PATH "$PATH:/home/developer/flutter/bin"
# Run basic check to download Dark SDK
RUN flutter doctor
Here’s my Makefile
# set the path of the flutter installation on the local machine to share it with the docker container
flutter_dir = $$(which flutter)
# set the path of the current project directory on the local machine to share it with the docker container
wildr_flutter_dir = $$(git rev-parse --show-toplevel)/wildr_flutter
# set the flutter version to use the same in the docker container
flutter_version = $$(flutter --version | grep -m 1 -o '[0-9]*.[0-9]*.[0-9]*')
# Base command to run the docker container
docker_build_image := docker build --build-arg flutter_version=$(flutter_version) -t docker_tests $(wildr_flutter_dir)/docker/
docker_run_image_docker_tests = docker run -it -v $(wildr_flutter_dir):/home/developer/wildr_flutter -v ~/.pub-cache:/home/developer/.pub-cache -e PUB_CACHE="/home/developer/.pub-cache" docker_tests
# get every argument after the make command
RUN_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
# check if the update-goldens option is given
ifeq ($(findstring update-goldens,$(RUN_ARGS)),update-goldens)
update-goldens="--update-goldens"
else
update-goldens=""
endif
# check if the coverage option is given
ifeq ($(findstring coverage,$(RUN_ARGS)),coverage)
coverage="--coverage"
else
coverage=""
endif
# We check if a testPath option is given
ifeq ($(filter test/%.dart,$(RUN_ARGS)),)
testPath=""
else
testPath="$(filter test/%.dart,$(RUN_ARGS))"
endif
test_app: CMD = cd wildr_flutter &&
pwd &&
flutter test $(testPath) $(update-goldens) $(coverage)
test_app:
(cd $(wildr_flutter_dir) && $(docker_build_image) && $(docker_run_image_docker_tests) /bin/sh -c "$(CMD)")
run_bash:
(cd $(wildr_flutter_dir) && $(docker_build_image) && $(docker_run_image_docker_tests) bash)
I tried manually running flutter pub get
in the container. No luck :/