Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What makes a Feature and What a scenario in Gherkin and cucumber? [closed]

Say I am developing a Shopping cart, BDD, with Cucumber. A cart is rather complex and has many bells-and whistles, but this could be just as well for "a blog" or "a user profile".

I've always considered the "cart" to be the Feature and the bells-and-whistles to be the Scenario's. However, this can make large Feature files and goes against the literal meaning of a Scenario. Here is how that would look:

Feature: Cart

  So that I can buy items
  As a user
  I want to place items in a cart


  #.... Many more scenarios

  Scenario: Empty a filled cart
    Given 2 products in my cart
    When I visit the cart page
    And I press "Empty cart"
    Then I should see the text:
      """
      Your cart is empty.
      """

  Scenario: Empty an empty cart
    Given 0 products in my cart
    When I visit the cart page
    Then I should not see the "Empty cart" button

  # Many more Scenario's

The more details are filled out, the longer this "empty cart" group becomes. I wonder, should "emptying cart" be considered a standalone Feature? This would lead to many Features, all containing but a few Scenario's. The Scenario's then become more like "contexts". Like so:

Feature: Emptying Cart

  So that I can reconsider my shopping-spree
  As a user
  I want to empty my cart

  Scenario: with a filled cart
    Given 2 products in my cart
    When I visit the cart page
    And I press "Empty cart"
    Then I should see the text:
      """
      Your cart is empty.
      """

  Scenario: with an empty cart
    Given 0 products in my cart
    When I visit the cart page
    Then I should not see the "Empty cart" button

What is a good guideline for making something a Feature? When should I regroup Scenario's into their own Feature? How many Scenario's does a Feature commonly have?

like image 473
berkes Avatar asked Apr 17 '13 11:04

berkes


2 Answers

You can shorten your scenarios - and even get rid of a few - by phrasing them in declarative, rather than imperative, language.

For instance:

Given the cart has two products in
When I empty the cart
Then I should see it has nothing in it.

This could be just as true of an actual shopping cart as a UI. It has no implementation details in it. You can see that some of the steps correspond to more than one of yours; this is a good thing as it keeps the complexity in the code where it's more maintainable.

If we phrase your other scenario this way, we get:

Given my cart is empty
Then I should not be able to empty it again.

There's no "when" here because the "then" is simply true for that state.

Do you really need this scenario, though? Would it kill you or your company to release with the ability to empty an already-empty cart? This is essentially aesthetic. It's been added to make the UI easier to use, and the only way to tell if a UI is usable is to actually use it. If you ever find these kind of scenarios, I recommend taking them out. You can always unit-test the logic that leads to the button being enabled or disabled.

If you change to this style of language, then remove any scenarios that are only testing aesthetics and usability, you'll find your feature files become much, much smaller.

I also recommend putting the most interesting or surprising scenarios at the top. For instance, this would be a more interesting scenario (and yes, it has two "whens" in it, because it describes the behavior associated with an interaction between two different users):

Given a user put a copy of "Moby Dick" in his cart
When the last copy of "Moby Dick" is sold
And the user comes back to look at his cart
Then it should tell him, "Sorry, this item is currently out of stock."

This would be even more interesting:

Given a user put a new copy of "Moby Dick" in his cart
And there are second-hand copies of "Moby Dick" available
When the last new copy of "Moby Dick" is sold
And the user comes back to look at his cart
Then it should tell him, "Sorry, this item is currently out of stock."
And it should also show the way to the second-hand copies with,
  "2nd hand copies are available."

That would be a differentiating scenario; something that your shop did differently to other shops, and therefore of great interest to the business.

By putting the most interesting ones at the top, it won't matter that the feature file is long. We all know how a cart works for buying and selling items, and we're not reading the scenarios at the bottom by that stage anyway.

Andy Waite is right when he says there are no hard rules, so play it by ear; if it doesn't work, do something differently. Hopefully these hints will help too.

like image 62
Lunivore Avatar answered Nov 12 '22 19:11

Lunivore


You can group features into folders e.g. you might have a folder cart and then feature files for emtpy_cart.feature, update_cart.feature, etc.

There's no hard rules, but personally I wouldn't put more than about 8 scenarios in a single feature file.

Check out Relish's own docs for a great example of how to structure features: https://www.relishapp.com/relish/relish

like image 27
Andy Waite Avatar answered Nov 12 '22 18:11

Andy Waite