LoginSignup
2
0

More than 3 years have passed since last update.

Ruby 3.x, Rails 6.x, MySQL 8.x のプロジェクトを CircleCI に設定し RSpec と Rubocop を実施する。

Last updated at Posted at 2021-02-27

概要

前回の記事 Ruby 3.x, Rails 6.x, MySQL 8.x の Docker 環境構築。 を引き継いで、プロジェクトを CircleCI に設定し、GitHub リポジトリへの push 時に RSpec と Rubocop を自動実施するように設定します。

基本的に以下の CircleCI 公式ドキュメントを参考にしていますので、初期設定の方法などはそちらをご確認ください。
大きく違うのは、Ruby on Rails で MySQL に対応した点です。

前提

下記の環境が準備されていること。

  • GitHub のアカウントを持っていること(無料版でも大丈夫)
  • 上記の GitHub アカウントに紐づいた CircleCI のアカウントを持っていること(無料版でも大丈夫)
  • Docker を利用した Ruby on Rails のプロジェクトが作成されていること

今回は CircleCI の設定が主になるため、Docker や RSpec、Rubocop の細かい説明は省きます。

RSpec と Rubocop の組み込み

Gemfile を編集し、:development と :test 環境に rubocop(ついでに pry-byebug と factory_bot_rails)を、:test 環境に rspec-rails と database_cleaner-active_record を追加します。

gem についてはプロジェクトごと、必要に応じて対応してください。

.Gemfile

.Gemfile

group :development, :test do
  # 略
  gem 'pry-byebug'
  gem 'factory_bot_rails'

  # https://github.com/rubocop-hq/rubocop
  gem 'rubocop', '~> 1.10.0', require: false
end

group :test do
  # 略
  gem 'rspec-rails', '4.0.2'

  gem 'database_cleaner-active_record'
end

設定後、bundle install と RSpec のインストール rails g rspec:install、rubocop の設定ファイル作成 bundle exec rubocop --auto-gen-config を実行します。
前回のプロジェクトは Docker で作成していたため、その場合は以下のように docker-compose を使用します。
なお、minitest 用の test フォルダが不要な場合は削除してください。

$ docker-compose run app bundle install
$ docker-compose run app rails g rspec:install
$ docker-compose run app bundle exec rubocop --auto-gen-config

config/application.rb

Scaffold 実行時に RSpec のスケルトンを自動生成するかどうかの設定を APP::Application クラス内に記入します。自動生成が不要な場合は g.test_framework false とします。
また、FactoryBot についても書いておきます。

config/application.rb
module App
  class Application < Rails::Application
    config.generators do |g|
      g.test_framework :rspec,
                       feature_specs: true,
                       fixtures: false,
                       view_specs: true,
                       helper_specs: false,
                       routing_specs: false,
                       controller_specs: false,
                       request_specs: true,
                       system_specs: true

      g.factory_bot false
      g.factory_bot dir: 'spec/factories'
    end
  end
end

rubocop ファイル

bundle exec rubocop --auto-gen-config を実行することで .rubocop.yml と .rubocop_todo.yml ファイルが作成されます。

.
├── rubocop.yml
└── rubocop_todo.yml

実際の rubocop の運用については公式サイトを確認してください。

cf. rubocop / rubocop

大まかな手順としては、rubocop --auto-gen-config 実施時にエラーになった箇所が _todo.yml の方に記載されるので、そこから修正するつもりがない設定を .rubocop.yml に移動し、それ以外は _todo.yml からは削除し、エラー要素を実ファイルから修正していくことになります。

CircleCI の設定

本題の CircleCI の設定となります。

.circleci/config.yml

.
└── .circleci/
    └── config.yml

.circleci/config.yml は Docker の docker-compose.yml と少し似ています。
今回はリポジトリへの push 時に RSpec と rubocop を自動実施するためのモノなので、設定する環境は test となります。

注意点としては、この設定では MySQL および Docker の仕組み上、CircleCI 実施時に MySQL のコンテナで頻繁に mbind: Operation not permitted という警告が出ますが、いまのところ無視するしかないようです。
(Docker だけの対応では cap_add: - SYS_NICE を付加することで警告が非表示になるようですが、CircleCI では設定できません)

cf. circleci コンテナの立ち上げ失敗&ビルドがキャンセルされる?

