Rails + MySQL + CircleCI で簡単なアプリ作ってみた

# はじめに
Qiita初投稿です！
巷によく聞くCircleCIを触ってみたくて簡単なアプリで実装してみた忘備録です。
遭遇したエラーを解決していく形で実装していきます。
間違いや修正点がありましたらご指摘いただけるとありがたいです！！

こちらの記事を参考にさせていただきました！
→　https://qiita.com/rentama/items/477d3dcae423373f7c0d

## 環境
- Rails: 5.2.3

## 概要
1. Railsアプリケーションと雛形の作成
2. rspecを用いたテストコードの記述
3. CircleCIでコミット時の自動テスト

# 1.Railsアプリケーションと雛形の作成
まずはアプリケーションを立ち上げましょう！

```terminal:ターミナル
$ rails _5.2.3_ new test-app -d mysql
```

今回は名前とテキストを持った商品テーブルを作成していきます

```terminal:/test-app
$ rails db:create 
$ rails g scaffold Item name:string text:string
$ rails db:migrate
$ rails s
```

http://localhost:3000/items/new で新規投稿ができるようになっています。
[![Image from Gyazo](https://i.gyazo.com/8e3af97ff8977be7033fe486f33e52fc.gif)](https://gyazo.com/8e3af97ff8977be7033fe486f33e52fc)

基本的なアプリは完成しました！
ここからrspecを使用してテストコードを書いていきます。

# 2. rspecを用いたテストコードの記述

まずはモデルにValidationをかけておきます。
実用的ではありませんが練習ということで…

```ruby:app/models/item.rb
  validates :name,   presence: true
  validates :text,   presence: true, length: {minimum: 5, maximum: 20}
```

次にrspecの設定を行っていきます
最初にGemをインストール

```ruby:Gemfile
gem 'rspec-rails'
```
bundle installしてRSpec用の設定ファイルを作成

```terminal:ターミナル
$ bundle install
$ rails g rspec:install
```
rspec用のファイルが作成されたと思います

```terminal:ターミナル
      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb
```

specディレクトリ以下にmodelsディレクトリを作成しitem_spec.rbにモデルのテストを書いていきます…

```ruby:spec/models/item_spec.rb
require 'rails_helper'

RSpec.describe Item, type: :model do
  it 'name存在し,textが5文字以上存在する時保存される' do
    item = Item.new(name: 'name', text: '12345')
    expect(item).to be_valid
  end
  it 'nameが存在しないので保存されない' do
    item = Item.new(text: '12345')
    expect(item).not_to be_valid
  end
  it 'textが存在しないので保存されない' do
    item = Item.new(name: 'name')
    expect(item).not_to be_valid
  end
  it 'textが５文字未満なので保存されない' do
    item = Item.new(name: 'name', text: '1234')
    expect(item).not_to be_valid
  end
end
```

テストコードが動いているか確認

```terminal:ターミナル
$ bundle exec rspec
2020-01-29 20:42:29 WARN Selenium [DEPRECATION] 

Finished in 0.02331 seconds (files took 1.94 seconds to load)
4 examples, 0 failures
```

準備オッケー！いよいよ本題です！


# 3. CircleCIでコミット時の自動テスト

最初に作成したアプリケーションをGitリポジトリに登録しておきましょう

[![Image from Gyazo](https://i.gyazo.com/93540dcb9842392eaea986e57d20e299.png)](https://gyazo.com/93540dcb9842392eaea986e57d20e299)

次に[こちら](https://circleci.com/ja/signup/)からCircleCIにサインアップして、GitHubと提携させます。

提携が終わったらサイドメニューの'ADD PROJECT'から作成したリポジトリを選択して設定しましょう

使用している言語を選択してStart Building!!

[![Image from Gyazo](https://i.gyazo.com/20ef2e23a58c74e6b5740eda8b2d3cf2.png)](https://gyazo.com/20ef2e23a58c74e6b5740eda8b2d3cf2)
config.ymlファイルもう作った？？みたいなこと聞かれますが無視してビルドしてみます
[![Image from Gyazo](https://i.gyazo.com/7dfc84fd3da32b00e850295b35029e84.png)](https://gyazo.com/7dfc84fd3da32b00e850295b35029e84)
当たり前ですが失敗しました…
エラーを見に行ってみましょう。
[![Image from Gyazo](https://i.gyazo.com/5f6707deb790e78d83bab69317cf0794.png)](https://gyazo.com/5f6707deb790e78d83bab69317cf0794)
案の定設定ファイルがないと怒られました…
言われた通りCircleCIの設定ファイルを作っていきましょう。

アプリケーションのルートディレクトリに.circleic/config.ymlを作成して設定ファイルを記述します。
内容は[こちら](https://qiita.com/rentama/items/477d3dcae423373f7c0d)の記事を参考にさせていただきました

```ruby:.circleci/config.yml
# Ruby CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
#
version: 2
jobs:
  build:
    docker:
      # specify the version you desire here
      - image: circleci/ruby:2.5.1-node-browsers
        environment:
          RAILS_ENV: test
          MYSQL_HOST: 127.0.0.1
          MYSQL_USERNAME: 'root'
          MYSQL_PASSWORD: ''
          MYSQL_PORT: 3306
      - image: circleci/mysql:5.7.18
        environment:
          MYSQL_ALLOW_EMPTY_PASSWORD: true
          MYSQL_ROOT_PASSWORD: ''
          MYSQL_DATABASE: circle_ci_test-test

      # Specify service dependencies here if necessary
      # CircleCI maintains a library of pre-built images
      # documented at https://circleci.com/docs/2.0/circleci-images/
      # - image: circleci/postgres:9.4

    working_directory: ~/circle-ci-test

    steps:
      - checkout

      # Download and cache dependencies
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

      - run:
          name: install dependencies
          command: |
            bundle install --jobs=4 --retry=3 --path vendor/bundle

      - save_cache:
          paths:
            - ./vendor/bundle
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}

      # Database setup
      - run:
          name: waiting for stating database
          command: dockerize -wait tcp://127.0.0.1:3306 -timeout 1m
      - run: bundle exec rake db:create
      - run: bundle exec rake db:schema:load

      # run tests!
      - run:
          name: Run rspec in parallel
          command: |
            bundle exec rspec --profile 10 \
                              --format RspecJunitFormatter \
                              --out test_results/rspec.xml \
                              --format progress \
                              $(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)

      # collect reports
      - store_test_results:
          path: /tmp/test-results
      - store_artifacts:
          path: /tmp/test-results
          destination: test-results
```

ファイルを追加したらcommit&pushしてあげましょう！
またマスターにプッシュされるとまたCircleCIが走ってくれます。

しかしまたエラー…
[![Image from Gyazo](https://i.gyazo.com/f23ec45078862918d499418e9c35b24b.png)](https://gyazo.com/f23ec45078862918d499418e9c35b24b)
bundlerのバージョンが2以上じゃないとダメみたいですね
bundler2.1.0をインストールしてバージョン指定して実行するようにしました

```ruby:.circleci/config.yml
jobs:
  build:
    docker:
      # specify the version you desire here
      - image: circleci/ruby:2.5.1-node-browsers
        environment:
          RAILS_ENV: test
          MYSQL_HOST: 127.0.0.1
          MYSQL_USERNAME: 'root'
          MYSQL_PASSWORD: ''
          MYSQL_PORT: 3306
          #　追記
          BUNDLER_VERSION: 2.1.0

# 省略
　　　
# 以下を変更
      - run:
          name: install dependencies
          command: |
            gem install bundler:2.1.0
            bundle _2.1.0_ install --jobs=4 --retry=3 --path vendor/bundle
```

コミット、プッシュしてみると今度はMySQLのエラー…
[![Image from Gyazo](https://i.gyazo.com/9e510934aa18a4e6d2a6652e56949506.png)](https://gyazo.com/9e510934aa18a4e6d2a6652e56949506)
mysql.sockがない？
[こちら](https://qiita.com/t-izaki/items/c6ef3239176f9c6697f2)の記事を参考にdatabase.ymlにhostを設定してあげました！

```ruby:config/database.yml
~~

default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  socket: /tmp/mysql.sock
# 追記
  host: <%= ENV['MYSQL_HOST'] %>

~~
```
Database setupは通った！！
しかし、rspecでエラー
[![Image from Gyazo](https://i.gyazo.com/53607bb764a868fcd3d7de91e6b3e3bd.png)](https://gyazo.com/53607bb764a868fcd3d7de91e6b3e3bd)

'rspec_junit_formatter'がないようです。
circleicでrspecを使うにはgemが必要になるみたいです。
言われた通り以下のgemを追加しましょう！

```ruby:Gumfile
gem 'rspec_junit_formatter'
```

bundle installしてもう一度コミットプッシュ！

[![Image from Gyazo](https://i.gyazo.com/f3fae9f9d007719d811a4971c11ece69.png)](https://gyazo.com/f3fae9f9d007719d811a4971c11ece69)
完走！！！
そして…
[![Image from Gyazo](https://i.gyazo.com/e31b7c9a0d1bfa4de968099384842a60.png)](https://gyazo.com/e31b7c9a0d1bfa4de968099384842a60)
テストも通ってる！！！！
しかし…
[![Image from Gyazo](https://i.gyazo.com/7e8b209be1806c237721eadfbe064bb2.png)](https://gyazo.com/7e8b209be1806c237721eadfbe064bb2)
MySQLのコンテナがビルドされていない？

# おわりに
ゼロ知識でCircleCiを使ってみましたがなかなか苦戦しました。
コンテナ技術ありきなのでDockerはじめコンテナとインフラ知識があればスムーズにconfigも書けそうですね。
課題を残して終わってしまったので解決したら追記していこうと思います。
最後まで読んでいただきありがとうございました！！

# 参考にさせていただいた記事
はじめてのCircleCI。Railsプロジェクトで試してみる。
https://qiita.com/rentama/items/477d3dcae423373f7c0d

CircleCIでRails+MySQLプロジェクトの自動テストを行うための最低限の設定
https://qiita.com/t-izaki/items/c6ef3239176f9c6697f2