Behavior-driven development

Last updated

Behavior-driven development (BDD) involves naming software tests using domain language to describe the behavior of the code.

Contents

BDD involves use of a domain-specific language (DSL) using natural-language constructs (e.g., English-like sentences) that can express the behavior and the expected outcomes.

Proponents claim it encourages collaboration among developers, quality assurance experts, and customer representatives in a software project. [1] [2] [3] It encourages teams to use conversation and concrete examples to formalize a shared understanding of how the application should behave. [4] BDD is considered an effective practice especially when the problem space is complex. [5]

BDD is considered a refinement of test-driven development (TDD). [1] [2] [6] [7] [ vague ] [8] [9] BDD combines the techniques of TDD with ideas from domain-driven design and object-oriented analysis and design to provide software development and management teams with shared tools and a shared process to collaborate on software development. [2] [8]

At a high level, BDD is an idea about how software development should be managed by both business interests and technical insight. Its practice involves use of specialized tools. [6] Some tools specifically for BDD can be used for TDD. The tools automate the ubiquitous language.

Overview

BDD is a process by which DSL structured natural language statements are converted to executable tests. The result are tests that read like acceptance criteria for a given function.

As such BDD is an extension of TDD.

BDD focuses on:

At its heart, BDD is about rethinking the approach to automated testing (including unit testing and acceptance testing) in order to avoid issues that naturally arise. For example, BDD suggests that unit test names be whole sentences starting with a conditional verb ("should" in English for example) and should be written in order of business value. Acceptance tests should be written using the standard agile framework of a user story: "Being a [role/actor/stakeholder] I want a [feature/capability] yielding a [benefit]". Acceptance criteria should be written in terms of scenarios and implemented in classes: Given [initial context], when [event occurs], then [ensure some outcomes] .

Starting from this point, many people developed BDD frameworks over a period of years, finally framing it in terms of a communication and collaboration framework for developers, QA and non-technical or business participants in a software project. [10] During the "Agile specifications, BDD and Testing eXchange" in November 2009 in London, Dan North [11] gave the following description of BDD:

BDD is a second-generation, outside-in, pull-based, multiple-stakeholder, multiple-scale, high-automation, agile methodology. It describes a cycle of interactions with well-defined outputs, resulting in the delivery of working, tested software that matters.

History

During an interview with Dan North at GOTO Conference in 2013, Liz Keogh [12] defined BDD as:

It's using examples to talk through how an application behaves... And having conversations about those examples. [13]

Dan North created a BDD framework, JBehave, followed by a story-level BDD framework for Ruby called RBehave [14] which was later integrated into the RSpec project. [15] He also worked with David Chelimsky, Aslak Hellesøy and others to develop RSpec and also to write "The RSpec Book: Behaviour Driven Development with RSpec, Cucumber, and Friends". The first story-based framework in RSpec was later replaced by Cucumber mainly developed by Aslak Hellesøy. Capybara, which is a part of the Cucumber testing framework is one such web-based test automation software.

Principles

BDD suggests that software tests should be named in terms of desired behavior. [6] [8] [1] Borrowing from agile software development the "desired behavior" in this case consists of the requirements set by the business that is, the desired behavior that has business value for whatever entity commissioned the software unit under construction. [6] [1] Within BDD practice, this is referred to as BDD being an "outside-in" activity. [16]

TDD does not differentiate tests in terms of high-level software requirements, low-level technical details or anything in between. One way of looking at BDD therefore, is that it is an evolution of TDD which makes more specific choices.

Behavioral specifications

Another BDD suggestion relates to how the desired behavior should be specified. BDD suggests using a semi-formal format for behavioral specification which is borrowed from user story specifications from the field of object-oriented analysis and design. The scenario aspect of this format may be regarded as an application of Hoare logic to behavioral specification of software using the domain-specific language.

BDD suggests that business analysts and software developers should collaborate in this area and should specify behavior in terms of user stories, which are each explicitly documented. [1] [16] Each user story should, to some extent, follow the structure: [6] [16]

