Skip to content

テスト用フィードをすべてモックで作るようにしたが、テストが通らない #12

Closed
weed opened this Issue Mar 11, 2013 · 14 comments

2 participants

@weed
Owner
weed commented Mar 11, 2013
Failures:

  1) Feedクラス サンプルフィードを取得するとき 配列オブジェクトの要素数は5である
     Failure/Error: @feed3.items.length.should == 5
       expected: 5
            got: 1 (using ==)
     # ./spec/feed_spec.rb:24:in `block (3 levels) in <top (required)>'

  2) Feedクラス #append @feed1の長さは5、@feed3の長さは2のとき、それらをappendしたfeedの長さ 
     Failure/Error: it{should have(10).items}
       expected 10 items, got 6
     # ./spec/feed_spec.rb:32:in `block (4 levels) in <top (required)>'

  3) Feedクラス #unique #unique:重複する項目を除去する
     Failure/Error: @feed1.append(@feed1).unique.items.length.should == 5
       expected: 5
            got: 6 (using ==)
     # ./spec/feed_spec.rb:42:in `block (3 levels) in <top (required)>'

Finished in 4.87 seconds
11 examples, 3 failures
@utwang
Collaborator
utwang commented Mar 11, 2013

メールが飛んできたので見ちゃいました。

feed_spec.rbの各itブロックの先頭に、
以下のコードを追加してrspec実行すると原因がわかると思います。

puts "example_1"   #数字は連番
puts  [@feed1, @feed2, @feed3, @feed4].map{|f| f.items.length}

例)

it "1つ以上の要素を持った配列オブジェクトが生成される" do
  puts "example_1" 
  puts  [@feed1, @feed2, @feed3, @feed4].map{|f| f.items.length}
  ...
end

it "配列オブジェクトの要素数は5である" do
  puts "example_2" 
  puts  [@feed1, @feed2, @feed3, @feed4].map{|f| f.items.length}
  ...
end
it { should xxxx }

と書いているところは

it {
  デバッグ文
  should xxxx
}

とする

@weed
Owner
weed commented Mar 12, 2013
puts "example_1"
puts [@feed1, @feed2, @feed3, @feed4].map{|f| f.items.length}

で確認したところ以下の結果が得られた

example_1
5
5
1
5

@feed3の中身は以下のモック

https://github.com/weed/p120908-new-movies-server/blob/master/hatena_gijutsu.txt

truncateしても要素数1にはならないはずなのだが・・・?

@utwang
Collaborator
utwang commented Mar 12, 2013

全部のitブロックに仕込みました?
そうするとexample_1, example_2, .....と
複数のデバッグ文が表示されません?

@weed
Owner
weed commented Mar 12, 2013

ご指示通り出力したら、なぜか動くようになりました。

weed-MBA% rspec -fd

App
  レスポンスの精査
    /へのアクセス
      正常なレスポンスが返ること

Feedクラス
example_6
5
5
5
5
  #truncate:項目数を制限する
example_7
5
5
5
5
  #regex:内容を置換する
example_8
5
5
5
5
  #filter:キーワードを含むフィードを返す
  サンプルフィードを取得するとき
example_1
5
5
5
5
    1つ以上の要素を持った配列オブジェクトが生成される
example_2
5
5
5
5
    配列オブジェクトの要素数は5である
  #append
    長さ5の@feed1に長さ5の@feed3を#appendしたとき、返るfeed
example_3
10
5
5
5
      should have 10 items
  #unique
example_4
5
5
5
5
example_5
5
5
5
5
    #unique:重複する項目を除去する

Urlクラス
  #to_s:URL文字列を返す
  #host:ホスト名を返す
  #path:パスを返す

Finished in 9.05 seconds
11 examples, 0 failures
@weed weed pushed a commit that closed this issue Mar 12, 2013
Tatsuro Ueda fixed #12 787e49c
@weed weed closed this in 787e49c Mar 12, 2013
@utwang
Collaborator
utwang commented Mar 12, 2013

まだ解決はしてないと思いますよ。

もう1〜2回rspec実行してみてください。

@utwang utwang reopened this Mar 12, 2013
@weed
Owner
weed commented Mar 12, 2013

いけておりまする。不可思議。

@utwang
Collaborator
utwang commented Mar 12, 2013

あーー、before(:all)から before(:each)に直してるじゃないですか。
そりゃ、通るわ。

before(:all)に戻して、何回か実行してみたらなぜだかわかると思いますよ。

@weed
Owner
weed commented Mar 12, 2013

やってみます!

@weed
Owner
weed commented Mar 12, 2013

ががーん。なるほどー。流石ですね。素晴らしい。大変良くわかりました。

weed-MBA% rspec -fd

App
  レスポンスの精査
    /へのアクセス
      正常なレスポンスが返ること

Feedクラス
example_5
5
5
5
5
  #truncate:項目数を制限する
example_6
5
5
5
5
  #regex:内容を置換する
example_7
5
5
5
5
  #filter:キーワードを含むフィードを返す
  サンプルフィードを取得するとき
