メニュー

リファレンス

HTMLタグ逆引き

検索

テスト(test)

テストとは

説明

単体テスト

機能テスト

総合テスト

Railsのテストについて

Railsのテストの仕組み

  1. ユニットテスト
  2. ファンクションテスト
  3. インテグレーションテスト

ユニットテスト

モデル対処にテストを行う

ファンクションテスト

モデルからビュー、コントローラまで含む、アクションごとのテストを行う

インテグレーションテスト

アクション間をまたぐテストなどを行う

テストを実行

説明

Railsではテストの実行の仕組みは2つある

  1. rubyコマンドで直接実行
  2. rakeコマンドで実行

rubyコマンドで直接実行

$ ruby test/unit/entry_test.rb

rakeコマンドで実行

タスク 説明
rake db:test:prepare development環境のDBからスキーマをコピーするなど、テスト用のDBを準備する
rake test すべてのテストを実行
rake test:functionals ファンクショナルテストを実行
rake test:integration インテグレーションテストを実行
rake test:units ユニットテストを実行
rake test:recent ファイルのタイムスタンプをもとに、10分以内に更新されたファイルのテストを実行

テストデータ (fixtures)

説明

事前に用意したテストデータを読み込み、常にDBの内容を一定に保つための仕組みのことを、フィクスチャと呼ぶ

フィクスチャを用意

test/fixtures/テーブル名.yml
rubyonrails:
  id: 1
  name: Ruby on Rails
  url: http://www.rubyonrails.org
 
google:
  id: 2
  ;name: Google
  url: http://www.google.com

テスト内からフィクスチャを読み込む

require 'test_helper'

class WebSiteTest < ActiveSupport::TestCase
  test "web_site_count" do
    assert_equal 2, WebSite.count
  end
end

フィクスチャを使用

require 'test_helper'
 
class SiteTest < ActiveSupport::TestCase
  fixtures :sites
 
  def test_google_fixture
    # フィクスチャ名を指定して使用
    google = sites(:google)
    assert_equal "http://www.google.com", google.url
  end
 
  def test_google_fixture_from_db
    # findメソッドなどでDBからロードして使用
    google = Site.find(2)
 
    # フィクスチャ名で取得したものと同じであることを検証
    assert_equal sites(:google), google.url
  end
end

フィクスチャからのデータの取得

フィクスチャに含まれているデータはテストの実行時に使うものだがmこれを使ってデータをロード

$ mkdir db/migrate/dev_data
$ ruby script/generate migration <マイグレーション名>
require 'active_recode/fixtures'
class <クラス名> < ActiveRecode::Migration
  def self.up
    down
 
    directory = File.join(File.dirname(__FILE__), 'dwv_data')
    Fixtures.create_fixtures(disrectory, "<YAML名>")
  end
  def self.down
    <YAML名>.delete_all
  end
end

ユニットテストについて

使い方

#coding: utf-8
require 'test_helper'

class ArticleTest < ActiveSupport::TestCase
test テスト名 do
テストコード
end

class ShopTest < ActiveSupport::TestCase
  def test_instanciate_from_cvs_string
    shop = Ship.parse("コーヒー, aaa")
    assert_not_nil shop
    assert_equal "コーヒー", shop.name
    assert_equal "aaa", shop.tel
  end
end
class Shop < ActiveRecord::Base
  def self.parse(cvs_str)
  end
end
def self.parse(cvs_str)
  params = cvs_str.split(/\s*, \s*/)
  Shop.new(:name => params[0], :tel => params[1])
end

ユニットテストで使うメソッド

テストメソッド

