FlutterプロジェクトでGitHub Actionsを使って静的解析&自動テストを行ってみましたので記事にします。
特定のブランチにプルリクしたときに静的解析が通るかどうかを調べて、テストを自動で行ってくれるようになります。
今回作業したプロジェクトはこちらです。
静的解析を導入
Flutterの静的解析は色々とパッケージが用意されています。
こちらの記事に非常にわかりやすく書かれています。
Dart/Flutter の静的解析強化のススメ
【Dart/Flutter】静的解析の強化と注意
基本的には、静的解析のためのパッケージ(lintやpedanticなど)を導入して、プロジェクト直下にコーディングルールを指定するためのanalysis_options.yaml
を配置すると、そのルールに従ってIDEが警告を出してくれたり、コンパイル時に確認してくれるようになります。
私の場合は純粋にpedanticを導入するにとどめました。
以下のパッケージを入れて、
dev_dependencies:
pedantic: ^1.9.0
pedanticの公式GitHubリポジトリのlib/にanalysis_options.yaml
の例がありますので、これ真似して自分のプロジェクトの直下にコピーしておいても良いですし、
pedanticの導入バージョンの最新のルールで良ければ、公式のやり方に従って、プロジェクト直下に以下のファイルを配置すればOKです。
include: package:pedantic/analysis_options.yaml
Android Studioの画面最下部のDart Analysisタブを開くと、エラーや警告が一覧となって確認できます。
GitHub Actionsでテスト&静的解析を自動化
以下の記事を参考に少し変更して、静的解析とテストを自動化しました。
Flutter の快適 GitHubActions まとめ
プロジェクト直下に.github/workflows
というフォルダを作成し、その中にyamlファイルを置いていきます。
まずは静的解析用のflutter_analyze.yaml
です。
name: Flutter_Analyzer
on:
pull_request:
types: [opened, synchronize]
push:
branches:
- main
- develop
jobs:
flutter_analyze:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 1
- uses: subosito/flutter-action@v1
with:
channel: 'stable'
- run: flutter pub get
- run: flutter analyze
on:
の部分がトリガーになっていて、今回はpull_request
とmain
、develop
ブランチへのpush
に対して行うようにしました。
jobs:
の部分で実際に何を行うかを定義しますが、参考の記事に書いてあったものを大部分流用しています。
timeout-minutesは文字通りタイムアウトを定義するのですが、初め1分で指定したところ解析が終わらずタイムアウトしていたので、適当に10分にしています。
コードが長くなるとその分時間がかかるでしょうから、タイムアウトが発生したらチューニングが必要そうです。
analyzeでエラー
また、ローカルのflutter analyzeではエラーが出ないのに、GitHubActions上では失敗するという事象が発生しました。
詳しくは以下の記事に載っていますが、channel
がbeta
になっていたからのようです。
※上記に載せたflutter_analyze.yaml
はstable
に修正してますのでローカルのchannel
と合わせるようにしてください。
Flutter + GitHub Actions で flutter analyze に失敗したときの対処法
channel
はターミナル上で以下のように確認できます。
XXX\AndroidStudioProjects\todo_app_sample_flutter> flutter channel
Flutter channels:
master
dev
beta
* stable
変更したければ以下のように打てば良いです。
> flutter channel stable
> flutter upgrade
エラーが発生すると以下のように、プロジェクトの「Actions」タブで赤丸の×が表示されます。
テスト自動化
テスト自体の書き方は以下で詳しく書いていますのでご参照ください。
Flutterで単体テストを書く
【Flutter】Providerで最低限のDIを行ってテスタブルなコードにリファクタリングする
テストの方は以下のようなyamlとしました。先に結果を示しておきます。
name: Flutter_Test
on:
pull_request:
types: [opened, synchronize]
push:
branches:
- main
- develop
jobs:
flutter_test:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 1
- uses: subosito/flutter-action@v1
with:
channel: 'stable'
- run: flutter pub get
- run: flutter test --no-test-assets --coverage --coverage-path=~/coverage/lcov.info
- uses: codecov/codecov-action@v1
with:
token: ${{secrets.CODECOV_TOKEN}}
file: ~/coverage/lcov.info
純粋にrun: flutter test
でも良いのですが、今回はcodecovを使ってカバレッジを可視化するところまで自動化しました。
Codecovでカバレッジ可視化
codecovはテストのカバレッジを可視化できるサービスです。publicリポジトリであれば無料で利用でき、privateでも個数の制限の限りは無料で使えるようです。
codecov
GitHubのアカウントでログインできるので、そちらを選択すると以下のようなページに飛ぶのでAuthorize codecovを押して許可しましょう。
ログインが完了したらrepository選択できる画面が表示されるので、「Add a repository」をクリックします。
Choose a new repository belowと出てくるので、追加するrepositoryを選択します。
選択出来たら、以下のようにTOKENが発行されますので、GitHubのページに貼り付けるためにコピーしておきます。
プロジェクトのSettingsのSecretsを押してNew Repository Secretをクリックすると以下の画面が表示されます。
Nameを適当に設定して、valueの欄に先ほどコピーしたTOKENを張り付けてから「Add secret」をクリックします。
準備が整いましたので、トリガーに指定したようにプルリクをオープンするかmain、developにプッシュしてみます。
成功すると、codecov上にカバレッジの情報が表示されます。
以下のようにファイル毎にどこがテストできていないのかなどが可視化されます。
Macであればローカルでも可視化できる
codecovはWindows環境でもMac環境でも利用できますが、Mac環境の場合、lcovというツールを使えば、ローカル環境でカバレッジを可視化することができます。
ターミナル上で以下のコマンドを実行します
brew install lcov
flutter test --coverage
genhtml coverage/lcov.info -o coverage/html
すると、プロジェクト直下にcoverageというフォルダができています。
展開すると下記の様に、htmlの静的ページが生成されています。
Finderでたどって、index.htmlを開くと以下のようにカバレッジが表示できます。
ファイル毎に細かく表示することができ、どのメソッドのテストが出来ていないかも見ることができます。
まとめ
GitHub Actionsを使って静的解析と単体テストの自動化を行いました。
カバレッジの可視化についても思っていたより簡単に実装出来ました。
カバレッジがXX%を超えていなければプルリクを通さない、などの設定も行えるようなので
プロジェクトのルールを決めて運用すると品質を保つのに貢献できそうです。
GitHub Actionsでは他にもデプロイを自動化したりもできるようなので、機会があればまた記事にしようと思います。
2021/4/9 追記
こちらに関する発表を行いました。
以下が発表スライドです。
2021/4/16 追記
2021/1/31~2021/4/15の期間でcodecovに不正アクセスがあったようです。codecovを用いてGitHub Actionsから自動でカバレッジを計測していた場合は、
こちらの記事を参考にしてセキュリティの問題に対応してください。