Parametrising BDD Tests

As part of my day-to-day, I keep a collection of end-to-end tests which I use to verify the service I'm responsible for. These tests were written as plain Cucumber tests and are more-or-less what you'd expect from most Behaviour Driven Design tests:

For a while this worked reasonably well, but recently I found myself needing to run the same set of tests against a different service. You could imagine that simply doing a search-and-replace from myservice.com to adifferentservice.com would not be sustainable.

Fortunately, there's a way to parametrise these tests so that you can change the hostname without changing the tests themselves.

This technique can be used without adding any steps that imply reading configuration from the environment, thereby keeping the total number of steps down without sacrificing readability. Instead, this technique involves using reflection and Aspect Oriented Programming techniques to "weave" template supports into your step functions, resulting in scenarios that look like this:

Test Config

For this scenario, I will be focusing on tests written for and executed using godog. This is a Go-based BDD testing framework that works a lot like many of the other Cucumber implementations you'll find for other languages. It is worth taking a look at if you are interested in writing tests like these.

The first thing to consider is how parameters like ServiceHost will be made available to the tests. After-all, the values need to be stored somewhere.

One method of doing this is to wrap them all in a struct as publicly accessible fields:

We can read the value of environment variables for each of these fields by using the envconfig package. This can even be used to setup default values so that we don't loose anything from our existing tests after we parametrise them:

Putting this in our InitializeScenario means that we can make this context available to our tests. We'll see how we can do this a little later. For now, know that we have something to read configuration values from the environment.

Function Builders

First thing to note is that there's nothing that needs to be done to the step implementations themselves. If you can imagine the following test setup:

Last updated