RailsにRSpecを導入して、Cloud BuildでCI/CDパイプラインを構築するところまでをまとめています。
目次
RailsにRSpecを導入する
まずはRailsにRSpecを導入します。
実際にローカル環境でRSpecによるテストができるところまでの手順をまとめています。
「rspec-rails」、「factory_bot_rails」、「rails-controller-testing」のインストール
Gemfileを以下の3つのGemを追加しbundle installします。
・Gemfile
1 2 3 4 5 | group :development, :test do gem 'rspec-rails' gem 'factory_bot_rails' gem 'rails-controller-testing' end |
RSpecに必要なファイルを生成する
以下のコマンドでRSpecに必要なファイルを生成します。
1 | $ bundle exec rails generate rspec:install |
成功すると以下の3つのファイルが生成されていることが確認できます。
1 2 3 | .rspec spec/spec_helper.rb spec/rails_helper.rb |
RSpec実行に必要な設定をする
Factory Botの設定をrails_helper.rbに追加します。
・spec/rails_helper.rb
1 2 3 4 5 6 | RSpec.configure do |config| ... config.include FactoryBot::Syntax::Methods end |
Rails.loggerのログを出力するには以下を追加します。
1 | Rails.logger = Logger.new(STDOUT) |
rspec用のテストファイルを作成するために、application.rbに以下を追加します。
・application.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 | config.generators do |g| ... g.test_framework :rspec, fixtures: true, view_specs: false, helper_specs: false, routing_specs: false, controller_specs: true, request_specs: false g.fixture_replacement :factory_bot, dir: "spec/factories" end |
.rspecに以下を追加するとテストの実行結果が見やすくなります。
・.rspec
1 | --format documentation |
テストを作成する
factoriesやcontrollerを用意し、テストを作成していきます。
今回はテスト作成の過程は省略します。詳しくは以下の記事などを参考にしてください。
例として本のデータを取得するAPIの本コントローラのshowメソッドに対してテストを行います。
・spec/factories/books.rb
1 2 3 4 5 | FactoryBot.define do factory :book do name {'テスト本'} end end |
・spec/controllers/books_controller_spec.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | describe Api::BooksController, type: :controller do context '/api/books' do describe 'GET #show' do render_views before do @book = create(:book) get :show, params: { id: @book.id } @json = JSON.parse(response.body) end it '200チェック' do expect(response).to be_success expect(response.status).to eq 200 end it '本データチェック' do expect(@json[name]).to eq(@book.name) end end end end |
ローカルでテストが実行できるか確認します。
1 | $ docker-compose exec web bundle exec rspec |
正常にテストが成功すると以下のようなログが出力されます。
1 2 | Finished in 0.58604 seconds (files took 4.32 seconds to load) 2 examples, 0 failures |
Cloud BuildでRSpecを組み込む
ローカルでのRSpecによるテストが確認できたら、Cloud BuildにRSpecを組み込んでCI/CDパイプラインを構築していきます。
Dockerfileの作成
Rubyの公式イメージを元に作成しています。
テストする際のDBの接続先はMariaDBを使用します。
・Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | FROM ruby:2.5.8-alpine3.11 RUN set -ex \ && apk update \ && apk upgrade \ && apk add --no-cache \ build-base \ bash \ curl \ nodejs \ tzdata \ mariadb \ mariadb-client \ mariadb-dev \ openrc \ libc6-compat \ gcompat \ && mkdir -p /run/openrc \ && touch /run/openrc/softlevel \ && rc-status \ && /etc/init.d/mariadb setup \ && gem install bundler RUN mkdir /app_name ENV APP_ROOT /app_name WORKDIR $APP_ROOT ADD ./Gemfile $APP_ROOT/Gemfile ADD ./Gemfile.lock $APP_ROOT/Gemfile.lock RUN bundle install ADD . $APP_ROOT |
テスト用のDB設定
database.ymlに以下のようにテスト用のDBを設定します。
・database.yml
1 2 3 4 5 6 7 8 | test: adapter: mysql2 encoding: utf8 reconnect: false pool: 5 username: root password: password database: test_db |
テスト実行用のシェルスクリプト作成
Cloud Buildで実行するシェルスクリプトを作成します。
MariaDBを起動して、DBを作成しテストを実行できる環境を整えます。その後、テストを実行します。
・rspec.sh
1 2 3 4 5 6 7 8 9 10 | #!/bin/bash # MariaDBの起動 rc-service mariadb start # テスト用DB作成・マイグレーション RAILS_ENV=test rails db:create db:migrate # RSpecテスト実行 RAILS_ENV=test bundle exec rspec |
Dockerイメージを作成し、RSpecのテストを行いGAEにデプロイする
cloudbuild-staging.yamlのスクリプトでDockerイメージの作成、RSpecのテスト、GAEのステージング環境にデプロイを行います。いわゆるCI/CDパイプラインを構築して、実行しています。
Gitでプッシュするとcloudbuild.yamlのスクリプトが自動で実行されるようにしています。
Cloud BuildとGitの連携方法に関してはここでは省略しています。
・cloudbuild-staging.yaml
1 2 3 4 5 6 7 8 9 | steps: - name: 'alpine' args: ['echo', '${_ENVIRONMENT}'] - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'gcr.io/$PROJECT_ID/cloud-build-rspec', '.'] - name: 'gcr.io/$PROJECT_ID/cloud-build-rspec' args: ['/bin/bash', 'rspec.sh'] - name: 'gcr.io/cloud-builders/gcloud' args: ['app', 'deploy', 'app-staging.yaml'] |
Cloud BuildでRSpecによる自動テストの動作確認
テスト失敗時
テスト失敗した際の挙動を確認します。
テストが失敗するとCloud Buildのステップが停止し、デプロイされることはありません。
テスト成功時
テスト成功時の挙動を確認します。
テストが成功すると、そのままGAEへのデプロイが始まり、無事完了しました。
参考