In recent months, I have encountered more and more Testers wishing to become involved in Unit Testing, learning techniques such as TDD (Test Driven Development) and BDD (Behaviour Driven Development), and utilising tools such as Selenium and Cucumber.
"We need to learn Ruby and Cucumber"
Enthusiasm aside, many testers I have spoken with are responding to industry buzzwords and aren’t familiar enough with these tools and techniques to understand where they, as testers, fit in.
So while there may be an increasing requirement for technical testing capability, I would like to use this article to dispel the myth that all testers must be technical, share my opinions and provide a high level overview, starting with an explanation of some of these terms…
Unit Testing and TDD
Unit Testing is a method by which very granular units of code are tested in isolation from their dependencies (such as integrated applications, databases and file systems) to determine that they are fit for purpose. Although I have heard reference to manual unit testing (?), in practice, good Unit Tests are automated with a small fragment of code used to assert an expected outcome.
Test Driven Development (TDD) is the practice of writing a small automated Unit Test which initially fails, then writing the simplest and smallest amount of application code required to pass the test before refactoring and improving the quality of the code.
With tests being written before the application code, TDD (also sometimes referred to as test-first development) really drives the quality of the product by keeping the software development team focused on writing simple, testable code.
Since Unit Tests focus on the internals of the software, and are themselves written in code, they can be difficult to understand by stakeholders outside the development team. As such, there is often unease about the level of code coverage or the quality of the Unit Testing performed before System and Integration Testing can begin.
Due to the required knowledge of the underlying architecture and implementation, and the quick iteration between test and application code, these responsibilities don’t belong to testers, but to the application programmers (I’m purposely avoiding the term Developer to avoid the ambiguity of Scrum teams, where all team members are labelled Developers).
BDD
Behaviour Driven Development (BDD) is based upon Test Driven Development, but where TDD focuses on the inner workings of the software and the accuracy of the code (Unit Tests), BDD focuses on the requirements and the business value of the software (Acceptance Tests).
Acceptance Tests are often modelled around User Stories (“As a [role] I want [feature] so that [benefit]”) and Acceptance Criteria. Being written in natural language makes Acceptance Tests more easily understood by stakeholders outside of the software development team, such as BAs, Testers and Project Managers.
-
TDD
Did we build the
system right?
-
BDD
Did we build the
right system?
It is important to note that BDD is more than just an approach to testing; it is about unambiguously specifying functionality and desired behaviour of the software (Business Requirements) in simple and testable terms – these specifications are called Features.
So, let’s take a look at the tools and how they are used.
Cucumber and Gherkin
Cucumber is a tool for writing and running Acceptance Tests as BDD features. Cucumber was originally developed in Ruby, but now supports a number of programming languages and over 40 spoken languages.
Cucumber was neither the first tool to assist with BDD, nor is it the only tool available; however, it’s syntax for specifying features (known as Gherkin) is arguably becoming the De facto standard, and has been adopted by a number of other BDD tools.
Although the implementation of the test code requires programming, the Gherkin syntax for specifying Acceptance Tests is natural language, which means that the tests can be written, read and understood by any stakeholder, and this is where testers are expected to contribute.
When specifying desired behaviour in feature files, the thing which really helps to avoid ambiguity is the language used to document the Acceptance Tests; these are called Scenarios and they are written in a “Given, When, Then” format.
-
GIVEN
The context or
pre-requisite
-
-
THEN
The expected
outcome
An example feature file is shown below documenting a couple of Acceptance Tests for an ATM withdrawal.
Feature: Account Holder withdraws cash
As an Account Holder
I want to withdraw cash from an ATM
So that I can get money when the bank is closed
Scenario: Account has sufficient funds
Given the account balance is $100
And the card is valid
And the machine contains enough money
When the Account Holder requests $20 dollars
Then the ATM should dispense $20 dollars
And the account balance should be $80 dollars
And the card should be returned
Scenario: Account has insufficient funds
Given the account balance is $10
And the card is valid
And the machine contains enough money
When the Account Holder requests $20
Then the ATM should not dispense any money
And the ATM should say there are insufficient funds
And the account balance should be $10
And the card should be returned
Within a feature file, the steps within each of the scenarios are associated with snippets of code called Step Definitions, which implement the automated test.
Many of our technical testers work within Development Teams, writing Object Oriented test code in Java and Ruby, but these technical skills were honed over many years, and this technical career path isn’t essential or viable for all testers.
Summary
Some Agile advocates argue that all members of software delivery teams should be programmers and share technical skills, and I feel that sentences like the one below, which was taken from the Scrum guide, don’t help with this perception:
Scrum recognises no titles for Development Team members other than Developer…
In reality, testers working in Agile teams can still use some of the modern tools and techniques such as BDD and Cucumber, and they don’t have to learn programming languages or implement automated tests to be useful, but maybe that’s just my opinion – what do you think?