Sharing state between scenarios

Don’t do it.

Scenarios must be independent from each other so it is important that state is not shared between scenarios. Accidentally leaking state from one scenario into others makes your scenarios brittle and also difficult to run in isolation.

To prevent accidentally leaking state between scenarios:

  • Avoid using global or static variables.
  • Make sure you clean your database in a Before hook.
  • If you share a browser between scenarios, delete cookies in a Before hook.

Sharing state between steps

Within your scenarios, you might want to share state between steps.

It’s possible to store state in variables inside your step definitions.

Be careful with state

State can make your steps more tightly coupled and harder to reuse.

Dependency Injection

PicoContainer

Spring

Guice

OpenEJB

Weld

Needle

How to use DI

Using a custom injector

The Cucumber object factory

Using the Cucumber object factory from the command line

Using the Cucumber object factory a property file

Using the Cucumber object factory with a test runner (JUnit 5/JUnit 4/TestNG)

The Event Bus

Configuring the UUID generator

Defining your own UUID generator

Databases

There are several options to remove state from your database, to prevent leaking state between scenarios.

The Before Hook Approach

The recommended approach to clean a database between scenarios is to use a Before hook to remove all data before a scenario starts. This is usually better than using an After hook, as it allows you to perform a post-mortem inspection of the database if a scenario fails.

An alternative approach is to use database transactions.

The Database Transaction Approach

If your database supports it, you can wrap a transaction around each scenario.

This might lead to faster scenarios, but it comes at a cost. You won’t be able to perform a post-mortem, and you won’t be able to use browser automation.

To use this approach, you need to tell Cucumber to start a transaction in a Beforehook, and later roll it back in an Afterhook.

This is such a common thing to do that several Cucumber extensions provide ready-to-use conditional hooks using a tag named @txn.

To enable it, you must tag every feature or scenario that requires transactions with @txn:

@txn
Feature: Let's write a lot of stuff to the DB

  Scenario: I clean up after myself
    Given I write to the DB

  Scenario: And so do I!
    Given I write to the DB

With JUnit 5 and Spring

Browser Automation and Transactions

If you’re using a browser automation tool that talks to your application over HTTP, the transactional approach will not work if your step definitions and the web application serving HTTP request each have their own database connection. With transactions on, transactions are never committed to the database (but rolled back at the end of each Scenario). Therefore, the web server’s connection will never see data from Cucumber, and therefore your browser won’t either. Likewise, Cucumber’s connection won’t see data from the web server.

In this case, you will have to turn off database transactions and make sure the test data is explicitly deleted before each Scenario.

Turn off transactions

Cleaning Your Database

You can help us improve this documentation. Edit this page.