问题
I am writing a feature which deals with adding multiple items to shopping cart like a typical e-commerce application.
It is something like this -
Scenario: Promotion is applied
Given I select "Bacon" worth "$1"
Given I select "Lettuce" worth "$2"
Given I select "Diet Coke" worth "$5"
Given I select "Bread" worth "$2"
Then "$0.5" promotion should be applied for "Bacon"
Then "$0.0" promotion should be applied for "Lettuce"
Then "$0.5" promotion should be applied for "Diet Coke"
Then "$1.0" promotion should be applied for "Bread"
Then total paid should be "$8"
Needless to say, the stepdefs.js look something like this:
Given(/^I select "([^"]*)" worth "([^"]*)"$/, function (item, price) {
//addToCart
});
etc.
There is another scenario which is similar and adds clothes instead of food items.
If I am using Scenario outline and Examples it turns to this:
Scenario Outline: Promotion is applied
Given I select "<item>" worth "<price>"
Given I select "<item>" worth "<price>"
Given I select "<item>" worth "<price>"
Given I select "<item>" worth "<price>"
Then "<discount>" promotion should be applied for "<item>
Then "<discount>" promotion should be applied for "<item>
Then "<discount>" promotion should be applied for "<item>
Then "<discount>" promotion should be applied for "<item>
Then total paid should be "$8"
Examples:
| item | price | discount |
| "Bacon" | "$1" | 0.5
| "Lettuce" | "$2" | 0.0
| "Diet Coke" | "$5" | 1.0
| "Bread" | "$2" | 0.5
But it runs the test once per row (so four tests are run), what I essentially want is running all of them for one test.
In fact I want to run them as 4 items added for food vs 2 items added for clothes. So,
Scenario Outline: Promotion is applied <type>
Given I select "<item>" worth "<price>"
Then "<discount>" promotion should be applied for "<item>"
Then total paid should be "<total>"
Examples:
type | items & prices & promotion (may be some object like that?) | total
food | [ {"Bacon - $1 - 0.5"}, {"Lettuce - $2 - 0.0"}, {"Diet Coke - $5 - 1.0"}, {"Bread - $2 - 0.5"} ] /*takes an array*/ | $8
clothes | [{"pant - $50 - 10"}, {"shirt - $25 - 5"}] | $60
Is it even possible? How do one achieve that?
Thanks
[EDIT]: This is just an example question, I've removed all complications and this is just a nailed down version. My idea is to get a way to use array of objects in scenarios. Please do not go by the name and numbers mentioned in the question.
回答1:
Putting figures in scenarios is a really good way to dramatically increase the cost of change, whilst at the same time creating fragile tests with high maintenance costs. So don't do it.
In addition you are not clearly stating what you are testing and you are repeating yourself.
From what you have written I can see lots of different behaviour you might be specifying here.
You should write separate scenarios for these things. So you could have scenarios like
Scenario: Promotion affects all products in the basket
Given a have a basket with several products
And I have applied a promotion
When I go to the checkout
Then I should see a discount applied to each product
Scenario: Some products are not discountable
to deal with the actual value of the discount
Scenario: Correct discount rate is applied for a promotion
Given a promotion with a 20% discount
And a basket of products
When I go to the checkout
Then I should see a 20% discount
etc. etc.
Note: Doing calculations like in your examples is a particularly effective way of making your scenarios expensive to maintain, and to increase the cost of change of your application.
Consider your example. It has several business rules hidden in the figures. Some of these probably are:
- lettuce is not discounted by promotions
- bacon is half price (or is that any quantity of bacon gets 50c off?) ...
Note how none of these rules a clearly specified in you example scenarios, you have to infer (guess) the rule from the example.
Now all of these are rules that must somehow be encoded in your application (hopefully in the promotion and products). What happens when
- lettuce becomes discountable
- bacon supplies are tight so you can't discount it any more
With your current approach what happens is that you tests fail and you have to re-write the scenarios to reflect your new business conditions - so you have dramatically increased the cost of change.
The simple rule for this stuff is don't put calculated numbers in scenarios. The fuller more complex rule is that all examples in scenarios should mature into concise verbal expressions of business rules. They should capture the WHAT i.e. that some products can have a percentage discount, rather than HOW i.e. bacon is currently 50c per pound cheaper. Then if someone makes the simple config change that bacon is no longer discountable you don't have your tests breaking because of this.
回答2:
A second answer is that
Cucumber is not a testing tool, if you want to write data driven tests use a testing tool like a unit test tool.
来源:https://stackoverflow.com/questions/59250093/cucumber-data-driven-testing-multiple-similar-steps-in-same-scenario