Behavior-driven development: Difference between revisions

Content deleted Content added
m top: MOS:REFSPACE (remove space between reference tags), replaced: /ref> <ref → /ref><ref
 
(759 intermediate revisions by more than 100 users not shown)
Line 1:
{{short description|Software test naming}}
{{context}}
{{Software development process}}
'''Behavior-driven development''' ('''BDD''') involves naming [[software testing|software tests]] using [[Domain model|___domain language]] to describe the behavior of the [[source code|code]].
 
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.
In computer science '''Behavior Driven Development''' is a programming technique that questions the behavior of an application before and during the development process. By asking questions as ''what should this application do?'' or ''what should this part do?'' developers can identify gaps in their understanding of the problem ___domain and talk to their peers or ___domain experts to find the answers.
 
Proponents claim it encourages collaboration among developers, quality assurance experts, and customer representatives in a software project.<ref name="BDD_Def_BehaviourDriven">{{cite web |url=http://behaviour-driven.org/ |title=Behaviour-Driven Development |archive-url=https://web.archive.org/web/20150901151029/http://behaviourdriven.org/ |archive-date=1 September 2015 |access-date=12 August 2012}}</ref><ref name="IntroBDD">{{cite web |last=Keogh |first=Liz |date=2009-09-07 |title=Introduction to Behavior-Driven Development |url=https://skillsmatter.com/skillscasts/934-introduction-to-behaviour-driven-development |access-date=1 May 2019 |work=SkillsMatterr |archive-date=2021-02-25 |archive-url=https://web.archive.org/web/20210225113241/https://skillsmatter.com/skillscasts/934-introduction-to-behaviour-driven-development |url-status=dead }}</ref> It encourages teams to use conversation and concrete examples to formalize a shared understanding of how the application should behave.<ref name="BDD in action">{{cite book |title=BDD in Action: Behavior-Driven Development for the Whole Software Lifecycle |author=John Ferguson Smart |publisher=Manning Publications |date=2014 |isbn= 9781617291654}}</ref> BDD is considered an effective practice especially when the ''problem space'' is complex.<ref name="When to adopt BDD">{{cite web |url= https://www.solutionsiq.com/resource/blog-post/behavior-driven-development-simplifying-the-complex-problem-space/|title=Behavior-Driven Development: Simplifying the Complex Problem Space |last=Tharayil |first=Ranjith|date=15 February 2016|work=SolutionsIQ |access-date=15 February 2018}}</ref>
The purpose is to question each part of the application and the application entirely. These questions deal not mere with technical or requirements issues but also with cost and time related issues. ''Is it feasible for our organization to build an application of this scope?'' is a question that can be answered by writing behavior tests. By exposing the complexities early on developers and management can make better assumptions on how fit the organization is to handle the creation of an application.
 
BDD is considered a refinement of [[test-driven development]] (TDD).<ref name="BDD_Def_BehaviourDriven"/><ref name="BDD_JW">{{cite journal |last1=Haring |first1=Ronald |date=February 2011 |title=Behavior Driven development: Beter dan Test Driven Development |editor-last = de Ruiter | editor-first = Robert |journal=Java Magazine |issue=1 |pages=14–17 |publisher=Veen Magazines |issn=1571-6236|language=nl}}</ref><ref>{{cite book|last1=Solis|first1=Carlos|last2=Wang|first2=Xiaofeng|title=2011 37th EUROMICRO Conference on Software Engineering and Advanced Applications |chapter=A Study of the Characteristics of Behaviour Driven Development |pages=383–387|doi=10.1109/SEAA.2011.76|year=2011|isbn=978-1-4577-1027-8|hdl=10344/1256|s2cid=3392536 |hdl-access=free}}</ref>{{Vague|date=May 2015}}<ref name="BDD_CodeMagazine">{{cite web |url=http://www.code-magazine.com/article.aspx?quickid=0805061&page=1 |title=Behavior-Driven Development |last=Bellware |first=Scott |date=June 2008 |work=Code Magazine |access-date=1 May 2019 |archive-url=https://web.archive.org/web/20120712114206/http://www.code-magazine.com/article.aspx?quickid=0805061&page=1 |archive-date=12 July 2012 |url-status=dead }}</ref><ref name="ATDD vs BDD">{{cite web|url=https://lizkeogh.com/2011/06/27/atdd-vs-bdd-and-a-potted-history-of-some-related-stuff/|author=Liz Keogh|title=ATDD vs. BDD, and a potted history of some related stuff|date=June 27, 2011|access-date=6 May 2019 }}</ref> 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.<ref name="BDD_Def_BehaviourDriven"/><ref name="BDD_CodeMagazine" />
To prove the behavior of an application during and after the development process application code is tested through behavioral tests. These tests should answer the questions organizations have about the application and illustrate how an application works. When writing behavioral tests developers are assumed to solve the most important or critical questions first. Each test that is written deals with the next most important question on the list. If every question is solved the behavior of the application is defined in tests and the application has been created.
 
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.<ref name="BDD_JW"/> Some tools specifically for BDD can be used for TDD. The tools automate the [[Domain-driven design#Building blocks|ubiquitous language]].
==Behavioral tests==
 
== Overview ==
The examples below demonstrate how behavioral tests can be written with the [[Java programming language]] using the [[JUnit]] automated testing framework. This allows the tests to be executed swiftly and constantly during the development process.
 
BDD is a process by which DSL structured natural-language statements are converted into executable tests. The result are tests that read like acceptance criteria for a given function.
The test below verifies if a prime number calculator can calculate the first prime number of 100 correctly.
 
As such, BDD is an extension of TDD.
<pre><nowiki>
public class PrimeNumberCalculatorTests extends junit.framework.TestCase {
public void testIfPrimeAfter100Is101() {
PrimeCalculator calculator = new EratosthenesPrimesCalculator(100);
int result = calculator.nextPrime();
assertEquals("First prime after 100 should be 101 but is " + result, 101, result);
}
}
</nowiki></pre>
 
BDD focuses on:
The test above should be expanded so that more prime numbers are tested, as shown below:
 
* Where to start in the process
<pre><nowiki>
* What to test and what not to test
public class PrimeNumberCalculatorTests extends junit.framework.TestCase {
* How much to test in one go
public void testIfPrimeAfter100Is101() {
* What to call the tests
PrimeCalculator calculator = new EratosthenesPrimesCalculator(100);
* How to understand why a test fails
int result = calculator.nextPrime();
assertEquals("First prime after 100 should be 101 but is " + result, 101, result);
}
 
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-When-Then|Given [initial context], when [event occurs], then [ensure some outcomes] ]].
public void testIfFirstPrimeIs2() {
PrimeCalculator calculator = new EratosthenesPrimesCalculator();
int result = calculator.nextPrime();
assertEquals("First prime should be 2 but is " + result, 2, result);
}
 
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, [[quality assurance|QA]] and non-technical or business participants in a software project.<ref>{{Cite web |url=http://forums.pragprog.com/forums/95/topics/3035 |title=The RSpec Book – Question about Chapter 11: Writing software that matters |access-date=2009-08-09 |archive-url=https://web.archive.org/web/20091107220359/http://forums.pragprog.com/forums/95/topics/3035 |archive-date=2009-11-07 |url-status=dead }}</ref>
public void testIfPrimeAfter683Is691() {
PrimeCalculator calculator = new EratosthenesPrimesCalculator(683);
int result = calculator.nextPrime();
assertEquals("First prime after 683 should be 691 but is " + result, 691, result);
}
 
== Principles ==
public void testFirst10Primes() {
PrimeCalculator calculator = new EratosthenesPrimesCalculator();
int[] primes = new int[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
for (int i = 0; i < primes.length; i++) {
int result = calculator.nextPrime();
assertEquals("Expected prime: [" + primes[i] + "], got: [" + result "]", primes[i], result);
}
}
}
</nowiki></pre>
 
BDD suggests that software tests should be named in terms of desired ''behavior''.<ref name="BDD_JW"/><ref name="BDD_CodeMagazine"/> Borrowing from [[agile software development]] the "desired behavior" in this case consists of the requirements set by the business &mdash; that is, the desired behavior that has [[business value]] for whatever entity commissioned the software unit under construction.<ref name="BDD_JW"/> Within BDD practice, this is referred to as BDD being an "outside-in" activity.
Behavioral tests use the techniques of Test-Driven Development but have a more specific goal. The purpose is to define the behavior of an application rather than the implementation. In the example above it's not really important how the prime numbers are calculated - if calculated at all. What's important is that the numbers are correct which is the expected behavior of the application.
 
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.
The application users may also require the prime number calculation must perform within certain benchmarks. If this is the case the behavioral tests should record the performance characterics and compare them with the expected results. But again this does not dictate how the prime number calculation should be implemented, it only dictates how it should behave.
 
===Behavioral specifications===
==Test conduct==
 
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 (computing)|scenario]] aspect of this format may be regarded as an application of [[Hoare logic]] to behavioral specification of software using the ___domain-specific language.
When writing behavioral tests there are number of practical rules to keep in mind that will help developers to stay on track with the goals of testing behavior instead of implementation. These numbers aim to make both tests and application code and design as flexible and robust as possible.
 
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. Each user story should, to some extent, follow the structure:<ref name="BDD_JW"/>
* '''Test size''': each test (that is each test method) should not be longer than 15 lines of code (not counting empty lines). Test methods that are longer are either too complex (or the implementation is inefficient) or test too much behavior. Small tests are more expressive - it's easier to understand the behavior that is tested - and are easier to maintain and [[refactor]].
* '''Mock objects''': the usage of mock objects is encouraged (e.g. by using the [[EasyMock]] framework for Java) to achieve the previous goal. Mock framework create easy to use - and verify - objects that make tests more accurate, shorter and easier to maintain since the framework creates the implementation of the objects, not the developers that write the behavioral tests.
* '''Helper methods''': some behavior is best implemented in a helper method (e.g. load this or that from the database) that can be easily tested and called from elsewhere in the application. These methods help to make the code more expressive (through expressive method and argument names) and easier to test.
* '''No dependencies''': behavioral tests should not depend on other test cases, the execution order of tests or test cases or the presences of any configured system. This assures that only a limited, well-defined behavior in tested in a fine-grained manner. The opposite is to test fully configured application (components) in a coarse-grained matter. This aspect of these an application is important yet it is the ___domain of [[Integration tests]].
* '''Isolated''': behavioral tests should work in full isolation to ensure only a very limited part of the entire behavior of an application is tested. The more fine-grained behavioral tests are the better the behavior is tested.
 
; Title: An explicit title.
Specifically for Java there are two more rules:
 
; Narrative: A short introductory section with the following structure:
* '''Packages''': tests should sit in a separate source tree but in the same package to allow for better testing.
:* '''As a''': the person or role who will benefit from the feature;
* '''Protected methods''': helper methods that implemented behavior that can be tested should be declared with package-protected access to allow their invocation from test cases.
:* '''I want''': the feature;
:* '''so that''': the benefit or value of the feature.
 
; Acceptance criteria:A description of each specific [[Scenario (computing)|scenario]] of the narrative with the following structure:
==Test first, implement next==
:*'''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.
 
{{anchor}}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.<ref name="BDD_JW"/> It also suggests 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.<ref name="declarative">{{cite web |url=http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html |archive-url=https://web.archive.org/web/20100603235246/http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html |url-status=dead |archive-date=3 June 2010 |title=Imperative vs. Declarative Scenarios in user stories |last=Mabey |first=Ben |access-date=19 May 2008 }}</ref> This format is referred to in [[Cucumber (software)|Cucumber]] as the [[Cucumber_(software)#Gherkin_language|Gherkin language]].
As promoted by most agile development techniques Behavior Driven Development promotes a short test/implement/improve cycle. Testing before implementating in a crucial aspect of Behavior Driven Development.
 
===Specification as a ubiquitous language===
===Test===
The first step is to write a behavioral test, as shown below:
 
BDD borrows the concept of the ''ubiquitous language'' from [[___domain driven design]].<ref name="BDD_JW"/><ref name="BDD_CodeMagazine"/> A ubiquitous language is a (semi-)formal language that is shared by all members of a software development team &mdash; both software developers and non-technical personnel.<ref name="DDD_Evans">{{cite book |title=Domain-Driven Design: Tackling Complexity in the Heart of Software |last=Evans |first=Eric |year=2003 |publisher=Addison-Wesley |isbn=978-0-321-12521-7 |access-date=August 12, 2012 |url=http://www.domaindrivendesign.org/books/evans_2003}}</ref> 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.<ref name="DDD_Evans"/> In this way BDD becomes a vehicle for communication between all the different roles in a software project.<ref name="BDD_JW"/>
<pre><nowiki>
public class PrimeNumberCalculatorTests extends junit.framework.TestCase {
public void testIfFirstPrimeIs2() {
PrimeCalculator calculator = new EratosthenesPrimesCalculator();
int result = calculator.nextPrime();
assertSame("First prime should be 2 but is " + result, 2, result);
}
}
</nowiki></pre>
 
A common risk with software development includes communication breakdowns between Developers and Business Stakeholders.<ref name="BDD_comms">{{cite web |url=http://www.geneca.com/75-business-executives-anticipate-software-projects-fail/ |title=Why Software Projects Fail |author=Geneca |date=16 Mar 2011 |access-date=16 March 2011}}</ref> 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.<ref name="BDD_JW"/> In addition, having such a ubiquitous language creates a ___domain model of specifications, so that specifications may be reasoned about formally.<ref name="BDD_CodeProj">{{cite web |url=http://www.codeproject.com/Articles/148043/Say-Hello-To-Behavior-Driven-Development-BDD-Part |title=Say Hello To Behavior Driven Development |author=Mahmudul Haque Azad |date=6 Feb 2011 |access-date=12 August 2012}}</ref> This model is also the basis for the different BDD-supporting software tools that are available.
After writing the test the project should compile correctly. This means the <code>PrimeCalculator</code> and <code>EratosthenesPrimesCalculator</code> classes should exist and sould have a <code>nextPrime()</code> method. [[Integrated Development Environment]] (IDE) tools can help with this by creating those classes and methods that are missing in the project. The code below is generated by an IDE:
 
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 (computer programming)|keyword]], for example) and may therefore be processed in some way by a tool that understands the formal parts of the ubiquitous language.
<pre><nowiki>
public interface PrimeCalculator {
int nextPrime();
}
 
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. <ref name="ieeeswbdd">
public class EratosthenesPrimesCalculator implements PrimeCalculator {
{{Cite journal |
public int nextPrime() {
doi= 10.1109/MS.2016.117 |
throw new UnsupportedOperationException();
title = Modeling Test Cases in BPMN for Behavior-Driven Development |
}
journal = IEEE Software | volume = 33 | issue = 5 | pages = 15–21 | year = 2016 |author1=Lübke, Daniel |author2=van Lessen, Tammo |
}
s2cid = 14539297 }}</ref>
</nowiki></pre>
 
== Specialized tooling ==
In the minds of the developers there may be methods missing from the classes above but since the behavioral test does not define other behaviors this is acceptable.
 
Much like TDD, BDD may involve using specialized tooling.
===Implement===
Once the behavioral test compiles the classes that are tested may be implemented. Their implementation is finished when the behavioral tests works without failing. The behavioral tests are are fixtures that can be used as bearings for developers to know when the implementation behaves as expected.
 
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").
===Improve===
When the behavioral test works correctly developers may improve the implementation to work more efficiently. This can happen right after the implementation or at a later time.
 
=== Tooling principles ===
==Setting behavioral priorities==
Developers, designers and project managers should talk with ___domain experts to determine what behaviors are the most crucial for the application to work properly and be useful for the organization. For each behavior it should be determined - or questioned - if sufficient information is available so that non-___domain experts - developers, designers, project managers - can test and implement it. It may not be apparent information is missing until testing starts.
 
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.
==External links==
 
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.<ref name="BDD_Enterprise">{{cite web |url=http://www.methodsandtools.com/archive/entreprisebdd.php |title=Fundamentals of Enterprise-Scale Behaviour-Driven Development (BDD) |author=Adam Craven |date=September 21, 2015 | access-date=14 January 2016}}</ref> The exact implementation of behavioral requirements varies per tool, but agile practice has come up with the following general process:
* [http://daveastels.com/files/sdbp2005/BDD%20Intro.pdf Overview of BDD]
* [http://jbehave.codehaus.org/ Implementation of BDD framework]
 
* The tooling reads a specification document.
* The tooling directly understands completely formal parts of the ubiquitous language (such as the '''Given''' keyword in the example above). Based on this, the tool breaks each scenario up into meaningful clauses.
* Each individual clause in a scenario is transformed into some sort of parameter for a test for the user story. This part requires project-specific work by the software developers.
* The framework then executes the test for each scenario, with the parameters from that scenario.
 
==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. Specification tools don't use user stories as an input format for [[Scenario testing|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.<ref name="BDD_JW"/><ref name="BDD_SPEC_OSHEROVE">{{cite web |url=http://osherove.com/blog/2008/10/4/bdd-behavior-vs-spec-frameworks.html |title=BDD: Behavior vs. Spec Frameworks |author=Roy Osherove |date=October 4, 2008 |access-date=12 August 2012}}</ref> An example of a specification for a [[stack (abstract data type)|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.<ref name="BDD_SPEC_OSHEROVE"/>
 
== 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.<ref>{{Cite web|url=https://www.agilealliance.org/glossary/three-amigos/|title=What are the Three Amigos in Agile?|date=2016-06-16|website=Agile Alliance|language=en-US|access-date=2019-06-10}}</ref>
 
The three amigos are:
* Business - Role of the business user is to define the problem only and not venture into suggesting a solution
* Development - Role of the developers involve suggesting ways to fix the problem
* Testing - Role of testers is to question the solution, bring up as many as different possibilities for brain storming through what-if scenarios and help make the solution more precise to fix the problem.
 
==See also==
* [[Specification by example]]
* [[Behat (computer science)|Behat]] (PHP framework)
* [[Cynefin framework]]
* [[Concordion]] (Java framework)
* [[RSpec]]
* [[Gauge (software)|Gauge]]
* [[Jasmine (JavaScript testing framework)]]
* [[Squish (Froglogic)|Squish GUI Tester]] (BDD GUI Testing Tool for JavaScript, Python, Perl, Ruby and Tcl)
* [[Use case]]
* [[Fitnesse]] has been used to roll out BDD<ref name="FitNesse_BDD">{{cite web |url=http://ketiljensen.wordpress.com/2009/12/13/bdd-with-scenario-tables-in-fitnesse-slim/ |title=BDD with Scenario tables in Fitnesse Slim |author=Ketil Jensen |date=December 13, 2009 |work=Walk the walk |publisher=Wordpress |access-date=12 August 2012}}</ref>
 
==References==
{{Reflist|30em}}
 
[[Category:Software design]]
[[Category:Software development philosophies]]
[[Category:Software testing]]
[[Category:Articles with example Java code]]