また、イメージのタグは以下の一覧から 2021/02 現在の安定最新版を探しました。
cf. https://circleci.com/docs/ja/2.0/docker-image-tags.json

circleci/config.yml
version: 2.1

orbs:
  ruby: circleci/ruby@1.1.2
  node: circleci/node@4.2.0

jobs:
  build:
    docker:
      - image: cimg/ruby:3.0.0-node
    steps:
      - checkout
      - ruby/install-deps
      - node/install-packages:
          pkg-manager: yarn
  test:
    docker:
      - image: cimg/ruby:3.0.0-node
        environment:
          RAILS_ENV: test
      - image: circleci/mysql:8.0.4
        name: db
        command: mysqld --default-authentication-plugin=mysql_native_password
        environment:
          MYSQL_DATABASE: app_test
          MYSQL_USER: user
          MYSQL_PASSWORD: password
    environment:
      BUNDLE_JOBS: "3"
      BUNDLE_RETRY: "3"
    steps:
      - checkout
      - ruby/install-deps
      - node/install-packages:
          pkg-manager: yarn
      - run:
          name: Wait for DB
          command: dockerize -wait tcp://db:3306 -timeout 1m
      - run:
          name: Database setup
          command: bundle exec rails db:schema:load --trace
      - ruby/rspec-test
      - ruby/rubocop-check

workflows:
  version: 2
  build_and_test:
    jobs:
      - build
      - test:
          requires:
            - build

ここまで追加したものを登録済みの GitHub に push しておきます。

CircleCI サイトでのプロジェクトの設定

https://app.circleci.com/ にログインし、GitHub と連携したプロジェクト(リポジトリ)を設定します。
詳細な手順は 入門ガイド を確認してください。

GitHub と連携できている場合は Projects ページにリポジトリの一覧が表示されるため、対象となるもので「Set Up Project」ボタンを押下します。

image.png

その後、すでに config.yml は設定済みのため、次の画面で「Use Existing Config」ボタンを押下します。

image.png

簡単な警告ダイアログが出ますが、「Start Building」ボタンを押下して先に進めます。

image.png

この時点で、設定に問題がなければ CircleCI の Dashboard に最初のテスト結果が「Success」として表示されます。

image.png

また、GitHub 側のリポジトリにも安心のチェックマークが表示されるようになります。
image.png

RSpec の実装

rubocop は書式の問題なのでさておき、RSpec の動作確認だけ簡単に説明します。

前提

前回の最後に scaffold で作成した users テーブルがあることとします。

$ docker-compose run app rails g scaffold user name:string email:string

バリデーション追加

User モデルにバリデーションを追加します。

app/models/user.rb
class User < ApplicationRecord
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i

  validates :name, presence: true, length: { maximum: 250 }
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }

  before_save { self.email = email.downcase }
end

FactoryBot

ユニットテストで使用するテストデータを事前に設定しておきます。

spec/factories/users.rb
FactoryBot.define do
  factory :user do
    sequence(:name) { |n| "test name#{n}" }
    sequence(:email) { |n| "test#{n}@example.com" }

    trait :empty do
      name { nil }
      email  { nil }
    end

    trait :invalid_email do
      sequence(:email) { |n| "test#{n}" }
    end
  end
end

モデルテスト

(ごく単純なものとなりますが、)モデルのテストを設定します。

spec/models/user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  describe '#valid?' do
    let!(:user) { described_class.new(attributes) }
    subject { user.valid? }

    context 'successful' do
      let!(:attributes) { attributes_for(:user) }
      it { is_expected.to be true }
    end

    context 'failure' do
      let!(:attributes) { attributes_for(:user, :invalid_email) }
      it { is_expected.to be false }
    end
  end
end

ローカルでの確認

ローカルで RSpec(と rubocop)を実施する場合は、以下のコマンドを実行して下さい。

$ docker-compose run app rspec
$ docker-compose run app rubocop

GitHub へ push

問題がなければ git commit と git push を行います。
これだけで GitHub へ反映されると同時に CircleCI が RSpec と rubocop を自動実行してくれます。

今回は RSpec と rubocop の実施だけですが、エラーがなかった場合にそのまま本番環境へのデプロイなどを行うことも可能です。

少し駆け足となってしまいましたが、今回は以上となります。

参考資料

以下の記事、情報を参考にさせていただきました。
ありがとうございます。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0