Sharing State Between Step Definition Lessons – Grape Up

It’s an apparent truth for anybody who’s been utilizing Cucumber for Java in take a look at automation that steps should be outlined inside a category. Passing take a look at state from one step definition to a different might be simply achieved utilizing occasion variables, however that solely works for elementary and small tasks. In any state of affairs the place writing cucumber situations is a part of a non-trivial software program supply endeavor, Dependency Injection (DI) is the popular (and normally obligatory!) resolution. After studying the article under, you’ll study why that’s the case and how one can implement DI in your Cucumber-JVM exams rapidly.

Preface

Let’s take a look on the following situation written in Gherkin:

If we assume that it’s a part of a small take a look at suite, then its implementation utilizing step definitions inside the Cucumber-JVM framework may seem like this:

Within the instance above, the information is handed between step definitions (strategies) by way of occasion variables. This works as a result of the strategies are in the identical class – PurchaseProcess, since occasion variables are usually accessible solely inside the identical class that declares them.

Downside

The variety of step definitions grows when the variety of Cucumber situations grows. In the end, this forces us to separate our steps into a number of courses – to take care of code readability and maintainability, amongst different causes. Making use of this truism to the earlier instance would possibly lead to one thing like this:

However now we face an issue: the checkPriceInHistory technique moved into the newly created PurchaseHistory class can’t freely entry knowledge saved in occasion variables of its authentic PurchaseProcess class.

Resolution

So how will we go about fixing this pickle? The reply is Dependency Injection (DI) – the really useful method of sharing the state between steps in Cucumber-JVM.

If you happen to’re unfamiliar with this idea, then go by Wikipedia’s definition:

“In software engineeringdependency injection is a design pattern during which an object or function receives different objects or features that it depends upon. A type of inversion of control, dependency injection goals to separate the concerns of developing and utilizing objects, resulting in loosely coupled applications.[1][2][3] The sample ensures that an object or operate which desires to make use of a given service mustn’t need to know how one can assemble these companies. As a substitute, the receiving ‘client‘ (object or operate) is supplied with its dependencies by exterior code (an ‘injector’), which it’s not conscious of.” [1]

Within the context of Cucumber, to make use of dependency injection is to “inject a typical object in every class with steps. An object that’s recreated each time a brand new situation is executed.” [2]

Thus Comes PicoContainer

JVM implementation of Cucumber helps a number of DI modules: PicoContainer, Spring, Guice, OpenEJB, Weld, and Needle. PicoContainer is really useful in case your utility doesn’t already use one other one. [3]

The primary advantages of utilizing PicoContainer over different DI modules steam from it being tiny and easy:

  • It doesn’t require any configuration
  • It doesn’t require your courses to make use of any APIs
  • It solely has a single characteristic – it instantiates objects [4]

Implementation

To make use of PicoContainer with Maven, add the next dependency to your pom.xml:

<dependency>
	<groupId>io.cucumber</groupId>
	<artifactId>cucumber-picocontainer</artifactId>
	<model>7.8.1</model>
	<scope>take a look at</scope>
</dependency>

If utilizing Gradle, add:

compile group: 'io.cucumber', identify: 'cucumber-picocontainer', model: ‚7.8.1’

To your construct.gradle file.

Now let’s return to our instance code. The implementation of DI utilizing PicoContainer is fairly easy. First, we’ve got to create a container class that may maintain the widespread knowledge:

Then we have to add a constructor injection to implement the PurchaseProcess and PurchaseHistory courses. This boils right down to the next:

  • making a reference variable of the Container class within the present step courses
  • initializing the reference variable by way of a constructor

As soon as the modifications above are utilized, the instance ought to seem like this:

Conclusion

PicoContainer is light-weight and simple to implement. It additionally requires minimal modifications to your current code, serving to to maintain it lean and readable. These qualities make it an ideal match for any Cucumber-JVM undertaking since sharing take a look at context between courses is a query of ‘when’ and never ‘if’ in basically any take a look at suite that may develop past a couple of situations.

  1. Dependency injection – Wikipedia
  2. Sharing state between steps in Cucumber-JVM using PicoContainer (thinkcode.se)
  3. State – Cucumber Documentation
  4. How to Use Polymorphic Step Definitions | Cucumber Blog
  5. Maven Repository: io.cucumber » cucumber-picocontainer (mvnrepository.com)