Here’s a question about BDD (behavior-driven development) that I thought I would share with you:
Where does BDD fit in the testing pyramid? I see BDD as unit tests since unit tests verify the domain behavior (classical school). If so, would you limit at all what amount of the units tests are done with BDD/Gherkin?
This is a very interesting question because it touches upon the bigger topic of writing valuable unit tests. I’ll split it in 2 topics: BDD itself and the Gherkin language.
1. BDD
If you look at the Test Pyramid, where would you put tests written in the BDD style?
Most people would put them into integration or end-to-end category. This is understandable, but incorrect.
The reason why BDD-style tests are often equated with integration tests is because we are used to using our unit tests for verifying the code’s low-level implementation details, not its behavior. If you’ve read my book about unit testing, you might remember that this is one the biggest anti-patterns in unit testing, and I railed against it pretty much throughout the whole book.
In reality, verifying your system’s behavior is what all tests should do, regardless of their placement in the test pyramid. It’s just they should do it at different levels of granularity.
In my opinion, BDD is an attempt to go back to basics — apply the old, common-sense principles to automated testing under the new branding.
In that sense, BDD similar to Microservices. We already had a similar discipline under the name of SOA, but it got bloated with anti-patterns and bad practices. Microservices architecture emerged as a simplified alternative to SOA that focused on its good parts and explicitly called out the bad ones.
Overall, BDD is unit testing done right. Always write your tests such that they verify the end result from the perspective of the client, without paying attention to how exactly that end result is achieved. In other words, target the observable behavior, not implementation details.
2. Gherkin language
Regarding whether or not I used Gherkin — I don’t anymore, though I used to in the past.
Gherkin is an interesting way to bring DSL to the world of testing. Here how this DSL typically looks:
Feature: Assigning an Employee a Project In order to distribute projects among employees As a manager I want to assign an employee a project So that all projects are finished in time Scenario: Assign an employee a project Given I have an employee And I have a project When I assign the employee to the project as a 'Developer' Then the employee becomes a 'Developer' on that project
Each scenario in Gherkin represents a test case, which itself is split into Given/When/Then sections. Each line in the sections gets translated into arrange/act/assertion code behind the scenes, so in the end we get executable documentation.
The word executable is key here because it means that such specifications never get out of date, like most other documentation. This is a great way to bring developers and analysts/stakeholders together because both groups can refer to the same documentation.
This is a very readable way to describe a feature and its related scenarios. The overall idea is great in theory.
In practice, though, no one reads these scenarios aside from the people who write them — developers. And so the whole idea with the separate DSL becomes a waste of time. You can achieve pretty much the same level of readability (at least for fellow programmers) with regular code, which takes much less time to implement.
Here’s how the same test can be represented in plain C# (this is an end-to-end test, hence the reference to window objects):
[Fact] public void Assigning_an_employee_a_project() { ProjectCreator.Create(); EmployeeCreator.Create(); Windows.Main.OpenCreatedEmployee(); Windows.Employee .AssignToCreatedProjectAs(RoleInProject.Developer) .Save(); Windows.Main.OpenCreatedProject(); Windows.Project .IsCreatedEmployeeAssignedAs(RoleInProject.Developer) .Should().BeTrue(); }
--Vlad
Enjoy this message? Here are more things you might like:
Workshops — I offer a 2-day workshop for organizations on Domain-Driven Design and Unit Testing. Reply to this email to discuss.
Unit Testing Principles, Patterns and Practices — A book for people who already have some experience with unit testing and want to bring their skills to the next level.
Learn more »
My Pluralsight courses — The topics include Unit Testing, Domain-Driven Design, and more.
Learn more »