説明
- あるURLにアクセスした際に、予期した画面が表示されるか
- ある正しい操作をした際に、アプリケーションの状態が正しく変更されるか
- ある正しくない操作をした際に、適切なエラーメッセージが表示されるか
上記の確認作業をブラウザで確認するのではなく、プログラムで確認出来るようにするのが目的 (変更箇所によって別の機能が動かなくなることや、確認漏れをなくす効果が期待できる)
テストには大きく分けて3種類ある
- 単体テスト
- 機能テスト
- 総合テスト
単体テスト
- モデルの検索系メソッドが正しい値を取得できるか
- モデルの更新系メソッドが正しくデータベースを更新できるか
- モデルの更新系メソッドが不正な入力に対して、適切なエラーを発生させるか
機能テスト
- 適切なテンプレートが選択されているか
- インスタンス変数に適切な値が格納されているか
- 適切にレンダリングされているか
- 更新系のアクションが正しくデータベースを更新されるか
総合テスト
- ログインして、新しいメンバーを追加して、ログアウトするといった一連の動きをテスト
railsでテストを行う時のテストフレームワークには様々な種類がある
- rspec
- minitest
- test-unit
- capybara
- cucumber
今回はminitest
を使ったテストの方法を解説する
(個人的好み & railsデフォルトのため選定)
rails new
& rails g scaffold item
& rake
でテストの実行が出来ます
$ rails new rails-minitest
$ cd rails-minitest
$ rails g scaffold item
$ rake db:migrate
$ rake
Run options: --seed 61987
# Running:
.......
Finished in 1.786684s, 3.9179 runs/s, 7.2760 assertions/s.
7 runs, 13 assertions, 0 failures, 0 errors, 0 skips
作成されたテストコード
$ tree test/
test/
├── controllers
│ └── items_controller_test.rb
├── fixtures
│ └── items.yml
├── helpers
├── integration
├── mailers
├── models
│ └── item_test.rb
└── test_helper.rb
6 directories, 4 files
controllers
下のファイルにテストコードが書かれている
fixtures
はテストデータ
models
にはテストは書かれていない、単体テストを行う時に記述する
items_controller_test.rb
のテストコード抜粋(本当はもうちょっと長いが最低限の部分のみ)
require 'test_helper'
class ItemsControllerTest < ActionController::TestCase
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:items)
end
test "should create item" do
assert_difference('Item.count') do
post :create, item: { }
end
assert_redirected_to item_path(assigns(:item))
end
indexアクションのテストコード
test "should get index" do
# indexアクションにgetアクセス
get :index
# レスポンスコード200が返るか確認
assert_response :success
# インスタンス変数 @items はnilではないのを確認
assert_not_nil assigns(:items)
end
createアクションのテストコード
test "should create item" do
# Item.countを実行してブロック終了時に +1 しているか確認
assert_difference('Item.count') do
# createアクションにpostアクセス、パラメータ付き
post :create, item: { }
end
# リダイレクトされてるか確認
assert_redirected_to item_path(assigns(:item))
end
ついでにmodels
下の単体テストの書き方
require 'test_helper'
class ItemTest < ActiveSupport::TestCase
# test "the truth" do
# assertでtrueかどうかの確認
# assert true
# end
end
こんな風に書く
test "saveできるか" do
item = Item.new(name: 'waiwai')
# saveしてtrueが返るか、save出来るか
assert item.save
end
- minitestのassert記法は簡単にテストを始められる
- 基本的にはtrueかどうかを確認するのがテスト
- trueかどうかを確認できる粒度にコードを細分化するのがテストしやすいいいコード
- 便利なassertの書き方は色々あるけど、trueかどうかを確認出来るようにするのが先、便利なのを探すのは後