A common implementation of BDD used by those creating web applications is the combination of Cucumber and WebDriver. Cucumber provides the Gherkin language, whose natural language syntax provides non-technical team members with the means to describe interactions and acceptance criteria. Cucumber then exposes these Gherkin commands as an extensible interface that in turn is used to automate a web browser via WebDriver.
A lot of people I speak to talk of Cucumber as a solution to their testing requirements. So when I was tasked with implementing Cucumber (under the assumption that I was also implementing BDD), I was surprised to find that there was no singularly popular Gherkin language I could replicate.
What I expected to find was an existing and accepted Gherkin language for interacting with a web page. While the fluent syntax of Gherkin makes it easy to describe interactions in terms of “When I click the button” or “When I open the web page." there are a lot of subtleties to these interactions that you will quickly run into when scripting the interactions with a real world web page. What happens if the element is optional (think A/B testing)? How do I identify elements that don’t have a nice ID or class type? How do you most eloquently describe the selection the third last element from a list of options?
I quickly found that there was no generally accepted Gherkin dialect for interacting with a web page. The documentation for Gherkin, and most tools that implement it, focus on how you would write your own dialect rather than trying to dictate what it should look like. Which is understandable given the broad scope of Cucumber and Gherkin, but still came as something of a surprise. Surely I’m not the only one trying to describe these kinds of web based interactions?
Introducing Modelling by Example articulated my dilemma better than most and cleared up a lot of confusion around the distinction between BDD and integration testing. The sorts of interactions I was asking Cucumber to perform were about the mechanics of using a web page, which is more about integration testing than BDD. BDD should be at a higher level again, describing processes in terms of business entities like “shopping baskets” or “product recommendations," and not at all concerning itself with element IDs or the position of items in a selection list.
The mistake I made was thinking about BDD in terms of how I as a developer would implement the feature. It was hard to see the distinction between “shopping basket” and “DIV with id of shopping_basket," because the two were the same thing in my mind, which meant that BDD and integration testing where much the same thing as well.
Ironically, there is no test that provides a concrete distinction between unit testing, integration testing, acceptance testing and BDD. They all exist on the same continium with blured lines between one and the next. But the easiest way I can describe BDD to myself is that it is the explanation of a process that I would give to a 5-year-old. This is not to say that BDD is childish, but that it should be at a high enough level conceptually that you don’t need a computer science degree to make the connection between “I click on the div with the ID of shopping_basket” and “I open my shopping basket."
If your tests leak the details of the underlying technologies being used, you are mostly likely writting an integration test. If you want to do BDD, then your tests should able able to result in three different and perfectly valid solutions, should you ask a desktop developer, web developer, or mobile developer to implement them.