Software Requirements 1-13
to create or modify production code to pass
all of the agreed-upon test cases. This step
might require several iterations. The code
may also be refactored during this step.
When all acceptance test cases have passed, and
presumably all unit and integration test cases as
well, then the unit of functionality is deemed to have
been completely and correctly implemented. The
ATDD process returns to step 1, where a new unit of
functionality is selected, and the cycle repeats.
ATDD might seem to be a testing technique rather
than a requirements specification technique. On the
other hand, a test case has the general form of
“When given input that looks like X, we expect the
software to produce results that look like Y.” The
key is the underlined phrase, “we expect the
software to produce.” If we simply modify that
phrase to say, “the software shall produce,” as in
“When given input that looks like X, the software
shall produce results that look like Y,” what first
looked like a test case now looks like a requirement.
Technically, one acceptance test case can
encompass more than one single requirement, but
the general idea holds that the ATDD test cases are
essentially precise, unambiguous statements of
requirements.
The BDD approach [19] is slightly more structured,
and business domain experts typically prefer it over
ATDD because it is less technical in appearance. In
BDD, the unit of functionality is described as a user
story, in a form such as this: “As a <role>, I want
<goal/desire> so that <benefit>.” This leads to the
identification and specification of a set of
“scenarios” in this form: “Given <some context>
[and <possibly more context>], when <stimulus>
then <outcome> [and <possibly more outcomes>].”
If the story is “As a bank customer, I want to
withdraw cash from the Automated Teller Machine
(ATM) so that I can get money without going to the
bank,” one scenario could be that “the account has a
sufficient balance.” This scenario could be detailed
as “Given the account balance is $500, and the
customer’s bank card is valid, and the automated
teller machine contains enough money in its cash
box, when the Account Holder requests $100, then
the ATM should dispense $100 and the account
balance should be $400, and the customer’s bank
card should be returned.”
Another scenario could be that “the account has an
insufficient balance” and could be detailed as
“Given the account balance is $50, and the
customer’s bank card is valid, and the automated
teller machine contains enough money in its cash
box, when the Account Holder requests $100, then
the ATM should not dispense any money, and the
ATM should say there is an insufficient balance, the
balance should remain at $50, and the customer’s
bank card should be returned.”
The goal of BDD is to have a comprehensive set of
scenarios for each unit of functionality. In the
withdrawing cash situation, additional scenarios for
“The Bank Customer’s bank card has been disabled”
and “The ATM does not contain enough money in
its cash box” would be necessary.
The acceptance test cases are obvious from the BDD
scenarios.
Acceptance criteria-based requirements
specification directly addresses the requirements
ambiguity problem. Natural languages are
inherently ambiguous, but test case language is not.
In acceptance-based criteria requirements
specification, the requirements are written using test
case language, which is very precise. On the other
hand, this does not inherently solve the
incompleteness problem. However, combining
ATDD or BDD with appropriate functional test
coverage criteria, such as Domain Testing,
Boundary Value Analysis and Pairwise Testing (see
the Software Testing KA), can reduce the likelihood
of requirements incompleteness. (See also [9, c1,
c12].)
4.4. Model-Based Requirements Specification [1*,
c12] [2*, c5] [4*]
Another approach to avoiding the inherent
ambiguity of natural languages is to use modeling
languages such as selected elements of the Unified