Acceptance Test-Driven Development (ATDD) extends across the spectrum of engineering practices and requirement practices of Define-Build-Test.
If acceptance tests are automated, then they can be run as part of continuous integration. This way any changes in an implementation to meet new requirements will be checked to ensure they do not affect previously fulfilled requirements.
Example of ATDD in action
The following example of ATDD in action can illuminate these facets, just as examples help explain requirements.
Feature Acceptance Tests
Acceptance tests can apply at a higher level, such as the feature or the project. An objective of a project if correctly stated acts as a test. For example, suppose a business decided to give discounts on purchases based on previous orders. The reason for giving discounts is usually to increase sales and thus profits. So an objective for this feature might be:
“Within one year, current customers will have increased their order total by 5%.”
If the acceptance test fails, then the discount feature can be examined for reasons why; for example, was the discount insufficient or not publicized well enough?
User Story Acceptance Criteria
A user story that is part of this business feature might be:
“As the marketing officer, I want the customer to receive a discount when they place an order.”
Acceptance criteria are general ideas for how to ensure that a story is complete. Specific acceptance tests can follow the form of the criteria. The acceptance criteria for this story could be:
“Check that the appropriate discount is applied to the order.”
Use cases give the details for a user story. The use case related to this user story could look like:
Give Customer Discount
Customer has previous orders
Order has a discount applied
Customer requests order summary
System determines discount according to business rule #1 and displays order summary
If the total of previous orders for past year is greater than $1000, discount percentage is 1%
Acceptance tests are created in order to achieve a common understanding of the details of a requirement. They are developed by the triad: the business customer, the developer, and the tester.
Acceptance tests are usually expressed in Given-When-Then scenarios. That is, given a particular condition (state of a system); when an action, such as input, is performed; then the state of the system changes or an output is produced. Acceptance tests can parallel use cases. The pre-conditions of a use case form the “Given” part and the post-conditions express the “Then” part.
An acceptance test for the preceding use case might look like:
Given: Customer has order history
When: Customer requests order summary for an order:
Then: System displays discount:
Total After Discount
With the details shown in the acceptance test, the triad has developed some domain terms, which need clear definitions. For example, Total Amount needs to be defined. Is it just the total for the items that are ordered or does it include taxes and shipping? The test can point out other unclear requirements, such as whether “for the past year” means for the current year (2012) or for the last 365 days. “Past Year” may become a domain term as well, if it is used in other places.
This is one acceptance test that is associated with the use case. There can be others that help clarify the meanings of the domain terms themselves.
Acceptance Test Usage
The acceptance test defined above can be used to develop unit tests. For example, the developer might create a method to compute the discount. The method might look like:
Dollar ComputeDiscount (Dollar Order TotalAmount, Dollar CustomerOrderHistoryTotalAmount);
The values used to test this method are:
where Discounts are
The acceptance test can be executed beneath the user interface through programmatic testing or through the user interface either manually or programmatically.
As shown in the example, Acceptance Test-Driven Development spans the entire Define-Build-Test spectrum.