Title
An explicit title.
Narrative
A short introductory section with the following structure:
  • As a: the person or role who will benefit from the feature;
  • I want: the feature;
  • so that: the benefit or value of the feature.
Acceptance criteria
A description of each specific scenario of the narrative with the following structure:
  • Given: the initial context at the beginning of the scenario, in one or more clauses;
  • When: the event that triggers the scenario;
  • Then: the expected outcome, in one or more clauses.

BDD does not require how this information is formatted, but it does suggest that a team should decide on a relatively simple, standardized format with the above elements. [6] [16] In 2007, Dan North suggested a template for a textual format which is used in multiple BDD tools. [16] For example:

Title: Returns and exchanges go to inventory.  As a store owner, I want to add items back to inventory when they are returned or exchanged, so that I can sell them again.  Scenario 1: Items returned for refund should be added to inventory. Given that a customer previously bought a black sweater from me and I have three black sweaters in inventory, when they return the black sweater for a refund, then I should have four black sweaters in inventory.  Scenario 2: Exchanged items should be returned to inventory. Given that a customer previously bought a blue garment from me and I have two blue garments in inventory and three black garments in inventory, when they exchange the blue garment for a black garment, then I should have three blue garments in inventory and two black garments in inventory.

BDD suggested that the scenarios should be phrased declaratively rather than imperatively — in the business language, with no reference to elements of the UI through which the interactions take place. [17]

This format is referred to as the Gherkin language. The term Gherkin, however, is specific to the Cucumber, JBehave, Lettuce, [18] behave and Behat software tools. [19] [20] [21] [22]

Specification as a ubiquitous language

BDD borrows the concept of the ubiquitous language from domain driven design. [6] [8] A ubiquitous language is a (semi-)formal language that is shared by all members of a software development team both software developers and non-technical personnel. [23] The language in question is both used and developed by all team members as a common means of discussing the domain of the software in question. [23] In this way BDD becomes a vehicle for communication between all the different roles in a software project. [6] [24]

A common risk with software development includes communication breakdowns between Developers and Business Stakeholders. [25] BDD uses the specification of desired behavior as a ubiquitous language for the project Team members. This is the reason that BDD insists on a semi-formal language for behavioral specification: some formality is a requirement for being a ubiquitous language. [6] In addition, having such a ubiquitous language creates a domain model of specifications, so that specifications may be reasoned about formally. [26] This model is also the basis for the different BDD-supporting software tools that are available.

The example given above establishes a user story for a software system under development. This user story identifies a stakeholder, a business effect and a business value. It also describes several scenarios, each with a precondition, trigger and expected outcome. Each of these parts is exactly identified by the more formal part of the language (the term Given might be considered a keyword, for example) and may therefore be processed in some way by a tool that understands the formal parts of the ubiquitous language.

Most BDD applications use text-based DSLs and specification approaches. However, graphical modeling of integration scenarios has also been applied successfully in practice, e.g., for testing purposes. [27]

Specialized tooling

Much like TDD, BDD may involve using specialized tooling.

BDD requires not only test code as does TDD, but also a document that describes behavior in a more human-readable language. This requires a two-step process for executing the tests, reading and parsing the descriptions, and reading the test code and finding the corresponding test implementation to execute. This process makes BDD more laborious for developers. Proponents suggest that due to its human-readable nature the value of those documents extends to a relatively non-technical audience, and can hence serve as a communication means for describing requirements ("features").

Tooling principles

In principle, a BDD support tool is a testing framework for software, much like the tools that support TDD. However, where TDD tools tend to be quite free-format in what is allowed for specifying tests, BDD tools are linked to the definition of the ubiquitous language.

The ubiquitous language allows business analysts to document behavioral requirements in a way that will also be understood by developers. The principle of BDD support tooling is to make these same requirements documents directly executable as a collection of tests. If this cannot be achieved because of reasons related to the technical tool that enables the execution of the specifications, then either the style of writing the behavioral requirements must be altered or the tool must be changed. [28] The exact implementation of behavioral requirements varies per tool, but agile practice has come up with the following general process:

