最近までcucumberを使ってたのでその時に気づいたことのメモです。
基本通りfeatures以下にfeatureファイルとかを置いていたとして、cucumberはfeature以下のファイルを全て読み込むようなのでステップの定義がユニークじゃないと意図しないほうが呼ばれてしまうので気をつけないといけないのですね。
そのかわり同じステップを使いたい場合は重複して実装する必要は無いということになるのですが…
あと、@マーク付きのインスタンス変数も同じような感じなので注意ですね。
例えばこんなディレクトリ構造にして
features --- background | |--- background.rb |-- say_goodbye | |--- say_goodbye.feature | |--- say_goodbye.rb |-- say_hello | |--- say_hello.feature | |--- say_hello.rb
say_hello.featureをこのようにしてバックグラウンド、シナリオのアウトライン、シナリオを定義します。
Feature: cucumber test say_hello In order to foobar As a Foo I want test say_hello Background: This is a common background Given I start a test I setup global data |greeting| |hello, world| Scenario Outline: say_hello scenario outline Given a test scenario When I print "<message>" to user Then this test will finish Scenarios: say_hello scenario 1 |message| |foobar|
say_hello.rbを以下の用にしてBackgroundは別ファイルに記述してみます。
Given /^a test scenario$/ do printf "\\nshow greeting\\n" printf "%s\\n", @greeting end When /^I print "(.*?)" to user$/ do |message| printf "%s\\n", message end Then /^this test will finish$/ do printf "this test will finish\\n" end
background.rbはこんな感じです、greetingに.featureで定義したテーブルから読んだ値を入れるようにします。
Given /^I start a test I setup global data$/ do |table| @greeting = table.raw[1][0] end
あとはsay_goodbye.featureですが、こちらはバックグラウンドはデータが違うだけにして、シナリオのステップも最後以外は同じにします。
@say_goodbye Feature: cucumber test say_goodbye In order to foobar As a Bar I want test say_goodbye Background: This is a common background Given I start a test I setup global data |greeting| |goodbye, world| Scenario Outline: say_goodbye scenario outline Given a test scenario When I print "<message>" to user Then I want to say goodbye again Scenarios: say_goodbye scenario 1 |message| |FOOBAR|
say_goodbye.rbは最終ステップだけ書きます。
Then /^I want to say goodbye again$/ do printf "%s\\n", @greeting end
これでfeaturesがあるディレクトリに移動して以下のように実行すると
$ cucumber --tags @say_hello
- background.rbにあるステップを実行
- say_hello.rbのステップを実行
↑という風に動くので↓のような出力になります。
[masami@saga:~/cc]$ cucumber --tags @say_hello @say_hello Feature: cucumber test say_hello In order to foobar As a Foo I want test say_hello Background: This is a common background # features/say_hello/say_hello.feature:9 Given I start a test I setup global data # features/background/background.rb:1 | greeting | | hello, world | Scenario Outline: say_hello scenario outline # features/say_hello/say_hello.feature:14 Given a test scenario # features/say_hello/say_hello.rb:1 When I print "<message>" to user # features/say_hello/say_hello.rb:6 Then this test will finish # features/say_hello/say_hello.rb:10 Scenarios: say_hello scenario 1 | message | | show greeting hello, world foobar this test will finish foobar | 1 scenario (1 passed) 4 steps (4 passed) 0m0.005s
say_goodbyeも同じような感じでbackground.rbのステップ、say_helloのステップ、say_goodbyeのステップが実行されます。
[masami@saga:~/cc]$ cucumber --tags @say_goodbye @say_goodbye Feature: cucumber test say_goodbye In order to foobar As a Bar I want test say_goodbye Background: This is a common background # features/say_goodbye/say_goodbye.feature:9 Given I start a test I setup global data # features/background/background.rb:1 | greeting | | goodbye, world | Scenario Outline: say_goodbye scenario outline # features/say_goodbye/say_goodbye.feature:14 Given a test scenario # features/say_hello/say_hello.rb:1 When I print "<message>" to user # features/say_hello/say_hello.rb:6 Then I want to say goodbye again # features/say_goodbye/say_goodbye.rb:1 Scenarios: say_goodbye scenario 1 | message | | show greeting goodbye, world FOOBAR goodbye, world FOOBAR | 1 scenario (1 passed) 4 steps (4 passed) 0m0.005s
と言うわけでcucumberを使うときにステップ名が重複した場合、意図しないステップが実行される可能性があるので気をつけないといけないですねφ(・・*)ゞ ウーン