0

The web application I am working on is currently (partially) tested automatically. All scenarios are hardcoded in custom code in this way :

WebElement bt = findButtonWithLabel("foo")
bt.click();
WebElement input = ...
input.sendKeys("...");
// ... do that
// ... verify the text "baz" is present on the page

I want to switch to BDD scenarios with all the benefits that come with it.

First I want to move for this imperative way and write business sentences. So far so good. On small scenarios, it's relatively easy, after discussing with product owner, we found the business words to use. So bye-bye the click there, do that !

Given a manager connected to the application
  And an operation is waiting for approbation
 When the manager refuse the operation
 Then the operation status changes to refused 

Ok good!

But the real use-case is to test a large workflow (a big Camunda BPMN) with lot of states, lot of user interactions, etc.

And I don't know how to write such scenarios.

It seems not a good BDD scenario to write something like that:

Given an operation newly created
  And document "pdf1" is added
  And document "pdf2" is added
 When employee1 do that
 Then operation status is that
 When employee2 do that
  ... 
  (a lot of steps)
  ...
 Then operation status is waiting for approbation
 When the manager accept the operation
 Then the operation status changes to accepted

But testing small part of the workflow is difficult as I can't easily create an operation at a specific state. It requires a lot of data, and I can insert data directly in the database to put create the operation at a given state just for the test.

How should I do?
What is the best practices in such a case?

2
  • Each of your steps in your workflow shouldn't care about the other steps. If they do, that's why it's hard to test. Fix your workflow so that each step can stand on its own, and you will have created a system that's more easily testable. Commented May 21, 2022 at 14:09
  • @RobertHarvey: I agree with what you said, except business dependencies are acceptable between steps. Technical dependencies should be avoided. Commented May 21, 2022 at 14:19

2 Answers 2

2

Sometimes a business operation simply requires a large number of steps. You want to avoid multiple sequences of Given, When followed by Then steps in a single scenario. A "When" for one scenario can be a "Given" for another. Code reuse is not the goal. Communication and specification by example are the goals.

Most BDD frameworks allow you to map a single step definition to multiple types of steps, so you could write one definition that applies to a Given and a When.

When a business process requires many steps, avoid naming things as much as possible. Steps become more focused on the business process without the additional mental overhead of understanding why something was given a certain name.

For example, the step Given document "pdf2" is added requires the name of a PDF file. Unless the name of the file is important to understand the use case, consider rephrasing the step as Given a document is added. If the number of documents is important, but the names and types are not, consider adding a numeric parameter to specify the number of documents: Given 3 documents have been added. Most BDD frameworks will stub out the step definition with an int parameter for the number.

Some additional strategies you can use to reduce the information in a scenario so it focuses on the important details:

  • Omit details from steps that are not important to understand the use case.

  • Organize scenarios into features so the repetitive steps can be grouped into a scenario background. This reduces the number of "Given" steps required for each scenario, but only do this if it increases the understandability of the scenarios.

    Remember that code reuse is a benefit of using a scenario background, not the goal.

1

It's not really a technical problem, it's a "design a system which is understandable" problem.

You would like to be able to describe your system like:

Given the **Thing** is in state **X**
When the user does something
Then the **Thing** is in state **Y**

But this requires that states X and Y are recognised as part of the way the system works. ie there are states where once you are in them the preceding action history is unimportant.

In a complex organically grown system, that just might not be true, there simply is no state X but complex sets of actions which must be completed before "the user does something" should result in the desired result.

I don't think Behaviour Driven Design would encourage inventing "states" that don't exist just to simplify the testing. You can only write tests for the actual desired behaviour and encourage the business to think about changing the functionality to simplify the system.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.