Dan North has developed a number of frameworks that support BDD (including JBehave and RBehave), whose operation is based on the template that he suggested for recording user stories. [6] These tools use a textual description for use cases and several other tools (such as CBehave) have followed suit. However, this format is not required and so there are other tools that use other formats as well. For example, Fitnesse (which is built around decision tables), has also been used to roll out BDD. [29]

Tooling examples

There are several different examples of BDD software tools in use in projects today, for different platforms and programming languages.

Possibly the most well-known is JBehave, which was developed by Dan North, Elizabeth Keogh and several others. [30] The following is an example taken from that project: [20]

Consider an implementation of the Game of Life. A domain expert (or business analyst) might want to specify what should happen when someone is setting up a starting configuration of the game grid. To do this, he might want to give an example of a number of steps taken by a person who is toggling cells. Skipping over the narrative part, he might do this by writing up the following scenario into a plain text document (which is the type of input document that JBehave reads):

Given a 5 by 5 game When I toggle the cell at (3, 2) Then the grid should look like ..... ..... ..... ..X.. ..... When I toggle the cell at (3, 1) Then the grid should look like ..... ..... ..... ..X.. ..X.. When I toggle the cell at (3, 2) Then the grid should look like ..... ..... ..... ..... ..X..

The bold print is not part of the input; it is included here to show which words are recognized as formal language. JBehave recognizes the terms Given (as a precondition which defines the start of a scenario), When (as an event trigger) and Then (as a postcondition which must be verified as the outcome of the action that follows the trigger). Based on this, JBehave is capable of reading the text file containing the scenario and parsing it into clauses (a set-up clause and then three event triggers with verifiable conditions). JBehave then takes these clauses and passes them on to code that is capable of setting a test, responding to the event triggers and verifying the outcome. This code must be written by the developers in the project team (in Java, because that is the platform JBehave is based on). In this case, the code might look like this:

privateGamegame;privateStringRendererrenderer;@Given("a $width by $height game")publicvoidtheGameIsRunning(intwidth,intheight){game=newGame(width,height);renderer=newStringRenderer();game.setObserver(renderer);}@When("I toggle the cell at ($column, $row)")publicvoidiToggleTheCellAt(intcolumn,introw){game.toggleCellAt(column,row);}@Then("the grid should look like $grid")publicvoidtheGridShouldLookLike(Stringgrid){assertThat(renderer.asString(),equalTo(grid));}

The code has a method for every type of clause in a scenario. JBehave will identify which method goes with which clause through the use of annotations and will call each method in order while running through the scenario. The text in each clause in the scenario is expected to match the template text given in the code for that clause (for example, a Given in a scenario is expected to be followed by a clause of the form "a X by Y game"). JBehave supports the matching of clauses to templates and has built-in support for picking terms out of the template and passing them to methods in the test code as parameters. The test code provides an implementation for each clause type in a scenario which interacts with the code that is being tested and performs a test based on the scenario. In this case:

The primary function of this code is to be a bridge between a text file with a story and the code being tested. Note that the test code has access to the code being tested (in this case an instance of Game) and is very simple in nature. The test code has to be simple, otherwise a developer would end up having to write tests for his tests.

Finally, in order to run the tests, JBehave requires some plumbing code that identifies the text files which contain scenarios and which inject dependencies (like instances of Game) into the test code. This plumbing code is not illustrated here, since it is a technical requirement of JBehave and does not relate directly to the principle of BDD-style testing.

Story versus specification

A separate subcategory of behavior-driven development is formed by tools that use specifications as an input language rather than user stories. An example of this style is the RSpec tool that was also originally developed by Dan North. Specification tools don't use user stories as an input format for test scenarios but rather use functional specifications for units that are being tested. These specifications often have a more technical nature than user stories and are usually less convenient for communication with business personnel than are user stories. [6] [31] An example of a specification for a stack might look like this:

