2012-02-09 22 views
15

シナリオ特定の例外がキュウリにスローされると主張し

私は、私は非常に詳細なキュウリの機能を持っているしたい対象のライブラリ(on Railsの無ルビー)を書いています。これには、さまざまな場合にスローされるべきエラー/例外の記述が含まれます。

キュウリの手順を記述するための最も直感的な方法は、おそらく私が対処しなければならない二つの問題があります

When I do something unwanted 
Then an "ArgumentError" should be thrown 

ような何か問題

次のようになります。

  1. 例外がスローされた場合、最初の手順は失敗しません。
  2. 最初のステップがスローする例外は、アサーション・マジックを行うために2番目のステップにアクセス可能でなければなりません。

Unelegant面倒なソリューション

私が思い付くことができました最善のアプローチは、第2のステップはアクセスできることを最初のステップで例外をキャッシュし、インスタンス変数にそれを入れています、以下のようなので:

When /^I do something unwanted$/ do 
    begin 
    throw_an_exception! 
    rescue => @error 
    end 
end 

Then /^an "(.*)" should be thrown$/ do |error| 
    @error.class.to_s.should == error 
end 

はしかし、これは私がが、それは失敗したくない、それが良いことになることはありませんインスタンス変数を、必要とする場合は、多かれ少なかれ役に立たない最初のステップになります。

少なくとも、あまり煩雑なソリューションで誰も助けてくれませんか?とにかく私の機能を別の方法で書き込むべきですか?どんな助けでも大歓迎です。

+0

この質問はうまく書かれています。 (私は1つを思い付くことができなかった申し訳ありません)確かに良い答えに値する:) – user562529

+0

ありがとう@ user562529。残念ながら、私は実際にこの問題に簡単な解決策がないと感じているので、キュウリの問題を開いて、実用的なものを実装してほしいと思うかもしれません。 – JLimperg

答えて

5

私はもう一度それについて考え、そしておそらく答えは:

Given-When-Then -schemeがあなたのケースに違反しているので、何もエレガントな解決策は、ありません。 あなたは「例外がスローされるはずです」とは、「私が何か望ましくないことをしたとき」の結果です。

しかし、あなたがそれについて考えるとき、これは真実ではありません!例外はこのアクションの結果ではありません。実際、例外は「いつ」 - ステートメントが失敗したことを示しています。

When I do something unwanted 
Then an error should be logged 

または

When I do something unwanted 
Then the user should get an error message 

または

When I do something unwanted 
Then the program should be locked in state "error" 

、またはこれらの組み合わせ:これに

私のソリューションは、より高いレベルでテストすることになります。

あなたはあなたのプログラムに「例外をキャッシュする」でしょう - とにかくそれを行う必要があるので、これは完璧な意味を持ちます。

あなたが述べた2つの問題も解決されます。あなたが本当に例外

をテストしなければならない場合には

さて、私はその後、キュウリはうーん、右のテストスイートではないと思いますか? ;-)

考える-すると、その後、スキームがとにかく違反しているとして、私は単に

When I do something unwanted it should fail with "ArgumentError" 

を書くでしょうなどステップの定義何かに(あなたがそれをしようとテストしていない、私を修正してください)

上記のように、それはスキームが壊れているのでひどく間違っていますが、目的に役立つでしょうか? ;-)

さらに、テストエラーat rspec expectationsでドキュメントが見つかります。

+0

ああ...もう一度最初の文章を読みました。あなたの書いた図書館のように、答えが多かれ少なかれ役に立たないかどうか気にしないでください。 – user562529

+1

この広範な執筆をいただきありがとうございます。残念なことに、あなたのコメントも頭の爪に当たっています。 ;) しかし、あなたの言うことはおそらく、この問題にはまだ正確で関連しています。キュウリは、図書館のエラー処理を深く掘り下げる目的で設計されていないかもしれません。私はこの問題についてRSpecに固執するようです。 – JLimperg

+0

私はこの同じ問題を抱えており、Cucumberはアプリケーションのテストに最適なライブラリですが、ライブラリのテストには適していないという結論に達しました。キュウリの最大の強みは、コードを読んでいない人が読むことができ、開発者のライブラリの仕様を読むのに非デベロッパーはほとんど関心がないということです。そのため、アプリのためのCucumberとライブラリのRSpec 。 これは、アプリケーション開発中にこのページを見つけた私のような人にとっては良い答えです。その場合、より高いレベルで仕様を書く方が適切です。 –

4

1つの方法は、@allow-rescueというシナリオをマークし、ページの出力とステータスコードを確認することです。例えばmy_steps.rb

Then(/^the page (?:should have|has) content (.+)$/) do |content| 
    expect(page).to have_content(content) 
end 

Then(/^the page should have status code (\d+)$/) do |status_code| 
    expect(page.status_code.to_s).to eq(status_code) 
end 

Then /^I should see an error$/ do 
    expect(400..599).to include(page.status_code) 
end 

my_feature.feature

で​​

または代わり:

@allow-rescue 
Scenario: Make sure user can't do XYZ 
    Given some prerequisite 
    When I do something unwanted 
    Then I should see an error 

これは、あなたが望んでいたまさにではないかもしれないが、それはあるかもしれませんこのページに出会う一部の人々のための許容可能な回避策。私はそれが例外のタイプに依存すると考えています。なぜなら、例外がどのレベルでも救済されなければ、シナリオはまだ失敗するからです。私はこのアプローチを、今までのところルーティングエラーのために使ってきましたが、うまくいきました。

-1

私はビヘイビア駆動開発の状況にキュウリの機能を使用していますので、それを取るか、またはそれを残す誰かの視点から答える...

シナリオは、「機能」や機能をテストするために書かれるべきですコード自体のテストに使用されるのではなく、アプリケーションの例である:

When the service is invoked 
Then a success code should be returned 

それはあなたのテストケースのように聞こえる(私はこれを行う場合、すなわち、この例外がスローされなければならない)は、ユニットまたは統合テストのための候補である - 私の場合には、我々はいくつかのモッキングかを使用しますユニットテストフレームワーク。

フィーチャシナリオを再評価して、実際にテストする対象をテストしているかどうかを確認することをお勧めします。個人的な経験から、テストクラスが異常に複雑になると、私の機能が「間違っている」ことがわかりました。

1

Whenブロックで例外を発生させ、次にそれを次のThenブロックでアサーションすることができます。;例はRSpecのマッチャーを使用していますが、重要な部分は、->(ラムダ)であることを

When /^I do something unwanted$/ do 
    @result = -> { throw_an_exception! } 
end 

Then /^an "(.*)" should be thrown$/ do |error| 
    expect{ @result.call }.to raise_error(error) 
end 

あなたの例を使用してthrow_an_exception!メソッドへの参照を渡すことができます。

私はそれが助けてくれることを願っています!

関連する問題