Udemy 8. ユーザーモデル開発 #06
2020年07月14日に公開

Rails6から導入された並列テストを理解する

今回達成すること

  • テスト結果を見やすくするGemの導入と
  • テストデータにSeedデータを投入する設定を行い

テスト環境を整えます。

またこの記事では、Rails6から導入された並列テストについての解説も行います。

GO 並列テストとは?

テスト結果を色付けして見やすくするGemの導入

現状のRailsテストは、結果が白黒で非常に見にくい状態です。

そこでテスト結果を色付けしてくれるGemを導入します。

minitest-reportersのインストール

Gemfiletestグループを作成し、その中でminitest-reporters(ミニテストレポーターズ)をインストールします。

これにより、テスト環境で使用するGemとしてRailsに認識されます。

api/Gemfile
...

# 追加
group :test do
  # テスト結果色付け Doc: https://github.com/kern/minitest-reporters
  gem 'minitest-reporters', '~> 1.1', '>= 1.1.11'
end
# ここまで

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

Gemfileを書き換えたのでDockerイメージをビルドしましょう。

root $ docker-compose build api

Gemのインストールを確認しておきましょう。

root $ docker-compose run --rm api bundle info minitest-reporters

* minitest-reporters (1.4.2)
...

minitest-reportersのセットアップ

インストール後はtest_helper.rbにGemを読み込む設定を行います。

api/test/test_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
require 'rails/test_help'

# 追加
# gem 'minitest-reporters' setup
require "minitest/reporters"
Minitest::Reporters.use!
# ここまで

class ActiveSupport::TestCase
...

以上でminitest-reportersが使えるようになりました。

テストが色付けできているか確認

ここまでの設定を確認して見ましょう。テストコマンドを実行します。

root $ docker-compose run --rm api rails t

うまく色付けされましたね。

2020-07-14 12-40-44

テストデータをSeedデータに切り替える

テストデータとは、Railsのテスト内で使われるデータのことです。

Railsのデフォルトでは「fixture(フィクスチャ)」を使ってテストデータを生成します。

fixtureとは

fixtureとは、Railsが用意しているテストデータを生成するための方法です。

この方法を使う場合、テストデータはymlファイルで生成します。

users.ymlファイルサンプル
<% 1000.times do |n| %>
user_<%= n %>:
  username: <%= "user#{n}" %>
  email: <%= "user#{n}@example.com" %>
<% end %>

ymlファイルでRailsコードを書くには

ymlファイル内でRailsを実行するにはERB形式(Html内にRubyコードを書く方式)で書く必要があります。

あの<% %>でコードを囲む方式です。

ただこの方法は書きにくいといったデメリットがあります。

今回のテストデータの生成方法

そこで今回は「fixture」を使わず、開発環境と同じSeedデータをテストデータとして使用します。

設定は簡単でtest_helper.rbに「seeds.rb」を読み込む設定を行えば良いだけです。

同時に「fixture」の読み込みは削除します。

api/test/test_helper.rb
...
class ActiveSupport::TestCase
  # 追加
  # プロセスが分岐した直後に呼び出し
  parallelize_setup do |worker|
    load "#{Rails.root}/db/seeds.rb"
  end
  # ここまで

  parallelize(workers: :number_of_processors)

  # 削除
  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  # fixtures :all
end
  • parallelize_setup(パラレルライズセットアップ)

    並列テストで使用するメソッドです。

    プロセス開始直後に実行したいアクションをブロック内に記述します。

並列テストとは?

Raisl6で新たに追加された機能で、複数のプロセスを分岐させテストの実行時間を短縮する機能のことです。

スレッド化のサポートもされていますが今回は触れません。

並列テストの有効化

並列テストはデフォルトで有効になっています。

有効無効の切り替えは下記コードで行います。

parallelize(workers: :number_of_processors)

workers: プロセス数

workers:に渡す値がプロセスが分岐する数となります。

2以上の場合はプロセスが複数分岐するので並列テストが有効になります。

デフォルトの:number_of_processorsは使用しているマシン(Docker)のコア数が入ります。

Dockerのコア数確認

使用しているイメージのコア数を確認するにはコンテナに入って$ nprocコマンドを実行します。

# apiコンテナに入る
root $ docker-compose run --rm api sh

# コア数確認
/app # nproc
2

# コンテナから抜ける
/app # exit

参考 docker — DockerコンテナはいくつのCPUを使用しますか?

並列テストの無効化

並列テストを無効化する場合はworkersに1以下の値を渡します。

プロセスが1つになるため並列テストが無効になります。

parallelize(workers: 1)

データベースの自動作成