Specification: Stack  When a new stack is created Then it is empty  When an element is added to the stack Then that element is at the top of the stack  When a stack has N elements  And element E is on top of the stack Then a pop operation returns E And the new size of the stack is N-1

Such a specification may exactly specify the behavior of the component being tested, but is less meaningful to a business user. As a result, specification-based testing is seen in BDD practice as a complement to story-based testing and operates at a lower level. Specification testing is often seen as a replacement for free-format unit testing. [31]

Specification testing tools like RSpec and JDave are somewhat different in nature from tools like JBehave. Since they are seen as alternatives to basic unit testing tools like JUnit, these tools tend to favor forgoing the separation of story and testing code and prefer embedding the specification directly in the test code instead. For example, an RSpec test for a hashtable might look like this: [32]

describeHashdolet(:hash){Hash[:hello,'world']}it{expect(Hash.new).toeq({})}it"hashes the correct information in a key"doexpect(hash[:hello]).toeq('world')endit'includes key'dohash.keys.include?(:hello).shouldbetrueendend

This example shows a specification in readable language embedded in executable code. In this case a choice of the tool is to formalize the specification language into the language of the test code by adding methods named it and should. Also there is the concept of a specification precondition the before section establishes the preconditions that the specification is based on.

The result of test will be:

 Hash    should eq {}    includes key    hashes the correct information in a key

The three amigos

The three amigos, also referred to as a "Specification Workshop", is a meeting where the product owner discusses the requirement in the form of specification by example with different stakeholders like the QA and development team. The key goal for this discussion is to trigger conversation and identify any missing specifications. The discussion also gives a platform for QA, development team and product owner to converge and hear out each other's perspective to enrich the requirement and also make sure if they are building the right product. [33]

The three amigos are:

See also

Related Research Articles

<span class="mw-page-title-main">Acceptance testing</span> Test to determine if the requirements of a specification or contract are met

In engineering and its various subdisciplines, acceptance testing is a test conducted to determine if the requirements of a specification or contract are met. It may involve chemical tests, physical tests, or performance tests.

Software testing is the act of examining the artifacts and behavior of software via verification and validation.

In computer programming, unit testing, a.k.a. component or module testing, is a form of software testing by which isolated source code is tested to validate expected behavior.

In software and systems engineering, the phrase use case is a polyseme with two senses:

  1. A usage scenario for a piece of software; often used in the plural to suggest situations where a piece of software may be useful.
  2. A potential scenario in which a system receives an external request and responds to it.

A modeling language is any artificial language that can be used to express data, information or knowledge or systems in a structure that is defined by a consistent set of rules. The rules are used for interpretation of the meaning of components in the structure of a programing language.

Test-driven development (TDD) a way of writing code that involves writing an automated test case that fails, then writing just enough code to make the test pass, then refactoring both the test code and the production code, then repeating with another new test case.

<span class="mw-page-title-main">Requirements analysis</span> Engineering process

In systems engineering and software engineering, requirements analysis focuses on the tasks that determine the needs or conditions to meet the new or altered product or project, taking account of the possibly conflicting requirements of the various stakeholders, analyzing, documenting, validating and managing software or system requirements.

In software development, agile practices include requirements, discovery and solutions improvement through the collaborative effort of self-organizing and cross-functional teams with their customer(s)/end user(s). Popularized in the 2001 Manifesto for Agile Software Development, these values and principles were derived from, and underpin, a broad range of software development frameworks, including Scrum and Kanban.

In software testing, test automation is the use of software separate from the software being tested to control the execution of tests and the comparison of actual outcomes with predicted outcomes. Test automation can automate some repetitive but necessary tasks in a formalized testing process already in place, or perform additional testing that would be difficult to do manually. Test automation is critical for continuous delivery and continuous testing.

Model-driven engineering (MDE) is a software development methodology that focuses on creating and exploiting domain models, which are conceptual models of all the topics related to a specific problem. Hence, it highlights and aims at abstract representations of the knowledge and activities that govern a particular application domain, rather than the computing concepts.

