An Introduction to
Test-Driven Development (TDD)
Agenda
5 minutes
30 minutes
1.
What is TDD?
2.
TDD Stages
3.
How do we get started in TDD?
4.
Why TDD?
What is TDD?
TDD is a technique whereby you write your test cases
before you write any implementation code
Initially, the developer writes a failing automated test case
that defines the new function, then produces code to pass
that test.
An indication of intent
Tests provide a specification of what a piece of code actually
does
Some might argue that tests are part of the documentation
TDD Stages
Write a test
Refactor code
(and test)
Compile
Run test,
watch it pass
Fix compile errors
Write code
Run test,
watch it fail
TDD starts from User Stories
Start from writing acceptance tests. This is a natural
TDD approach.
Before TDD
After TDD
ID: US18898
Name: Remove Recurring Flag in the agreement
screens in Siebel
Description:
As a GCSO Rep, I want to see clean and accurate
contract data in Siebel, so I can perform my work
correctly, Since the Recurring Flag is being "retired" in
favor of other contract characteristics like Contract
Term, Billing Behavior and Renewal Term / UOM, the
Agreement Recurring Flag should be removed from all
Siebel UI's where it is displayed.
ID: US18898
Name: Remove Recurring Flag in the agreement
screens in Siebel
Also I would like the "contracts" pulled down and a
new header "Contract Details" put above.
Acceptance:
Agreement Screens do not display Recurring Field.
Contracts pulled down
New heading of "contract details" added above.
Acceptance test:
The system will display clean, accurate contract data
in Siebel:
Contracts pulled down
Contract Details in header
Description:
As a GCSO Rep, I want to see clean and accurate
contract data in Siebel, so I can perform my work
correctly, Since the Recurring Flag is being "retired" in
favor of other contract characteristics like Contract
Term, Billing Behavior and Renewal Term / UOM, the
Agreement Recurring Flag should be removed from all
Siebel UI's where it is displayed.
TDD ends with an adjusted Definition of Done
In a TDD environment, the definition of "done" is pretty simple:
All automated tests pass
Those automated tests should include new ones written for
the story in question to verify the required functionality or
behavior exists and works.
Code review passed
At least one senior dev on the team is content to let your
work become part of the codebase, and that you didn't
"cheat" or "hack" your way through the story.
Commit successful
Includes the build bot passing all automated tests, code
coverage metrics, style cop checks, etc.
Why TDD? What are the agile benefits?
Bob Martin:
The act of writing a unit test is more an act
of design than of verification
Confidence boost
By practicing TDD, developers will strive to
improve their code without the fear that is
normally associated with code changes
Isnt the green bar a feel good factor?
Remove / Reduce reliance on the
debugger
No more debug-later attitudes
5 Steps to get to TDD:
Specifics you can take back to your teams
1.
Pick 1 feature to pilot TDD. Make sure theres a clear team
understanding of its requirements and decomposition.
Groom the new user stories together.
2.
Have each developer create a test as if code already
existed. Run the tests as a group. They should fail.
3.
Make the test pass by any means necessary. Write the
production code to make the test pass by keeping it simple.
4.
Refactor. Remove duplication caused by the addition of new
functionality. Rerun all the tests to make sure they still pass.
5.
Repeat. Each cycle should be short. A typical work hour
usually contains 3 4 cycles.
Summary
TDD does not replace traditional testing
It defines a proven way that ensures effective unit testing
Tests are working examples of how to invoke a piece of code
Essentially provides a working specification for the code
No code should go into production unless it has associated
tests
Catch bugs before they are shipped to your customer
No code without tests
Tests determine, or dictate, the code
9
Managing the change to TDD
Project Management
Communications
Key messages and key themes inform, engage and promote sustained change.
Training
Set the guiding principles that endorse TDD.
TDD is a new behavior. It is key to define and provide your team with helpful
resources such as quick reference guides, demos, and coaching.
Common sense and innovation
You know your team culture best. Dont go by the book on TDD methods. If
your teams get engaged by using a buddy system, or learn better by getting
outside, sponsor an event to get them moving.
10
The Guiding Principles to TDD
1.
Dont kill the messenger
2.
Make every requirement testable
3.
Anticipate some failure by making room for correction
4.
Embrace learning
5.
Avoid isolation
11
An Introduction to
Behaviour Driven Development
(BDD)
Behavior driven development
BDD is not:
A testing framework or style of testing
A method for writing tests
BDD is:
A formalised template for User Stories
Able to create testable User Stories since they are defined in a
formal manner
Promotes security to a first call citizen in the analysis process
Behavior driven
How do you write a test when you dont know where you are going?
Maybe we need requirements that are easy to write tests for?
Requirements
What are they
Describes what a system should do but not how it will be done
Contract between the implementation team and the analysis team
Audience is typically the stake holders and not the development team
Requirements Precise and clear over verbose
We want requirements that
Can be tested!!!
Are attainable!!!
Are traceable into code!!!
Requirements gathering
BDD merges two different approaches
User Stories
Short one or two line statement that maps to a few days of development work
Highly focused
Domain Driven Design
Ubiquitous language Ensure business terminology permeates into code
Clear single definition (within the project) for each business concept - Account has a single
meaning
BDD User Stories
Formal template for User Stories
Story Template
As a [User/Role]
I want [Behaviour]
so that [I receive benefit]
Example
As a Operations staff member
I want To create a Portfolio
so that So that it can be traded
BDD User Stories
Formal template for User Stories
Scenario Template
Given some initial context (the givens),
When an event occurs,
then ensure some outcomes.
Example
Given New portfolio is called Balanced Fund
When Portfolio already exists
then Portfolio can not be created
NBehave
What is it?
.NET Library for writing automated BDD style tests
Fluent syntax for building up a BDD Style User Stories
Test runner that executes the stories and generates a report listing the contents of the stories
BSD License
Creating a BDD Theme
Collection of related stories
[Theme("Portfolio Maintenance")]
public class PortfolioMaintenanceStory
{
[Story]
public void portfolio_create_story () { ... }
[Story]
public void portfolio_delete_story() { ... }
}
Reference: NBehave.Narrator.Framework.dll
Creating a Story
Fluent interface to define the story
var story = new Story("Create portfolio");
story.AsA(Operations team member")
.IWant("To create a new portfolio on behalf of a portfolio manager")
.SoThat("the portfolio manager can configure the portfolio and the front office can
trade");
Creating a Scenario
Fluent interface to define the story
story.WithScenario("portfolio does not exist")
.Given("portfolio name is $name", "Aggressive Fund")
.When("portfolio does not exist in the database")
.Then("new portfolio should be created");
story.WithScenario("portfolio already exists")
.Given("portfolio name is $name", "Aggressive Fund")
.When("portfolio already exists in database")
.Then("an error should occur");
Executing the test
With NBehave runner or mbUnit
Ouch we get an error???
The scenario throws an exception NBehave isnt validating any code
Use Pending
story.WithScenario("portfolio does not exist")
.Pending("In progress")
.Given("portfolio name is $name", "Aggressive Fund")
.When("portfolio does not exist in the database")
.Then("new portfolio should be created");
Behavior Driven Development
1.
2.
3.
4.
5.
Across the Project (Story) Life Cycle
Story
Pending Scenario
Stubbed Behavior Cycle (Red, Green, Refactor)
Real Behavior Cycle (Red, Green, Refactor)
Acceptance Test
Story
Pending
Scenario
Stubbed
Scenario
Real
Behaviour
Acceptance
Test
Stubbing out the behavior
With NBehave and Rhino. Mocks
Steps to generate an API
1. Go through the User story and find all the domain objects
2. Create a class for each domain object but dont add state
3. Go through the User story and create a find all the services that are required
(Repositories etc)
4. Create an interface for each service but dont add any methods
5. Slowly implement the story
6. Add domain object properties as required
7. Add methods signatures as required
8. Use Stubs to explore Inputs/Outputs to the methods
Stubbing example - Create a new portfolio story
string portfolioName = "";
Portfolio p = null;
var portfolioRepository = MockRepository.GenerateStub<IPortfolioRepository>();
var portfolioService = MockRepository.GenerateStub<IPortfolioService>();
s.WithScenario("portfolio already exists")
.Given("portfolio name is $name", "Aggressive Fund", n => {
portfolioName = n;
p = new Portfolio { Name = portfolioName };
portfolioRepository.
Stub(x => x.FindPortfolioByName(portfolioName)).Return(p);
portfolioService.
Stub(X => X.CreatePortfolio(p)).Throw(new
})
ItemExistsException());
Stubbing example
Create a new portfolio story
.When("portfolio already exists in database",
() => Assert.IsNotNull(
portfolioRepository.FindPortfolioByName(portfolioName))
)
.Then("new portfolio create should fail",
() => Assert.Throws<ItemExistsException>(() =>
portfolioService.CreatePortfolio(p))
);
TFD/BDD Comparison
Test First
Behavior Driven
Bottom Up approach
Lots of little steps working towards a
solution
Output
Tests
Top down approach
Design starting with interfaces (using
stubs)
Back fill with code later
Output
API creation
Giving it a go
Adding NBehave to your team
Developer Driven
Story as Pseudo code
Peer programming One person writes the scenario the other person removes
Pending() and makes it green
Dont use specification syntax
Consider not using NBehave story runner and host Stories within current
Continuous Integration setup (Use NUnit Test Fixture as opposed to Theme)
Giving it a go
Adding NBehave to your team
continued...
Scrum Master/PM driven
Ask for detailed requirements in BBD style
Embedded BDD Lifecycle (API->Stubs->Implementation->UAT) into estimates/deliverables
Use NBehave story output as a deliverable to analysis/test team ie as part of the release
notes
More information
http://nbehave.org/
http://www.codeplex.com/NBehave
http://behaviour-driven.org/
http://dannorth.net/
Questions?