Dockerで動くRailsアプリの展開とテストを試してみた

#目次
[1.はじめに](#はじめに)
[2.dockerで動くrailsアプリの展開](#dockerで動くrailsアプリの展開)
[3.docker上でのrspecテスト](#docker上でのrspecテスト)
[4.まとめ](#まとめ)

#はじめに
前回の記事[「開発環境のRailsアプリをDockerコンテナで起動してみた」](https://qiita.com/Unimaru/items/55115408f7d161fd32a7)では、既存のRailsアプリをDockerコンテナで動かしてみました。せっかく、Docker上で動くことが確認できましたので、今回はアプリを他の端末に配布して起動してみたり、Rspecのテストが問題なくできるかを試してみました。

#dockerで動くrailsアプリの展開
今回実施したアプリの展開フローは以下の通りです。
※端末AはMacBook Pro、端末BはMacBook Airであり、共にDocker Desctop for Macをインストール済
![スクリーンショット 2021-09-20 11.10.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067765/67003a2e-d7b7-ccd4-1fac-004b266ca1cb.png)

①前回記事で用意したRailsアプリを端末AからGitHubにpush
※Railsアプリのフォルダ階層に前回記事で作成した「DockerFile」、「docker-compose.yml」が含まれていること

![スクリーンショット 2021-09-20 11.17.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067765/0602e197-2200-fda0-1bf4-213b56ebaf47.png)

②別の端末BでGitHubから該当のアプリをクローン

```bash
xxxx@xxxxnoMacBook-Air projects % git clone https://github.com/unimarist/memory_tank.git
・・・
xxxx@xxxxnoMacBook-Air projects %
```

③端末BにてクローンしたアプリをDockerで起動

```bash
xxxx@xxxxnoMacBook-Air projects % cd memory_tank #クローンしたアプリのフォルダ階層まで移動
・・・
xxxx@xxxxnoMacBook-Air memory_tank % docker-compose up -d
Starting memory_tank_db_1 ... done
Starting memory_tank_app_1 ... done
xxxx@xxxxnoMacBook-Air memory_tank % docker-compose exec app bin/rails db:migrate #マイグレーション
・・・
xxxx@xxxxnoMacBook-Air memory_tank % docker-compose exec app bin/rails webpacker:install #webpackerのインストール
```

④端末Bにてブラウザから「localhost:3000」でアプリに接続できることを確認!
![スクリーンショット 2021-09-20 11.36.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067765/d0e080fd-8c33-f85a-7136-4af13a8854ca.png)

#docker上でのrspecテスト

端末BにてRspecによる単体テストおよび結合テストができることを確認します。
※今回、テストはアプリコンテナ内に接続して実施します。

■ 単体テストの実施

```
xxxx@xxxxnoMacBook-Air memory_tank % docker container ps -a #コンテナ一覧の表示
CONTAINER ID   IMAGE             COMMAND                  CREATED        STATUS                    PORTS                                       NAMES
(アプリコンテナID)   memory_tank_app   "bash -c 'rm -f tmp/…"   12 hours ago   Up 13 minutes             0.0.0.0:3000->3000/tcp, :::3000->3000/tcp   memory_tank_app_1
(DBコンテナID)   mysql:5.6         "docker-entrypoint.s…"   12 hours ago   Up 13 minutes             0.0.0.0:4306->3306/tcp, :::4306->3306/tcp   memory_tank_db_1
xxxx@xxxxnoMacBook-Air memory_tank %
xxxx@xxxxnoMacBook-Air memory_tank % docker exec -it (アプリコンテナID) /bin/bash #アプリコンテナに接続
root@(アプリコンテナID):/memory_tank# RAILS_ENV=development bundle exec rspec spec/models/user_spec.rb　#単体テストの実施
User
  アカウント登録
    【正常系】アカウント登録_成功
      username、password、password_confirmationが存在する場合
      usernameが15文字以下の場合
      passwordとpassword_confirmationが6文字以上の場合
    【異常系】アカウント登録_失敗
      usernameが空の場合
      passwordが空の場合
      passwordが存在し、password_confirmationが空の場合
      重複したusernameが存在する場合
      usernameが16文字以上の場合
      passwordが5文字以下の場合

Finished in 4.55 seconds (files took 8.51 seconds to load)
9 examples, 0 failures

root@(アプリコンテナID):/memory_tank# 
```
■ 結合テストの実施

※前提として、ブラウザを自動で操作してテストが実施できるよう、「selenium-webdriver」を利用します。
①Gemファイルにrspec-rails、capybara、selenium-webdriverが入っていること

```
group :development, :test do
  gem "rspec-rails"
  gem 'capybara'
  gem 'selenium-webdriver'
end
```
②以下、Rspec設定(Capybaraにドライバを登録)がされていること。

```spec/support/selenium_chrome.rb
require 'capybara/rspec'
require 'selenium-webdriver'

Capybara.register_driver :selenium_chrome do |app|
  options = ::Selenium::WebDriver::Chrome::Options.new

  options.add_argument('--headless')
  options.add_argument('--no-sandbox')
  options.add_argument('--disable-dev-shm-usage')
  options.add_argument('--window-size=1400,1400')

  driver = Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end

Capybara.javascript_driver = :selenium_chrome
```
```spec/rails_helper.rb
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }

RSpec.configure do |config|

  config.before(:each, type: :system) do
    driven_by :rack_test
  end

  config.before(:each, type: :system, js: true) do
    driven_by :selenium_chrome
  end
end
```

結合テストの実施

```
root@(アプリコンテナID):/memory_tank# RAILS_ENV=development bundle exec rspec spec/system/tanks_spec.rb #結合テストの実施
WordTank作成
  【正常系】WordTank作成_成功
    ログインしたユーザーでWordTankを作成する場合(Tankアイコンをアップロード)
    ログインしたユーザーでWordTankを作成する場合(Tankアイコンをアップロードしない)
  【異常系】WordTank作成_失敗
    ユーザがログインしていない場合

QuestionTank作成
  【正常系】QuestionTank作成_成功
    ログインしたユーザーでQuestionTankを作成する場合(Tankアイコンをアップロード)
    ログインしたユーザーでQuestionTankを作成する場合(Tankアイコンをアップロードしない)
  【異常系】QuestionTank作成_失敗
    ユーザがログインしていない場合

　　・
　　・
　　・
QuestionTank削除
  【正常系】QuestionTank削除_成功
    ログインしたユーザーでQuestionTankを削除する場合
  【異常系】QuestionTank削除_失敗
    ユーザがログインしていない場合

Finished in 28.59 seconds (files took 7.6 seconds to load)
14 examples, 0 failures

root@(アプリコンテナID):/memory_tank# 
```

#まとめ
今回、Docker起動を前提とすることで、アプリを別の端末にクローンしても、問題なくスムーズに起動できることを体験できました。また、アプリコンテナ内でのRspecテスト(単体・結合テスト)を実施できることも確認ができました。今後はさらにDockerのメリットを活かせるような利用方法について学んでいきたいと思います。

以上、最後まで読んで頂きありがとうございました！