ちょっぴりテスト突入
今日の作業
明日のRuby研修の下準備
ユーザ削除、ログアウト
テストについて
今日の作業でわかったこと&わからなかったこと
今日からテストについてのタスクに入りました。
これまではdepotディレクトリのappディレクトリやdbディレクトリ内を主に触っていたので
testディレクトリ内にファイルができているのを知らなかったので驚いた。
今日の所はテストを作っていくにあたっての準備的な所で終わってしまったけど、
テスト用DBにスキーマ情報をロードする方法やテストフィクスチャについてなどを
知ることができました。
また明日からはRuby研修に塩見さんのサポート役として参加します。
サポート役ですがいろいろ知らないことの方が多いと思うので、
できるだけ多くの知識を吸収していきたい。
明日やること
モデルのテスト
Ruby研修
調べたことのまとめ
ユーザ削除機能
ユーザが全て削除されてしまうとDBを直接操作してデータを格納するまでログインできなくなるので
そうならないようにする。
それを実現するためにUserモデル内にdont_destroy_dave()というフックメソッドを定義し、
destroyされる前にこのメソッドが呼び出されるようにする。
ここでもコールバックを使うのか〜
コールバックを定義する前回と違う方法は次のようにクラスレベルの宣言を使って、
実際に処理をするインスタンスメソッドを参照する方法。
User.rbモデルに
before_destroy :dont_destroy_dave def dont_destroy_dave raise if name == 'aaa' end
raiseメソッドは例外を発生させるメソッド。
例外を処理するには次のようにコードをbeginとendで囲みrescue節を記述する。
login_controller.rb
def delete_user id = params[:id] if id && user = User.find(id) begin user.destroy flash[:notice] = "ユーザ #{user.name}が削除されました" rescue flash[:notice] = "このユーザは削除できない" end end redirect_to(:action => :list_users) end
Railsによるテストのサポート
このアプリケーションの最上位ディレクトリを見てみると既にその直下にtestと言うサブディレクトリが存在している。
その中には四つのディレクトリと一つのヘルパーファイルがある。
test$ ls fixtures functional integration mocks test_helper.rb unit
Railsでは規約により、モデルを対象とするテストはユニットテスト(unit test)、
コントローラを対象とするテストは機能テスト(functional test)と呼ばれる。
それぞれのディレクトリ内は
/test$ ls functional/ admin_controller_test.rb login_controller_test.rb store_controller_test.rb /test$ ls unit/ add_shipped_at_test.rb line_item_test.rb product_test.rb cart_test.rb order_test.rb user_test.rb
とモデルとコントローラに対応するユニットテストと機能テストを記述するためのファイルが、
既に作成されている。
まずはモデルのテストから始める。
その前にこのアプリを作る際3つのDBを作成した。
Railsのユニットテストでは自動的にテスト用DBが使用される。
しかしこのDBには商品データはおろかテーブルさえ作成されていない。
でもRailsには開発用DB構造をテスト用DBに複製する機能がある。
/depot$ rake clone_structure_to_test
これでテスト用DBにスキーマをロードできたが商品データは何も格納されていない。
insertで入力することもできるが手間がかかる。
また、今後DBのデータを変更するテストを実行した場合、その後同じ条件でテストを再開するために、
なんらかの方法で初期データをリロードしないといけなくなる。
この問題の対処法としてテストフィクスチャがある。
テストフィクスチャ
テストフィクスチャとはモデルの初期データの内容を指定したもの。
ユニットテストを実行する際、常にテーブルに正しい内容のデータが格納された状態で開始したい場合は、
そのデータの内容をフィクスチャで指定するだけ。
フィクスチャデータはtest/fixturesディレクトリのファイルで指定。
YAMLフォーマットのフィクスチャファイルに1つのモデルのデータだけ記述。
YAMLについて
http://jp.rubyist.net/magazine/?0009-YAML
test/fixtures/products.yml
version_control_book: id: 1 title: Pragmatic Version Control description: バージョン管理の使用法 price: 730 date_available: 2005-01-26 00:00:00 autmation_book: id: 2 title: Pragmatic Project Automation description: プロジェクトを自動化する方法 price: 2300 date_available: 2004-01-1 00:00:00
次はユニットテスト実行時に、このテストデータがRailsによってProductsテーブルに
ロードされるようにする。
product_test.rb内に
fixtures :products
fixtures()メソッドは、このテストケースの各テストメソッドの開始時に指定されたモデル名に
対応するフィクスチャを自動的にロードする。
また規約によりモデルのシンボル名を使用することが決められている。