Model
Active Model
AttributeMethodsモジュール
Callbacksモジュール
登録
実行
スキップ
停止
リレーションシップのCallBack
条件付きCallBack
CallBackClass
トランザクションCallBack
before_validation
after_validation
before_save
around_save
before_create
around_create
after_create
after_save
before_validation
after_validation
before_save
around_save
before_update
around_update
after_update
after_save
before_destroy
around_destroy
after_destroy
after_initialize
after_find
after_touch
Conversionモジュール
Dirtyモジュール
Validationsモジュール
Ruby on Rails-View
View
Ruby on Rails-Controller
Controller
Ruby on Rails-Debugging
Debugging
Ruby on Rails-API
Rails API Server
Testing
基本
全てのRailsアプリケーションには3つの環境がある
それぞれの環境におけるデータベース設定はconfig/database.yml
で行う
- development
- test
- production
Fixture
- YAMLで記述
- 特定のDBに依存しない
- 1つのモデルにつき1つのFixture
- ERBが使用できる
- 全てのFixtureを自動的に読み込み、テストで使用
# Sample Fixture
david:
name: David Heinemeier Hansson
birthday: 1979-10-15
profession: Systems development
steve:
name: Steve Ross Kellock
birthday: 1974-09-27
profession: guy with keyboard
# belongs_to/has_many関連付けの場合
# fixtures/categories.ymlの内容:
about:
name: About
# fixtures/articles.ymlの内容
one:
title: Welcome to Rails!
body: Hello world!
category: about
# ERBを使用した場合
<% 1000.times do |n| %>
user_<%= n %>:
username: <%= "user#{n}" %>
email: <%= "user#{n}@example.com" %>
<% end %>
Modelのユニットテスト
- ある値が別の値と等しいかどうか
- このオブジェクトはnilかどうか
- コードのこの行で例外が発生するかどうか
- ユーザーのパスワードが5文字より多いかどうか
-
test_helper.rb
に追加したメソッドはすべてのテストで利用できる - テストを実行するには、テストDBが最新の状態で構成されている必要がある
- 全てのmigrationが完了している場合、
db/schema.rb
やdb/structure.sql
をテストDBに読み込む - テストにパス: . (ドット)
- テストに失敗: F
- エラー発生: E
- TDD
- assertion
- Rails固有のassertionもある
# ActiveSupport::TestCaseのすべてのメソッドを利用できる
# ActiveSupport::TestCaseのスーパークラスはMinitest::Test
class ArticleTest < ActiveSupport::TestCase
end
Controllerの機能テスト
- Webリクエストが成功したか
- 正しいページにリダイレクトされたか
- ユーザー認証が成功したか
- レスポンスのテンプレートに正しいオブジェクトが保存されたか
- ビューに表示されたメッセージは適切か
getメソッドに渡せるもの
- コントローラ内のアクション(アクション名は文字列またはシンボル)
- アクションに渡すリクエストパラメータに含まれるオプションハッシュ1つ(クエリ文字列パラメータや記事の変数など)
- リクエストで渡されるセッション変数のオプションハッシュ1つ
- flashメッセージの値のオプションハッシュ1つ
getやpostを使用すると、利用できるハッシュ
- assigns - ビューで使用するためにアクションのインスタンス変数として保存されるすべてのオブジェクト。
- cookies - 設定されているすべてのcookies。
- flash - flash内のすべてのオブジェクト。
- session - セッション変数に含まれるすべてのオブジェクト。
利用可能なインスタンス変数
- @controller - リクエストを処理するコントローラ
- @request - リクエスト
- @response - レスポンス
HTTPとヘッダーとCGI変数を設定する
# HTTPヘッダーを設定する
@request.headers["Accept"] = "text/plain, text/html"
get :index
# CGI変数を設定する
@request.headers["HTTP_REFERER"] = "http://example.com/home"
post :create
テンプレートとレイアウトが正しいかどうか
-
assert_template
一回の呼び出しで同時にテンプレートとレイアウトをテストできない - パーシャル (部分レイアウト) が使用されている場合は、パーシャルにもアサーションを行なう必要がある
test "index should render correct template and layout" do
get :index
assert_template :index
assert_template layout: "layouts/application"
assert_template layout: "layouts/application", partial: "_form"
end
Viewのテスト
- assert_select(セレクタ, [条件], [メッセージ])
- assert_select(要素, セレクタ, [条件], [メッセージ])
- ブロックを使用可能
- assert_select
assert_select "ol" do |elements|
elements.each do |element|
assert_select element, "li", 4
end
end
assert_select "ol" do
assert_select "li", 8
end
Integration test
- 複数のコントローラ同士のやりとりをテスト
- ActionDispatch::IntegrationTestから継承
SetupとTeardown
ActiveSupport::Callbacksに実装されている
# 各テストが実行される直前に呼び出される
def setup
@article = articles(:one)
end
# 各テストの実行直後に呼び出される
def teardown
# @article変数は実際にはテストの実行のたびに直前で初期化されるので
# ここで値をnilにする意味は実際にはないのですが、
# teardownメソッドの動作を理解いただくためにこのようにしています
@article = nil
end
Routing
test "should route to article" do
assert_routing '/articles/1', {controller: "articles", action: "show", id: "1"}
end
Mailer
- メールが処理 (作成および送信) されていること
- メールの内容 (subject、sender、bodyなど) が正しいこと
- 適切なメールが適切なタイミングで送信されていること
- 結果の出力と、Fixtureを比較
Unit test
# inviteというアクションで知人に招待状を送信するUserMailerという名前のメイラー
require 'test_helper'
class UserMailerTest < ActionMailer::TestCase
test "invite" do
# メールを送信後キューに追加されるかどうかをテスト
email = UserMailer.create_invite('me@example.com',
'friend@example.com', Time.now).deliver_now
assert_not ActionMailer::Base.deliveries.empty?
# 送信されたメールの本文が期待どおりの内容であるかどうかをテスト
assert_equal ['me@example.com'], email.from
assert_equal ['friend@example.com'], email.to
assert_equal 'You have been invited by me@example.com', email.subject
assert_equal read_fixture('invite').join, email.body.to_s
end
end
Functional test
メール配信メソッドを呼び出し、その結果適切なメールが配信リストに追加されるかどうかをチェック
期待されたタイミングでメールが送信されるかどうか
require 'test_helper'
class UserControllerTest < ActionController::TestCase
test "invite friend" do
assert_difference 'ActionMailer::Base.deliveries.size', +1 do
post :invite_friend, email: 'friend@example.com'
end
invite_email = ActionMailer::Base.deliveries.last
assert_equal "You have been invited by me@example.com", invite_email.subject
assert_equal 'friend@example.com', invite_email.to[0]
assert_match(/Hi friend@example.com/, invite_email.body.to_s)
end
end
Helper
ヘルパーメソッドの出力が期待どおりであるかどうかをチェック
class UserHelperTest < ActionView::TestCase
include UserHelper
test "should return the user name" do
# ...
end
end
Ruby on Rails-Deploy
Capistrano