メソッド説明
assert(式 [, メッセージ])式が真ならば成功
assert_equal(変数1, 変数2 [, メッセージ])変数1と変数2が等しければ成功
assert_not_equal(変数1, 変数2 [, メッセージ])変数1と変数2が等しくなければ成功
assert_nil(変数 [, メッセージ])変数がnilならば成功
assert_not_nil(変数 [, メッセージ])変数がnilじゃなければ成功
assert_match(正規表現, 文字列 [, メッセージ])正規表現に文字列がマッチすれば成功
assert_no_match(正規表現, 文字列 [, メッセージ])正規表現に文字列がマッチしなければ成功
assert_raise(例外1, 例外2 [, 例外3...]) { }ブロックを実行して例外1,2が発生し、その例外がexpected_exception_klassクラスならば成功
assert_nothing_raised(例外1, 例外2 [, 例外3...]) { .. }ブロックを実行して例外1,2がおきなけらば成功
assert_in_delta(expected_float, actual_float, delta, message="")
flunk([メッセージ])常に失敗
未定義のテストケースなどを暫定的に失敗させたりする場合に利用
assert_difference(expressions, difference = 1, message = nil, 6block)ブロック実行後にecpressionsの値がdifferenceの分だけ変わっていれば成功
assert_no_difference(exoressions, message = nil, &block) ブロック実行前後でexpressionsの値が変わっていなければ成功

ファンクショナルテスト

単一のアクションに対して、モデル・ビュー・コントローラを結合してテスト

requite File.dirname(__FILE__) + '/../test_helper'
 
class EntriesControllerTest < ActionController::TestCase
  def test_truth
    assert true
  end
end

流れ

テスト環境をセットアップ
requite File.dirname(__FILE__) + '/../test_helper'
コントローラを指定
requite File.dirname(__FILE__) + '/../test_helper'
 
class ShopsControllerTest < Test::Unit**testCase
  def setup
    @controller = ShopsController.new
    @request = ActionController::TestRequest.new
    @response = ActionController:TestResponse.new
  end
end
リクエストを送信
def test_should_get_index
  get :index
end
アクションの実行結果を確認
レスポンスが成功したかを検証
assert_response :success
アクション内で設定されたインスタンス変数を検証
assigns
出力結果のHTMLを検証
assert_select

テストメソッド

リクエスト送信のためのメソッド
メソッド 説明
get(action, parameters) アクションに対して、GETリクエストを送信
post(action, parameters) アクションに対して、POSTリクエストを送信
xhr(request_method, action, parameters = nil, session = nil, flash = nil) アクションに対して、XMLHTTPRequestを送信
状態設定・取得のためのメソッド
メソッド 説明
assigns(key = nil) アクションを実行した結果、インスタンス変数に代入されたオブジェクトを取得
session ファンクショナルテストで使用されるセッションへのアクセサ
flash コントローラ内で使用するflashへのアクセサ
検証のためのメソッド
メソッド 説明
assert_response(type, message = nil) アクション実行結果のレスポンスコードを検証
assert_redirected_to(options = {}, message = nil) リダイレクトを返すアクションに対して、そのリダイレクト先がどうなっているか検証
assert_template(expeced, message = nil) そのアクションで指定されたテンプレートが描写されているかを検証
assert_select(selector, equality?, message?) アクション実行の結果として描写されるHTMLの内容を検証

インテグレーションテスト

説明

複数のアクションやコントローラにまたがる挙動を検証するためのテスト

テストを生成

$ ruby script/generate integration_test テスト名

流れ

  1. テスト環境をセットアップ
  2. リクエストとその検証、というペアを複数回記述

テストを記述

class CreateNewShopFinallyShowThemAllTest < AxtionController::IntegrationTest
  fixtures :users, :shops
 
  def test_create_new_shop_and_show_thwm_all
    shops_count_before_create = Shop.count
 
    get "/shops/list"
    assert_response :success
    assert_select "table > tr", :count => (shops_count_before_create + 1)
    assert_select "a[href=?]", %r!/shops/new!
 
    get "/shops/new"
    assert_response :success
    assert_select "form[action=?]", %r!/shops/create!
    assert_select "form input[name='shop[name]']"
 
    post_via_redirect "/shops/create", :shops => { :name => "new_shop" }
    assert_response :seccess
    assert_template "shops/list"
 
    assert_equal (shops_count_before_create +1), Shop.count
  end
end