IanWatson IanWatson - 1 month ago 20
Java Question

Cucumber scenario assert condition in DataTable

I have the following scenario in Cucumber-jvm and wondering whats the best way of writing this.

Given I create a process
When I execute the following tasks with parameters:
|Task Name| param1 | param2| param3|
...
Then each task should have outcomes:
|Task Name| outcome1 | outcome2| outcome3|


Whats the best way of approaching this?

I need to execute the When Task1, Then Task1 followed by When Task2 Then Task2 etc due to state information being lost when the next task is started. Instead of invoking all of the When Task1,2,3 first followed by the Then Task1,2,3 first.

There will also be a lot of tasks +50 so splitting this into separate steps is not ideal.

I could merge the When/Then into one step but that doesn't seem right.

Any suggestions?

Answer

How about using a Scenario Outline. This will run each task as a scenario in itself.

To avoid the Given step being repeated you can setup a static boolean variable in your step definition java and check it as a flag.

Scenario Outline:
Given I create a process
When I execute the following task <TaskName> with parameters:
|<Parameter1>|<Parameter2>|<Parameter3>|
Then each task <TaskName> should have outcomes:
|<Outcome1>|<Outcome2>|<Outcome3>|

Examples:
|TaskName|Parameter1|Parameter2|Parameter3|Outcome1|Outcome2|Outcome3|
|task1|t1param1|t1param2|t1param3|t1out1|t1out2|t1out3|
|task2|t2param1|t2param2|t2param3|t2out1|t2out2|t2out3|
.......

In case you have variable number of parameters and outcomes, modify them by using a symbol delimited string. You can use the @Transform annotation in the step definition to get an object of parameters or outcomes.

Scenario Outline:

Given I create a process
When I execute the following task <TaskName> with parameters <parameters>
Then each task <TaskName> should have outcomes <outcomes>

Examples:
| TaskName | Parameters | Outcomes |
| task1 | t1param1,t1param2,t1param3| t1out1,t1out2,t1out3 |
| task2 | t2param1,t2param2,t2param3| t2out1,t2out2,t2out3 |
.......

If there is any dependency of of one task on the outcome of the other task then you have to be careful in how you handle them. You could even add a reset step like, killing current process etc, after your current Then step if required in any of the tasks.


Last scenario ---This is a big hack dependent on the scenario id remaining same. Add the count of scenarios in the example table for the last step as below.

Scenario Outline:

    Given I create a process
    When I execute the following task <TaskName> with parameters <parameters>
    Then each task <TaskName> should have outcomes <outcomes>
    ***And Last step to run for last scenario 3***

    Examples:
    | TaskName | Parameters | Outcomes |
    | task1 | t1param1,t1param2,t1param3| t1out1,t1out2,t1out3 |
    | task2 | t2param1,t2param2,t2param3| t2out1,t2out2,t2out3 |
    | task3 | t3param1,t3param2,t3param3| t3out1,t3out2,t3out3 |


Include in StepDefinition.java

private Scenario scenario;

@Before
public void before(Scenario sce) {
    this.scenario = sce;
    System.out.println("SCENARIO ID -- " +scenario.getId());
}

You will get a string like for scenario outline - **feature-description ; scenariooutline-description ; example-description ; rownumber + 1**. For example -- validating-sample;so1;se1;2. This will be for the first row of the examples table.

For scenario outline case you can split with delimiter ";" and use the last part after subtracting 1. Put this logic in a method getCurrentExamplesRow()

@Then("^Last step to run for last scenario (\\d+)$")
public void lastStep(int size) {

    // Will be called only for last scenario in examples... 
    if(size==getCurrentExamplesRow()) {

    }
}
Comments