How Do I Write Cucumber Tests That Build On Previous Features?

opticyclic :

I have started using Cucumber to write BDD tests to match the business use cases for my application. It is blockchain based so each user in the test is running an instance of the application. This also means that each test is quite heavy and 95% of the test time is in the setup stage.

As I write the tests I am finding that I am starting to repeat myself and the earlier features are seemingly becoming redundant.

One business flow is:

  • User1 saves a new message
  • User2 edits the message
  • User1 verifies the edit
  • User1 cancels the message
  • User2 acknowledges cancellation

This gets broken down into New/Edit/Cancel features.

Initially I started out with "New" and "Edit" feature files looking like this:

New

Feature: a new message is added

  Scenario: a user adds a new message
    Given there is a user called User1
    And there is a user called User2
    When User1 creates a new message with id 1234
    Then User2 should see the message with id 1234

Edit

Feature: Editing a message

  Scenario: A User edits a message
    Given there is a user called User1
    And there is a user called User2
    When User1 creates a new message with id 1234
    And User2 adds the location US to the message
    Then User1 should see the location US on the message

But now I am coming on to the Cancel part I realise that in order to test the Cancel properly, the system needs to have an edited message which means I need to have gone through the New and Edit features to get the message into the right state.

This would make the Cancel look something like this, which then is starting to get quite lengthy:

Cancel

Feature: Cancelling a message

  Scenario: A User cancels a message
    Given there is a user called User1
    And there is a user called User2
    When User1 creates a new message with id 1234
    And User2 adds the location US to the message
    And User1 cancels the message
    Then User2 should see status Cancelled on the message

I could write the Cancel like this instead:

Feature: Cancelling a message

  Scenario: A User cancels a message
    Given there is a message with id 1234
    And User1 cancels the message
    Then User2 should see status Cancelled on the message

which reads quite well as a feature, however, I would now have to write a step definition for "there is a message with id 1234" that does everything that the Edit feature was doing.

As mentioned at the start, the setup in these tests takes 95% of the test time so ideally I would like to run these as a series of steps together rather than starting from fresh for each feature. e.g.

  • Do the setup once
  • Create a New message
  • Edit the message
  • Cancel a message

Is it possible to chain the scenarios or features together and reuse the system state from the previous one?

Or do I have to start the system from scratch each time?

Is a step definition that calls all the other steps/methods that make up the Edit feature the right way to go for the Cancel or should I write lots of And statements?

Greg Burghardt :

I can understand your frustrations with this, but there is no way to have subsequent features build on each other. Each scenario is meant to be atomic and repeatable. The problem with scenarios depending on each other is a failed scenario will cause cascading failures in the scenarios that follow. One failure in the application triggers multiple failed tests, causing your team to start thinking the tests are flakey.

There is nothing wrong with writing a step that simulates the previous scenarios — this is the right way to do it. When defining those steps, keep them as atomic as possible so they are very composable.

To be honest, a 6 step scenario is perfectly fine. The only change I would suggest is making Given versions of your steps. The cancel scenario looks like it has to many When's.

Feature: Cancelling a message

  Scenario: A User cancels a message
    Given there is a user called User1
    And there is a user called User2
    And User1 created a new message with id 1234
    And User2 added the location US to the message
    When User1 cancels the message
    Then User2 should see status Cancelled

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324259&siteId=1