Railsチュートリアル二周目の完走記念にスクショ pic.twitter.com/zOGZtYrKRD
— sasaki (@yysaki) 2019年4月29日
未経験からRuby on Railsを学んで仕事につなげるまでの1000時間メニュー の一環で、先日 Ruby on Railsチュートリアルの2周しました。
2周目をやるとき、単純に動かすだけでは面白みに欠けるので、図のようにCIでminitestのカバレッジを都度取るようにしてみました:
このURLから参照できます。
ここではチュートリアルの作業リポジトリを使ってCIでテストカバレッジをとるまでの手順を記録します。
前提
- Ruby on Rails チュートリアル第4版 を順番通り行う
- Rubyのversionは2.6.3を使用
- GitHubの公開リポジトリをCircleCIと連携
- simplecovとCoverallsを使ってテストカバレッジを取得
CircleCIでrails testを回す
本チュートリアルでGit管理を行う点が触れられていますが、ここでホスティングをBitbucketではなくGitHubを使ってみます。
このとき、安全にソースコードを公開するにあたってアクセスキートークンなどプロジェクト固有の情報をENVから取るように確認しています。
次に、CircleCI公式の手順に従い連携の設定を行います。
Language Guide: Ruby - CircleCI
具体的には、リポジトリに以下のような .circleci/config.yml を配置します。
version: 2
jobs:
build:
docker:
- image: circleci/ruby:2.6.3-node
environment:
BUNDLE_PATH: vendor/bundle
RAILS_ENV: test
working_directory: ~/repo
steps:
- checkout
- run:
name: Configure Bundler
command: |
echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV
source $BASH_ENV
gem install bundler
- restore_cache:
keys:
- v1-dependencies-{{ checksum "Gemfile.lock" }}
- v1-dependencies-
- run:
name: Bundle Install
command: bundle check || bundle install --without development production
- save_cache:
paths:
- ./vendor/bundle
key: v1-dependencies-{{ checksum "Gemfile.lock" }}
- run:
name: Run rails test
command: |
bundle exec rails db:migrate
bundle exec rails test
Configure Bundler
の箇所は、Bundlerを動かすためのワークアラウンドです。
2.0系のbundlerで生成されたGemfileを使用すると
You must use Bundler 2 or greater with this lockfile.
Exited with code 20
といったエラーを吐いてしまうため、 フォーラムで紹介されていたGemfile.lock記載のバージョンを使う対処を入れました。
Using Bundler 2.0 during CI fails - Bug Reports - CircleCI Discuss
また、 bundle install --without development
することで、spring のトラブルを回避するのも大事です。
- Use Bundler.with_original_env so that BUNDLER_APP_CONFIG is honored by mattbrictson https://github.com/rails/spring/pull/546
上記pull requestで修正されている不具合ですが、springのバージョンがbump upされる気配があまりなく、初めはgithubブランチをGemfileで指定する形でお茶を濁していました。
gem 'spring', github: 'mattbrictson/spring', branch: 'honor-bundle-app-config'
ですがこのことをRubyKaigi 2019のコード懇親会で相談したところ、springは開発環境のビルドを高速化するためにありCIでは不要だから、そもそも外せばいいのではと助言いただきました。
その結果上記対処をしてひと満足しています。
simplecov
チュートリアルのminitestから行単位でどれだけ網羅されたのかカバレッジを取得してくれるツールとして simplecov を使用します。
READMEを参考に、以下のような設定を行いました
.gitignore:
coverage/
Gemfile:
group :test do
...
gem 'simplecov'
end
test/test_helper.rb:
if ENV['RAILS_ENV'] == 'test'
require 'simplecov'
SimpleCov.start 'rails' do
add_filter '/.bundle/'
add_filter '/vendor/bundle/'
end
end
ENV['RAILS_ENV'] ||= 'test'
...
この設定により、 rails test
を実行すると coverage/配下にテストカバレッジのドキュメントが生成されます。
参考: Ruby on Rails – gem SimpleCovを使ってテストカバレッジを計測|Miningoo
Coveralls
CoverallsはGitHubと連携して取得したカバレッジを可視化してくれるサービスです。
Ruby on Rails | Coveralls Docs
最後にこちらのSIMPLECOV CUSTOMIZATIONの手順を参考に設定を行います。
Gemfile:
group :test do
...
gem 'simplecov'
gem 'coveralls', require: false
end
test/test_helper.rb:
if ENV['RAILS_ENV'] == 'test'
require 'simplecov'
require 'coveralls'
SimpleCov.formatter = Coveralls::SimpleCov::Formatter
SimpleCov.start 'rails' do
...
以上で設定完了です。
githubにpushすると自動テストが走り、テストカバレッジが収集されるようになりました。
図のようにチュートリアルの通りminitestをしっかりを書いた結果をみると、演習中タッチしてないapplication_cableなど除くと大半が100%となるのがわかります。
チュートリアルのテストがしっかり網羅性のある手順を踏んでいることがわかり、ためになります。
一部0でも100%でもないものがありますが、例えばapp/model/user.rb ではBCryptの設定による分岐によるものでした。
必ずしもテストカバレッジは100%を目指すものではないとよく聞きますが、たしかにこの箇所はチェックする必要がなさそうです。
以上です。