Declarative BDD with Golang

Spiros Economakis
lenses.io
Published in
3 min readFeb 26, 2021

--

The Cloud team in Lenses.io uses Golang for the Lenses.io Cloud and we adopted BDD in our testing and in this article we will try to show how we can implement a simplistic BDD with Golang.

Behavioral Driven Development

In software engineering, behavior-driven development (BDD) is a software development process that emerged from test-driven development (TDD).

Given-When-Then is a style of representing tests specifying system’s behavior using a SpecificationByExample. Gerard Meszaros describes this pattern as the Four-Phase test which includes the followings:

  • Setup (Given)
  • Exercise (When)
  • Verify (Then)
  • TearDown

The above is simplified a bit more with the formulation as:

  • Arrange
  • Act
  • Assert

There are couple of frameworks out there for Golang to adopt BDD in your testing, like GoDog, Ginkgo and probably more than these two. We don’want to review these two popular frameworks in this article but overall you need to learn their style, spend time to write regular expressions or use nested functions to achieve the BDD style approach.

We love Golang for many reasons and one of them is the simplicity of the language. In this article we will try to present how we can adopt BDD without the need of an extra framework/dependency in the codebase.

Showcase

The scenario will be a real case by the Lenses Cloud codebase where we test a piece of code about generating the Leads of the platform to our internal CRM.

Firstly let’s define the feature file:

Feature: CRM Integration
A new AWS deployment updates CRM succesfully

Scenario: Deploy in AWS with success and update CRM
Given I am a lead
When I am deploying to AWS
Then it should return no error

Scenario: Deploy in AWS with success but CRM update failed
Given I am a lead
When I deploy to AWS successfully
Then it should return an error

In Lenses.io Cloud we use Testify and more specifically the Suite feature because we can create setup/teardown methods on our testing suites, which will run before/after the whole suite or individual tests.

So let’s see the first scenario and how it can be achieved written in Golang with the Testify Suite.

First we need to Setup our test suite. We initialize the necessary component dependencies like the piece of code shows below:

So let’s see how we can approach the first scenario Deploy in AWS with success and update CRM . In our codebase we need to represent with a declarative way the followings:

  • Actor
  • Given, When, Then

Actor

In our scenario we have a lead but to instrument a lead in our test case we need to have some actions first, so in our case we assume an anonymous user and this is how it can be represented in Golang:

In practice we return the suite struct so we can be able later to add more given actions to our test case.

Given, When, Then

As now we have the actor let’s see how we can instrument a lead who signs up in Lenses.io Cloud:

As every function is part of the suite Struct we can simple instrument our test case as:

s.asAnonymousUser().signup()

And we can do the same if we want to this for more than one action in Given for example:

s.asAnonymousUser().signup().and().deployLensesAWS()

Where the and() function is nothing more than returning the current suite struct back:

So with this approach we have a very clean, readable and declarative way to write a BDD test suite only with Golang and without any framework.

Arrange, Act, Assert

Let’s see the full code for Deploy in AWS with success and update CRM feature:

The same approach can be followed for the other test case Deploy in AWS with success but CRM update failed . Let’s see how we can instrument an error test case:

Conclusion

BDD may it is not suitable for every kind of application but it gives you the power and the ability to solve some complex business problem and document every feature in your application with a declarative and readable manner.

Imagine that with this way the Product Owner or every Business person can read the code or the feature file and understand what to expect for a feature implementation for different test cases and user journeys.

--

--

Spiros Economakis
lenses.io

Director of ProductOps @mattermost, Author of “Argo CD in practice” book