workersの値が2の状態で並列テストを実行すると、自動的にapp_test-0app_test-1という名のデータベースが作成されます。

# PostgreSQLに入る
root $ docker-compose exec -u postgres db psql

# データベース一覧を取得する
postgres=# \l

      Name       |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges   
-----------------+----------+----------+------------+------------+---------------------
 app_development | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 app_test        | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 app_test-0      | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 app_test-1      | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 ...
 
# PostgreSQLから抜ける
postgres=# \q

並列テストが有効な状態でテストを実行すると、このapp_test-0app_test-1のデータベースが使用されます。

データベースへのデータ投入時期

app_test-0app_test-1はプロセスが分岐した後に参照されます。

そのため、プロセスが分岐した直後にテスト環境へSeedデータを投入しないと、テストデータベースに何も入っていないといった現象に陥ります。

よって今回はparallelize_setup内でSeedデータの投入を行なっています。

parallelize_setup do |worker|
  load "#{Rails.root}/db/seeds.rb"
end

(筆者はユーザーデータが取れず3時間はまりました。。。😵 )

参考 Rails テスティングガイド - Railsガイド

ここまでの変更を確認してみよう

テストは何も書いていませんが実行してみましょう。

root $ docker-compose run --rm api rails t

...
users...
users...
users = 10
users = 10

ユーザーSeedデータがテスト環境に投入されていますね。

2つのプロセスに分岐しているため2回の表示があるはずです。

コミットしとく

これでテスト環境が整いました。

コミットしておきましょう。

root $ cd api
api  $ git commit -am "test_environment_setup"
api  $ cd ..
root $

まとめ

今回は

  • テスト結果を色付けするminitest-reportersの導入と
  • テストデータにSeedデータを投入し、

テスト環境を整えました。

また、Rails6から導入された並列テストについても学んでいきました。

このカテゴリーではユーザーモデルしか生成しないので、あまりテストの速さを体感できないかもしれませんが…。まあ速くなるに越したことはないですね。

さーて次回は?

ユーザーモデルのバリデーションテストを行います。

いよいよモデル開発も佳境へ!

GO!! ↓次の記事へ。

