How to organize the specs definition in Cucumber?
Asked Answered
H

3

16

We are considering to use Cucumber on our project for acceptance testing.

When we write a scenario in a Cucumber feature, we write a list of Given, When and Then statements.

As we use cucumber-jvm project, the Given, When and Then statement are related to Java methods in (JUnit) classes.

I want to know what is the best organization for the code related to Given / When / Then in the project structure. My main concern is the maintenance of the cucumber tests on a big project, where the number of scenario is quite important, and especially regarding the items that are shared between features.

I can see at least 2 main approaches:

  1. Each feature is related to it's own JUnit class. So if I have a foo/bar/baz.feature cucumber file, I will find the releated foo.bar.Baz JUnit class with the adequate @Given, @When and @Then annotated methods.

  2. Separate @Given, @When and @Then methods into "thematic" classes and packages. For example, if in my cucumber scenario I have a statement Given user "foo" is logged, then the @Given("^user \"([^\"]*)\" is logged$") annotated method will be located in the foo.user.User class method, but potentially, the @When method used later in the same cucumber scenario will be in a different Java class and package (let say foo.car.RentCar).

For me, the first approach seems good in the way that I can easily do the relation between my cucumber features and my Java code. But the drawback is that I can have a lot of redundancies or code duplication. Also, it may be hard to find a possible existing @Given method, to avoid to recreate it (the IDE can help, but here we are using Eclipse, and it does not seem to give a list of existing Given statement?).

The other approach seems better essentially when you have Given conditions shared among several cucumber feature, and thus I want to avoid code duplication. The drawback here is that it can be hard to make the link between the @Given Java method and the Given cucumber statement (maybe, again, the IDE can help?).

I'm quite new to cucumber, so maybe that my question is not a good question, and with time and experience, the structure will be self-evident, but I want to get good feedbacks on its usage...

Thanks.

Henleigh answered 17/10, 2012 at 9:33 Comment(1)
Note that I don't think it's a duplicate of this question: #5023628Henleigh
F
2

I would suggest grouping your code according to the objects it refers to, similar to option #2 you presented in your question. The reasons being:

  • Structuring your code based on how and where it's being used is a big no-no. It's actually creating coupling between your feature files and your code.
    Imagine such a thing in your product's code- the SendEmail() function wouldn't be in a class called NewEmailScreenCommands, would it? It would be in EmailActions or some such.
    So the same applies here; structure your code according to what it does, and not who uses it.

  • The first approach would make it difficult to re-organize your feature files; You'd have to change your code files whenever you change your feature files.

  • Keeping code grouped by theme makes DRYing it much easier; you know exactly where all the code dealing with the user entity is, so it's easier for you to reuse it.

On our project we use that approach (i.e BlogPostStepDefinitions class), with further separating the code, if the class gets too large, to types of steps (i.e BlogPostGivenStepDefinitions).

Femineity answered 6/3, 2014 at 13:42 Comment(0)
A
1

We have also started using Cucumber-JVM for acceptance testing and have similar problems with organising code. We have opted to have 1 step definition class for each feature. At the moment this is fine as the features we are testing aren't very complex and quite separate, there is very little overlap in our features.

The second approach you mentioned would be better I think, but it is often challenging to tie together several different step definition classes for a single scenario. I think the best project structure will become clearer once you start adding more features and refactor as normal.

In the meantime here is an Eclipse plugin for cucumber,

https://github.com/matthewpietal/Eclipse-Plugin-for-Cucumber

it has syntax highlighting as well as a list of existing available steps when writing a feature.

Ameliorate answered 18/10, 2012 at 10:9 Comment(2)
Thanks. I'm already using the Eclipse plugin, but not really satisfied by it yet (but it can be improved, of course)Henleigh
Would you have the option of switching to IntelliJ (there's a free community edition); it's very helpful in suggesting existing StepDefinitions.Disconcerted
M
0

On the current project I am taking part in, we asked ourselves the very same question.

After fiddling a bit with the possibilities, what we opted for was a mix of both the solutions you exposed.

  • Have steps regrouped in theme-centric common steps classes
    • app-start steps
    • security check steps
    • [place random feature concern here] steps
  • And classes of scenario (and in some case even feature) specific steps

This was to have at the same time the grouping of factorized code which is pretty easily identifiable on it's whatabouts, whereabouts and whatnot. Yet it allows not to clutter those common classes with overly specific code.

The wiring between all these classes is handled by spring (with cucumber spring which does a great job once you get the hang of it).

Multifaceted answered 10/9, 2015 at 9:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.