example_1
5
5
1
5
    1つ以上の要素を持った配列オブジェクトが生成される
example_2
5
5
1
5
    配列オブジェクトの要素数は5である (FAILED - 1)
  #append
    長さ5の@feed1に長さ5の@feed3を#appendしたとき
example_3
5
5
1
5
      should have 10 items (FAILED - 2)
  #unique
    @feed1に@feed1を#appendしたあと#uniqueしたとき
example_4
6
5
1
5
      should have 5 items (FAILED - 3)
@weed
Owner
weed commented Mar 12, 2013

できた!

weed-MBA% rspec -fd

App
  レスポンスの精査
    /へのアクセス
      正常なレスポンスが返ること

Feed
  サンプルフィードを取得するとき
    1つ以上の要素を持った配列オブジェクトが生成されること
    配列オブジェクトの要素数は5であること
  #append
    長さ5の@feed1に長さ5の@feed3を#appendしたとき
      should have 10 items
  #unique
    @feed1に@feed1を#appendしたあと#uniqueしたとき
      should have 5 items
  #truncate
    @feed1に@feed2を#appendしたあと#truncate(5)したとき
      should have 5 items
  #regex
    @feed2の中身を#regexしたとき
      should have 5 items
  #filter
    @feed3の内、指定のキーワードを含むものを抽出したとき
      1つ以上の要素を持つこと

Urlクラス
  #to_s:URL文字列を返す
  #host:ホスト名を返す
  #path:パスを返す

Finished in 9.94 seconds
11 examples, 0 failures
@weed weed closed this in 97ffe9b Mar 12, 2013
@utwang
Collaborator
utwang commented Mar 12, 2013

before(:all)が原因だったわけですけど、
it の実行順がspecファイルに書かれた順番ではないというのは、想定通りの動きでした??

@weed
Owner
weed commented Mar 12, 2013

それも発見でした。Test:Unitがそんな感じだよね。

書き上がったテスト。だいぶマシになったと思わない?
https://github.com/weed/p120908-new-movies-server/blob/master/spec/feed_spec.rb

@utwang
Collaborator
utwang commented Mar 12, 2013

いいんじゃないですかねぇ。:thumbsup:

順番が保証されていないということは、
before(:all)でデータをセットアップして、データを変更するようなテストは
example間で干渉しあうから向かないですね。

なので、before(:all)を使うときは
参照系のテストにしたほうがよさそうですね。

@utwang
Collaborator
utwang commented Mar 12, 2013

ローカルで試したり、調べてみたら、知らないことがあったのでメモしときます。

ソース:
https://www.relishapp.com/rspec/rspec-core/v/2-13/docs/command-line/order-new-in-rspec-core-2-8
http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/Configuration#order%3D-instance_method

以下、ローカルのRailsプロジェクトのModelのspec.rb

1) デフォルトの状態で実行するとランダムに実行される。

➜  address_book git:(rspec_order) ✗ be rspec spec/models/address_spec.rb

Address
  association
example_1
    should belong to address_list
  validation
example_6
    should require case sensitive unique value for email
example_3
    should require last_name to be set
example_4
    should require email to be set
example_5
    should require phone to be set
example_2
    should require first_name to be set

Finished in 0.63955 seconds
6 examples, 0 failures

Randomized with seed 38212

rails generate コマンドで作られるspec_helper.rbには
以下の設定がされてランダムになるよう。

 config.order = "random"

2) --order defaultオプションをつけて実行

➜  address_book git:(rspec_order) ✗ be rspec spec/models/address_spec.rb --order default

Address
  association
example_1
    should belong to address_list
  validation
example_2
    should require first_name to be set
example_3
    should require last_name to be set
example_4
    should require email to be set
example_5
    should require phone to be set
example_6
    should require case sensitive unique value for email

Finished in 0.59616 seconds
6 examples, 0 failures

ファイルに定義された順番通りに実行される。

3) 明示的にランダム実行するように指定することもできる

➜  address_book git:(rspec_order) ✗ be rspec spec/models/address_spec.rb --order rand

Address
  association
example_1
    should belong to address_list
  validation
example_4
    should require email to be set
example_2
    should require first_name to be set
example_5
    should require phone to be set
example_3
    should require last_name to be set
example_6
    should require case sensitive unique value for email

Finished in 0.64643 seconds
6 examples, 0 failures

Randomized with seed 3999

4) ランダム実行時に表示されるRandomized with seed XXXX
 のXXXXを指定することでランダム実行の順番を再現できる。
 以下は1)のランダム実行時のseed 38212を使って再現。
  -> 1)と同じ順番になる。

➜  address_book git:(rspec_order) ✗ be rspec spec/models/address_spec.rb --order rand:38212

Address
  association
example_1
    should belong to address_list
  validation
example_6
    should require case sensitive unique value for email
example_3
    should require last_name to be set
example_4
    should require email to be set
example_5
    should require phone to be set
example_2
    should require first_name to be set

Finished in 0.65543 seconds
6 examples, 0 failures

Randomized with seed 38212
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.