Specification by Example and BDD
Leading a software development project to success is never straightforward. It is a complex process and there are various elements that need to be considered. A requirements specification actually functions as the 'glue' to hold together many of those elements in the process.
At Deeson, we capture the requirements of a feature using the approach of specification by example.
Specification by Example is an excellent book written by Gojko, which defines the ideal software development process. The author offers practical solutions to capturing requirements and writing specifications that it makes it easy to turn them into test scripts and living documentation.
This post is essentially about behaviour-driven development (BDD), but has less focus on the automated testing aspect. Rather, it describes how BDD can improve the software development process as a whole.
Classic issues caused by poorly written specifications and how it can affect agencies
In the context of web application development, applications are usually built for organisations to solve their problems and achieve business goals.
For developers to be able to deliver features that precisely meet the requirements, they must be correctly and adequately captured in specifications.
This however, is not an easy task and developer teams often end up working based on specifications that are poorly written and known to cause issues such as:
- Inaccurate estimations.
- Rework due to misunderstanding of requirements.
- Missed deadlines.
- Over budget.
For an agency, such problems aren't contained within a single project or team, because delays in one project impact on other work, due to resource shortages. This can create further issues such as:
- Developer burnout due to overworking under pressure to meet the deadlines.
- Unhappy clients as a result of degradation of quality, as well as because the application is not built on time.
While adopting an agile project management methodology could mitigate some of these issues, it won't change the fact that poorly written specifications disappoint clients at the time of user acceptance testing (UAT).
How Specification by Example helps solve the issue
Gojko explains how requirements should be documented and maintained throughout a software development project.
Deciding on the scope
The book recommends capturing requirements by first identifying business goals, then deriving scopes out of them. Adzic is the author of another excellent (and short) book Impact Mapping and recommends adopting the technique for this phase.
At Deeson, we use Blueprint, our tested-and-proven approach that happens to be very similar to Impact Mapping.
The important thing to remember in this discovery phase, is that regardless of how strongly stakeholders feel about implementing a certain new feature, it should not be built if it doesn't help achieve their business goals. Approaches like Blueprint and Impact Mapping help the customer stay focused on their business goals and spend less time discussing features that don't deliver any value.
Using examples to illustrate requirements
Writing good specifications is difficult. They are often vague and open to individual interpretation, resulting in client disappointment at UAT. Or they can be too specific and technical so only developers can understand (and the project still fails to fulfil requirements).
When documenting specifications, examples are powerful tools for documenting requirements clearly and concisely. One of our clients asked for a feature that shows a published/last updated date to each post in the search results on their new Drupal site and the specifications looked like this:
User story:
"As a visitor, I want to see when a page of content was last updated or reviewed so that I can judge if the content is up to date"
Acceptance criteria:
- "On all content types"
- "When an Editor reviews or amends a page they have the option to set the current date or any date as the 'Updated or reviewed' date"
While this looks acceptable, there are still some unanswered questions. The story seems to imply that, from a developer's perspective, one field is used for recording the updated date, and another for recording the last updated dates. But how would it work if both fields have values? Also, is the value in Drupal's default 'published date' field used at all?
We discussed the requirements with the client in detail and although the rules turned out to be rather complex, we managed to distill the requirements into a set of examples within a chart.
Below is an excerpt from an updated acceptance criteria:
Content type | Published date | Default 'updated' field | Custom 'reviewed' field | Display |
Blog | Present | Present | (N/A) | Published date |
Publication | Present | Present | Present | Custom reviewed date |
Standard | Present | Present | Present | Custom updated date |
Standard | Present | Present | Absent | Default updated date |
This makes it easier for both the client and our developers to understand what date value should be displayed under which condition.
It is important to note that an 'example' doesn't mean a step-by-step definition of how a user interacts with the UI to achieve a goal. Workflows involving details of the UI can change over time and as a result, the specification can become obsolete as soon as a small change is introduced to the UI, while the core feature has not gone through any changes.
Taking examples to a next step – automated testing and living documentation:
The true power of writing specifications as examples is that they can be turned into executable tests, which is virtually a ‘living’ documentation.
Those who are familiar with behaviour-driven development (BDD) may recognise some similarities between the above table and scenario outlines. I can tell you that it is not a coincidence.
For those who are not familiar with BDD, here is a description from Wikipedia: ‘Behavior-driven development is an extension of test-driven development: development that makes use of a simple, domain-specific scripting language’. In short, a BDD framework allows you to convert your specifications into automated test scripts with relatively little effort.
The execution of tests can be automatically triggered when a certain event happens (eg at the time of merge/build), or manually by developers whenever they want, in order to detect breakages and regressions before they are introduced to the production environment.
Writing and maintaining tests may seem expensive and deciding on the test coverage can be tricky. However, if you consider the losses caused by bugs disabling key features (as well as fixing them), having automated tests can be cost-effective, especially for projects that are expected to run over the course of few years (which many web application projects tend to do or end up doing).
The tests should be executed on every build and if any one of them fails, it means either the application is broken or the test is outdated. You then have to fix the broken code or make changes to the test scripts ( = human-readable specifications) accordingly, to ensure that they correctly reflect how the application behaves. The result is completely up-to-date documentation.
In my career as a web developer, I have been asked to maintain web applications that were built by another agency and I often have no idea what the site’s features were supposed to do.
Their code often lacks comments and the brief documentation in README.txt is insufficient or outdated. I often fix things or add new features without knowing exactly how key features worked. The true value of living documentation would be appreciated in this situation.
In summary
Specification by Example is not about installing a testing framework and starting to write some test scripts. It is about reviewing the whole software development process, ie improving communication with your client, taking them through effective discovery processes, capturing requirements adequately to build deliverables that have a great impact on their business. It is also about keeping maintenance overheads manageable through regression testing and living documentation.
At Deeson, we have come to value the worth of well-defined specifications written collaboratively with the client, using this approach. It provides clarity on a project by allowing a common language for the business owners, designers and developers.