ITコンサルの日常

ITコンサル会社に勤務する普通のITエンジニアの日常です。

「RailsによるアジャイルWebアプリケーション開発」13章まで読了

モデルのユニットテスト

sqliteなので、データベースが無いエラーは出ませんでした。
が、テーブルが無いエラーは普通に出たので、rake db:test:prepareは行いました。


Railsとは関係ないのですが、priceが0.01以上ならOKというロジックに対して、テストケースが

  • -1
  • 0
  • 1

っていうのはいただけませんね。

  • -0.01
  • 0.009
  • 0.01

とかにして欲しかったです。


テストフィクスチャについては、以前Railsセミナーでもこれは使えるなあって思ってた要素なのですが、実際に使ってみるとやっぱりいいです。
データベースのデータって、コマンドとかでセットアップするのは結構大変なので、ymlに書くだけで自動セットアップしてくれるのはありがたいです。
ちなみにid列は省略することもできますし、明示的に書くことも出来ます。

コントローラの機能テスト

特にハマりポイントなし。
むしろ、before_filterの設定漏れが発覚したくらい。

アプリケーションの統合テスト

ここはハマりました。ポイントをいくつか。

xml_http_request "/store/add_to_cart", :id => ruby_book.id
assert_response :success

ここでエラー発生。

  1) Failure:
test_buying_a_product(UserStoriesTest)
    [test/integration/user_stories_test.rb:24:in `test_buying_a_product'
     C:/InsRails/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/integration.rb:547:in `run']:
Expected response to be a <:success>, but was <0>

レスポンスコード0って、どういうことよって感じですが。
いや、そもそも:successって何?っていうのは調べて分かりました。
http://api.rubyonrails.org/classes/ActionController/Assertions/ResponseAssertions.html#M000354
200のことらしいです。
うーん、どうもここは良く分からないので、AJAXバージョンじゃないリクエストを使って通すことにしました(解決になってない)

#    xml_http_request "/store/add_to_cart", :id => ruby_book.id
     get "/store/add_to_cart", {:id => ruby_book.id}
#    assert_response :success
     assert_redirected_to :action => :index

とりあえず無事通過。


次はここ

    post_via_redirect "/store/checkout",
    		      :order => { :name => "Dave Thomas",
		                  :address => "123 The Street",
		                  :email => "dave@pragprog.com",
		                  :payment_type_id => "1" }

最初、何も考えずに本を丸写ししてたら、さっぱり動かないので、何がいかんのだろうと考えた挙句、そういやsave_orderアクションはcheckoutアクションに統合したんだったとか、支払い方法はpayment_typesテーブルに持つことにしたんだったとか、色々思い出し上記のように変えてみました。
が、無情にも、

  1) Failure:
test_buying_a_product(UserStoriesTest)
    [test/integration/user_stories_test.rb:41:in `test_buying_a_product'
     C:/InsRails/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/integration.rb:547:in `run']:
expecting <"index"> but rendering with <"checkout">

とか出るし。


どうも、チェックアウトに失敗してチェックアウト画面に戻りつつ、エラーメッセージを出力している様子だったので、良く分からないながらprintデバッグを仕込むことに。
app/controllers/store_controller.rb

    if @order.save
      session[:cart] = nil
      redirect_to_index("ご注文ありがとうございます")
    else
      @order.errors.each {|err|
        puts "err: " + err.to_s
      }
      render :action => :checkout
    end

すると、エラーは

err: payment_type_idis not included in the list

であることが判明。
どうでもいいけど、idとisがくっついとるなあ。


で、昨日から考えててさっき分かったのが、payment_typesテーブルにレコードが入ってないとダメなんじゃん!ってこと。
なので早速payment_types.ymlを用意することに。

1:
  id: 1
  label: 現金
  value: check

2:
  id: 2
  label: クレジットカード
  value: cc

3:
  id: 3
  label: 注文書
  value: po

これで無事integrationテストも通りましたとさ。

パフォーマンステスト

テストフィクスチャにRubyコードが書けるのが素晴らしい!
繰り返し大量データを簡単に生成できます。