Railsのテストツールはminitestがバンドルされています。rails test
コマンドがテストランナーのコマンドです。以下の指定方法をよく使いますが、さらに細かいオプションで単体ケースの実行なども可能です。
rails test
- test/ディレクトリ以下のテストを一式実行
rails test test/some-directory
- 特定ディレクトリ内のテストを一式実行。末尾にスラッシュがつくと適切に動作しない
rails test test/some-directory/some-test.rb
- 特定ファイルのテストを実行
ミドルウェア設定
テストはRAILS_ENV=test
で実行されます。RDBMSやRedisなどの接続設定は、config/database.yml
のtest用設定や、config/environments/test.rb
などで設定でき、depelopmentと異なる構成をとれます。
サーバーインスタンス構成はdevelopmentの実行環境を流用し、データベースのみ切り分ける設定でも問題はないでしょう。実行環境は自動選択され、たとえばrails console
実行時はdevelopment環境で動作し、rails test
はtest環境で動作する挙動になります。
DB側の事前セットアップはCREATE DATABASE
とGRANT
までは完了しておく必要があります。また、あらかじめデーモン起動しておき、接続可能な状態が必要です。
また、アプリケーションでストアドプロシージャなどのDB機能を使用している場合、あらかじめRAILS_ENV=test
用のDBにセットアップしておくことで、テストコードからも問題なく利用できます。
ridgepoleでセットアップする場合は、以下のように-E
オプションでDBを指定できます。
$ ridgepole -c config/database.yml -f config/Schemafile -a -E test
Rails minitestのDB準備
テスト実行時の準備動作として db/schema.rb が実行され、テーブルをセットアップします。
DBスキーマの管理ツールに、ridgepoleなど非標準の手段を利用している場合、schema.rbを最新の状態にしておく必要があります。
rails db:schema:dump
を実行するとschema.rbが更新されます。
リリース前にテストを実行する実情を考慮すると、このコマンドの実行環境はdevelopmentが妥当でしょう。
なお、テストコードからDBMSへの書き込み操作については、テストの最後にROLLBACK
が走ります。基本的なテスト実行のためのクリーンアップ処理を追加する必要はありません。
fixture
テストにデータが必要かどうかは個別のテストケースに依存します。テストは冪等に実行すべきものであるため、データも個別のテストケース実装に近いレイヤのコードとして供給した方が良いでしょう。
Railsの場合、テーブル作成後のデータロードはfixtureを通じて行われます。
ロードされたfixtureオブジェクトはかなり高機能です。以下のようなUserモデルのfixtureの場合、User.find(1)
とusers(:john)
は同様のActiveRecordオブジェクトを返し、リレーションも機能します。
john:
id: 1
name: John
email: [email protected]
デフォルトでは test/test_helper.rbのfixtures :all
が設定されており、すべてのfixtureファイルをロードする挙動になります。テーブル名に対応するシンボルをカンマ区切りで列挙することで、特定のフィクスチャのみロードさせることも可能です。
fixturesはrails generate
した際に空の定義が生成されることがあり、NULLカラムに満ちたデータを作成する挙動になります。 DBテーブル定義でNOT NULL制約を指定しているカラムがあると、空のfixturesロード時にエラーになります。
そのため、中途半端に空のfixtureを置いた状態ではテストを実行できないケースが多々起こります。初期段階でデータを利用しないテストを実行したい場合はtest_helper.rbのfixtures設定をコメントアウトすれば、データロードを回避できます。
カバレッジ計測
カバレッジ計測には simplecovを使います。 Gemfileのtest環境向けブロックでsimplecovをインストールしておきます。
gem 'simplecov', require: false
test/testhelper.rbの冒頭でrequireします。アプリケーションのロード前にrequireしないとカバレッジを適切に計測できません。
require 'simplecov'
計測の設定はプロジェクトルートに.simplecov
というファイルを以下の内容で作成しています。
SimpleCov.start do
# exclude uneeded dirs
add_filter ['test/', 'config/']
add_group "Models", "app/models"
add_group "Controllers", "app/controllers"
add_group "Helpers", "app/helpers"
end
設定が完了したら、あとはrails test
などのテストランナーを一般的な手順で実行するだけです。レポートはcoverageディレクトリに生成されます。レポートは人が読むためのファイルであるため、.gitignore
でcoverageディレクトリを除外するのが適切でしょう。
なお、テストコードを1つも書いていないクラスはカバレッジの母数にも含まれないため、まずは広く薄くテストケースを書いておいた方が把握しやすくなります。
まとめ
まず、rails test
コマンドを実行してみて、DBMS関連のエラーで停止する場合にはテスト環境の事前準備が完了していない可能性が高いと言えます。
DB接続、スキーマ、fixtureを確認することで、テスト時セットアップ動作のトラブルに対処できます。
Chuma Takahiro