RSpec is a computer domain-specific language (DSL) testing tool written in the programming language Ruby to test Ruby code. It is a behavior-driven development (BDD) framework which is extensively used in production applications. The basic idea behind this concept is that of test-driven development (TDD) where the tests are written first and the development is based on writing just enough code that will fulfill those tests followed by refactoring. It contains its own mocking framework that is fully integrated into the framework based upon JMock. The simplicity in the RSpec syntax makes it one of the popular testing tools for Ruby applications. The RSpec tool can be used by installing the rspec gem which consists of three other gems, namely rspec-core, rspec-expectation and rspec-mock.

Domain-driven design (DDD) is a major software design approach, focusing on modeling software to match a domain according to input from that domain's experts.

Twist is a test automation and functional testing solution built by Thoughtworks Studios, the software division of ThoughtWorks. It uses Behavior Driven Development (BDD) and Test-driven development (TDD) for functional testing of the application. It is a part of the Adaptive ALM solution consisting of Twist for Agile testing by ThoughtWorks Studios, Mingle for Agile project management and Go for Agile release management.

<span class="mw-page-title-main">Jasmine (software)</span> Open-source testing framework for JavaScript

Jasmine is an open-source testing framework for JavaScript. It aims to run on any JavaScript-enabled platform, to not intrude on the application nor the IDE, and to have easy-to-read syntax. It is heavily influenced by other unit testing frameworks, such as ScrewUnit, JSSpec, JSpec, and RSpec.

Cucumber is a software tool that supports behavior-driven development (BDD). Central to the Cucumber BDD approach is its ordinary language parser called Gherkin. It allows expected software behaviors to be specified in a logical language that customers can understand. As such, Cucumber allows the execution of feature documentation written in business-facing text. It is often used for testing other software. It runs automated acceptance tests written in a behavior-driven development (BDD) style.

Specification by example (SBE) is a collaborative approach to defining requirements and business-oriented functional tests for software products based on capturing and illustrating requirements using realistic examples instead of abstract statements. It is applied in the context of agile software development methods, in particular behavior-driven development. This approach is particularly successful for managing requirements and functional tests on large-scale projects of significant domain and organisational complexity.

Acceptance test–driven development (ATDD) is a development methodology based on communication between the business customers, the developers, and the testers. ATDD encompasses many of the same practices as specification by example (SBE), behavior-driven development (BDD), example-driven development (EDD), and support-driven development also called story test–driven development (SDD). All these processes aid developers and testers in understanding the customer's needs prior to implementation and allow customers to be able to converse in their own domain language.

<span class="mw-page-title-main">Behat (software)</span>

Behat is a test framework for behavior-driven development written in the PHP programming language. Behat was created by Konstantin Kudryashov and its development is hosted on GitHub.

Capybara is a web-based test automation software that simulates scenarios for user stories and automates web application testing for behavior-driven software development. It is written in the Ruby programming language.