あなたの力になれること
私自身が独学でプログラミングを勉強してきたので、一人で学び続ける苦しみは痛いほど分かります。そこで、当時の私がこんなのあったら良いのにな、と思っていたサービスを立ち上げました。周りに質問できる人がいない、答えの調べ方が分からない、ここを聞きたいだけなのにスクールは高額すぎる...。そんな方に向けた単発・短期間メンターサービスを行っています。下のサービスへお進みください。
独学プログラマのサービス
次の記事はこちら
1. このカテゴリーの歩き方 #01
【お知らせ】UdemyでRails × Nuxt.jsの動画を公開することになりました
1. このカテゴリーの歩き方 #02
【随時更新】このカテゴリーで作るアプリケーションの仕様書
1. このカテゴリーの歩き方 #03
【随時更新】このカテゴリーの歩き方
1. このカテゴリーの歩き方 #04
(Docker+Rails6+Nuxt.js+PostgreSQL)=>Heroku 環境構築~デプロイまでの手順書
2. Docker入門 #01
Docker for Macをインストールする手順
2. Docker入門 #02
分かるDocker解説。仮想環境・コンテナ・Dockerイメージ・Dockerfileとは何か?
2. Docker入門 #03
分かるDocker解説。DockerComposeとは何か?
3. Dockerを使ったRails+Nuxt.js環境構築 #01
【Docker+Rails6+Nuxt.js】今回作成するアプリの開発環境の全体像を知ろう
3. Dockerを使ったRails+Nuxt.js環境構築 #02
【MacOS】Homebrew経由でGitをインストールする方法
3. Dockerを使ったRails+Nuxt.js環境構築 #03
Rails6を動かすAlpineベースのDockerfileを作成する(AlpineLinuxとは何か)
3. Dockerを使ったRails+Nuxt.js環境構築 #04
Nuxt.jsを動かすAlpineベースのDockerfileを作成する(C.UTF-8とは何か)
3. Dockerを使ったRails+Nuxt.js環境構築 #05
.envファイルを使ったdocker-compose.ymlの環境変数設計
3. Dockerを使ったRails+Nuxt.js環境構築 #06
Rails6・Nuxt.js・PostgreSQLを動かすdocker-compose.ymlファイルを作成する
3. Dockerを使ったRails+Nuxt.js環境構築 #07
docker-compose.ymlを使ってRails6を構築する(PostgreSQLパスワード変更方法)
3. Dockerを使ったRails+Nuxt.js環境構築 #08
docker-compose.ymlを使ってNuxt.jsを構築する
4. 複数プロジェクトのGit管理 #01
複数プロジェクトで行うGit管理の全体像を理解しよう(Gitサブモジュール解説)
4. 複数プロジェクトのGit管理 #02
【Git】既存の子ディレクトリをサブモジュール管理に変更する手順
4. 複数プロジェクトのGit管理 #03
【GitHub】秘密鍵の生成・公開鍵を追加・SSH接続するまでを画像で分かりやすく
4. 複数プロジェクトのGit管理 #04
【GitHub】リモートリポジトリの追加・サブモジュールのリンク設定を行う
5. RailsAPI×Nuxt.js初めてのAPI通信 #01
【Rails6】"Hello" jsonを返すコントローラを作成する
5. RailsAPI×Nuxt.js初めてのAPI通信 #02
【Nxut.js】axiosの初期設定を行う(baseURL・browserBaseURLを解説)
5. RailsAPI×Nuxt.js初めてのAPI通信 #03
【Rails6】Gem rack-corsを導入してCORS設定を行う(オリジン・CORSとは何か)
6. Heroku.ymlを使ったDockerデプロイ #01
デプロイ準備。Herokuへ新規会員登録を行いHerokuCLIをインストールする
6. Heroku.ymlを使ったDockerデプロイ #02
heroku.yml解説編。Docker環境のRails6をHerokuにデプロイする(1/2)
6. Heroku.ymlを使ったDockerデプロイ #03
HerokuCLI-manifestのデプロイ解説編。Docker環境のRails6をHerokuにデプロイする(2/2)
6. Heroku.ymlを使ったDockerデプロイ #04
Dockerfile解説編。Docker環境のNuxt.jsをHerokuにデプロイする(1/2)
6. Heroku.ymlを使ったDockerデプロイ #05
デプロイ完結編。Docker環境のNuxt.jsをHerokuにデプロイする(2/2)
7. モデル開発事前準備 #01
【Rails6】application.rbの初期設定(タイムゾーン・I18n・Zeitwerk)
7. モデル開発事前準備 #02
【Rails6】モデル開発に必要なGemのインストールとHirb.enableの自動化
7. モデル開発事前準備 #03
【Docker+Rails】A server is already running. Check /tmp/pids/server.pidエラーの対応
7. モデル開発事前準備 #04
【Docker】<none>タグのイメージを一括削除する & Rails .gitignoreの編集
8. ユーザーモデル開発 #01
Railsユーザーモデル作成。テーブル設計・ユーザー認証設計を理解する
8. ユーザーモデル開発 #02
Railsユーザーモデルのバリデーション設定(has_secure_password解説)
8. ユーザーモデル開発 #03
Railsバリデーションエラーメッセージの日本語化(ja.yml設定方法)
8. ユーザーモデル開発 #04
EachValidatorクラスのカスタムバリデーション設定(Rails6/lib以下読込)
8. ユーザーモデル開発 #05
Rails環境ごとにSeedデータ切り替えるseeds.rbの書き方
8. ユーザーモデル開発 #06
Rails6から導入された並列テストを理解する
8. ユーザーモデル開発 #07
Railsユーザーモデルバリデーションテスティング(name/email/password)
8. ユーザーモデル開発 #08
Nuxt.jsからRailsのユーザーテーブルを取得しHerokuにデプロイする
9. Nuxt.jsフロント開発事前準備 #01
【Nuxt.js2.13超解説】バージョンアップ手順と6つの新機能+2つの変更点
9. Nuxt.jsフロント開発事前準備 #02
Docker AlpineベースのNode.js上で動くNuxt.jsにVuetifyを導入する
9. Nuxt.jsフロント開発事前準備 #03
VuetifyにカスタムCSSを導入してオリジナルブレイクポイントを作る
9. Nuxt.jsフロント開発事前準備 #04
Nuxt.jsにnuxt-i18nを導入して国際化に対応する
10. 認証アプリのレイアウト設計 #01
Nuxt.jsのレイアウト・ページ・コンポーネントの役割を理解しよう
10. 認証アプリのレイアウト設計 #02
ウェルカムページを構成するコンポーネントファイル群を作成しよう(1/4)
新着
10. 認証アプリのレイアウト設計 #03
ウェルカムページにアイキャッチ画像・アプリ名・メニューボタンを表示しよう(2/4)
新着
10. 認証アプリのレイアウト設計 #04
addEventListenerでスクロールを検知しツールバーの色を変化させよう(3/4)
新着
10. 認証アプリのレイアウト設計 #05
ウェルカムページをレスポンシブデザインに対応させよう(4/4)
新着
SPA開発
ブログ構築
小ネタ集