References

  1. 1 2 3 4 5 North, Dan (March 2006). "Introducing BDD". Dan North. Retrieved 25 April 2019.
  2. 1 2 3 "Behaviour-Driven Development". Archived from the original on 1 September 2015. Retrieved 12 August 2012.
  3. Keogh, Liz (2009-09-07). "Introduction to Behavior-Driven Development". SkillsMatter. Archived from the original on 2021-02-25. Retrieved 1 May 2019.
  4. John Ferguson Smart (2014). BDD in Action: Behavior-Driven Development for the Whole Software Lifecycle. Manning Publications. ISBN   9781617291654.
  5. Tharayil, Ranjith (15 February 2016). "Behavior-Driven Development: Simplifying the Complex Problem Space". SolutionsIQ. Retrieved 15 February 2018.
  6. 1 2 3 4 5 6 7 8 9 10 11 Haring, Ronald (February 2011). de Ruiter, Robert (ed.). "Behavior Driven development: Beter dan Test Driven Development". Java Magazine (in Dutch) (1). Veen Magazines: 14–17. ISSN   1571-6236.
  7. Solis, Carlos; Wang, Xiaofeng (2011). "A Study of the Characteristics of Behaviour Driven Development". 2011 37th EUROMICRO Conference on Software Engineering and Advanced Applications. pp. 383–387. doi:10.1109/SEAA.2011.76. hdl: 10344/1256 . ISBN   978-1-4577-1027-8. S2CID   3392536.
  8. 1 2 3 4 Bellware, Scott (June 2008). "Behavior-Driven Development". Code Magazine. Archived from the original on 12 July 2012. Retrieved 1 May 2019.
  9. Liz Keogh (June 27, 2011). "ATDD vs. BDD, and a potted history of some related stuff" . Retrieved 6 May 2019.
  10. "The RSpec Book – Question about Chapter 11: Writing software that matters". Archived from the original on 2009-11-07. Retrieved 2009-08-09.
  11. Dan North. "How to sell BDD to the business". skillsmatter.com. Archived from the original on 2010-11-25. Retrieved 2023-02-07.
  12. "Liz Keogh".
  13. Interview with Liz Keogh & Dan North • GOTO 2013 , retrieved 2023-02-07
  14. D.North, Introducing RBehave Archived 2007-06-20 at the Wayback Machine
  15. Sean Miller (October 31, 2007). "RSpec Adds Eagerly-Awaited RBehave Functionality for Integration Testing". InfoQ. Retrieved 2023-02-07.
  16. 1 2 3 4 5 North, Dan (11 February 2007). "What's in a Story?". Dan North. Retrieved 12 August 2012.
  17. Mabey, Ben. "Imperative vs. Declarative Scenarios in user stories". Archived from the original on 3 June 2010. Retrieved 19 May 2008.
  18. "nutshell — Lettuce 0.2.23 (kryptonite release) documentation". lettuce.it. Retrieved 2020-02-06.
  19. "Gherkin" . Retrieved 7 June 2020.
  20. 1 2 "What is JBehave?". JBehave.org. Retrieved 20 October 2015.
  21. "behave is behaviour-driven development, Python style". Archived from the original on 22 January 2018. Retrieved 30 January 2018.
  22. "Writing Features - Behat 3.0.12 documentation". behat documentation. Archived from the original on 19 September 2015. Retrieved 20 October 2015.
  23. 1 2 Evans, Eric (2003). Domain-Driven Design: Tackling Complexity in the Heart of Software. Addison-Wesley. ISBN   978-0-321-12521-7 . Retrieved August 12, 2012.
  24. North, Dan (31 May 2012). "BDD is like TDD if..." faster organisations, faster software. Dan North & Associates. Retrieved 12 August 2012.
  25. Geneca (16 Mar 2011). "Why Software Projects Fail" . Retrieved 16 March 2011.
  26. Mahmudul Haque Azad (6 Feb 2011). "Say Hello To Behavior Driven Development" . Retrieved 12 August 2012.
  27. Lübke, Daniel; van Lessen, Tammo (2016). "Modeling Test Cases in BPMN for Behavior-Driven Development". IEEE Software. 33 (5): 15–21. doi:10.1109/MS.2016.117. S2CID   14539297.
  28. Adam Craven (September 21, 2015). "Fundamentals of Enterprise-Scale Behaviour-Driven Development (BDD)" . Retrieved 14 January 2016.
  29. Ketil Jensen (December 13, 2009). "BDD with Scenario tables in Fitnesse Slim". Walk the walk. Wordpress. Retrieved 12 August 2012.
  30. "jbehave.org/team-list". JBehave. 2017-05-28. Retrieved 1 May 2019.
  31. 1 2 Roy Osherove (October 4, 2008). "BDD: Behavior vs. Spec Frameworks" . Retrieved 12 August 2012.
  32. Jason Seifer (7 December 2011). "An Introduction To RSpec" . Retrieved 27 October 2012.
  33. "What are the Three Amigos in Agile?". Agile Alliance. 2016-06-16. Retrieved 2019-06-10.