2. AGENDA
Answers to the WH-words
(WHO – WHAT – WHERE)
Where to begin
The Turn …
… the Twist
Excuses and Common Traps
Where to go from here
4. WHAT IS TDD
Test-Driven Development (or test driven design) is a
methodology.
Common TDD misconception:
TDD is not about testing
TDD is about design and development
By testing first you design your code
5. WHAT IS TDD
Short development iterations.
Based on requirement and pre-written test cases.
Produces code necessary to pass that iteration's test.
Refactor both code and tests.
The goal is to produce working clean code that fulfills
requirements.
6. TEST-DRIVEN DEVELOPMENT
Test-driven development (TDD) is a software
development technique that uses short development
iterations based on pre-written test cases that define
desired improvements or new functions. Each
iteration produces code necessary to pass that
iteration's tests. Finally, the programmer or team
refactors the code to accommodate changes. A key
TDD concept is that preparing tests before coding
facilitates rapid feedback changes. Note that test-
driven development is a software design
method, not merely a method of testing.
7. HOW DOES TDD HELP
TDD helps you produce clean working code that
fulfills requirements
Write Test Code
Code that fulfills requirements
Write Functional Code
Working code that fulfills requirements
Refactor
Clean working code that fulfills requirements
8. ORIGIN
eXtreme Programming (XP)
1999 Kent Beck, Martin Fowler and others…
9. TDD BASICS - UNIT TESTING
Red, Green, Refactor
Make it Fail
No code without a failing test
Make it Work
As simply as possible
Make it Better
Refactor
10. TDD CYCLE
New
require-
ment
Write
Run
new
Make it Better tests
test
Run Make it Fail
Refactor
tests
Write
Run
new
Make it Work tests
code
11. TDD CYCLE
Write Test Code
Guarantees that every functional code is testable
Provides a specification for the functional code
Helps to think about design
Ensure the functional code is tangible
Write Functional Code
Fulfill the requirement (test code)
Write the simplest solution that works
Leave Improvements for a later step
The code written is only designed to pass the test
no further (and therefore untested code is not created).
Refactor
Clean-up the code (test and functional)
Make sure the code expresses intent
Remove code smells
Re-think the design
Delete unnecessary code
13. WHY / BENEFITS
Confidence in change
Increase confidence in code
Fearlessly change your code
Document requirements
Discover usability issues early
Regression testing = Stable software = Quality
software
14. WHERE DOES IT HURT
The pain is here! This is too late…
100% 10
9
80% 8
% defects created
7
Thousand $s
60% 6
5
40% 4
3
20% 2
1
0% 0
Requirements Coding Integration Testing Support
% of Defects Introduced Cost to Fix a Defect
15. IS TDD A WASTE OF TIME (MICROSOFT RESEARCH)
160%
140%
120%
Time To Code Feature
100%
Time To Code Feature
80%
using TDD
60% Defect density of team
40%
Defect density of team
20%
using TDD
0%
MS: VS MS: MSN MS: IBM: Drivers
Major quality improvement for minor time investment
Windows
17. REMEMBER - THERE ARE OTHER KINDS OF TESTS
Unit test (Unit)
Integration test (Collaboration)
User interface test (Frontend, ex. WatiN)
Regression test (Continuous Integration)
…, System, Performance, Stress, Usability, …
The only tests relevant to TDD is Black-box Unit Testing
Test types:
Black-box test
White-box test
18. DIFFICULT SCENARIOS TO UNIT TEST
Closed Object Models (Sharepoint, Silverlight)
Client – server architecture
Communicating Across a Network
An out-of-process call
Includes talking to databases and Web Services.
UI
GUI interaction
Touching the File System
Legacy Code
Requires the Environment to be configured
19. HOW TO DO TDD
… on my component A?
Unit Test A, but what about B, C, D…?
B
D
A
C E
20. HOW TO DO TDD
… on my component A?
This, and the previous two slides,
Ifare all thoughts on implementing tests on existing code.
my component reference…
My coworkers component
A third party component
This is all White-box Unit- or Integration Testing
A very slow component (Database, Web service)
and has therefore nothing to do with TDD.
A component with complex set up
A component with exceptional behavior (Exception)
A remote component (Remoting)
In TDD dependencya Black-box Unit test that fails, first,
Circular you write
and worry about the code implementation later.
Do I have to wait on these components to be
created and/or tested?
21. SINGLE MOST IMPORTANT THING
WHEN LEARNING TDD
Do not
write the code in your head
before you write the test
22. SINGLE MOST IMPORTANT THING
WHEN LEARNING TDD
When you first start at doing TDD you quot;knowquot; what the
design should be. You quot;knowquot; what code you want to
write. So you write a test that will let you write that bit
of code.
When you do this you aren't really doing TDD – since
you are writing the code first (even if the code is only
in your head )
It takes some time to (and some poking by clever
folk) to realize that you need to focus on the test.
Write the test for the behavior you want - then write
the minimal code needed to make it pass - then let
the design emerge through refactoring. Repeat until
done.
24. UNBOUNDED STACK EXAMPLE
Requirement: FILO / LIFO messaging system
Brainstorm a list of tests for the requirement:
Create a Stack and verify that IsEmpty is true.
Push a single object on the Stack and verify that IsEmpty is false.
Push a single object, Pop the object, and verify that IsEmpty is true.
Push a single object, remembering what it is; Pop the object, and verify that
the two objects are equal.
Push three objects, remembering what they are; Pop each one, and verify
that they are removed in the correct order.
Pop a Stack that has no elements.
Push a single object and then call Top. Verify that IsEmpty is false.
Push a single object, remembering what it is; and then call Top. Verify that
the object that is returned is the same as the one that was pushed.
Call Top on a Stack with no elements.
25. UNBOUNDED STACK EXAMPLE
Choosing the First Test?
The simplest.
The essence.
Answers:
If you need to write code that is untested, choose a
simpler test.
If the essence approach takes to much time to
implement, choose a simpler test.
26. UNBOUNDED STACK EXAMPLE
Anticipating future tests, or not?
Answers:
In the beginning, focus on the test you are
writing, and do not think of the other tests.
As you become familiar with the technique and the
task, you con increase the size of the steps.
But remember still, no written code must be untested.
28. UNBOUNDED STACK EXAMPLE
As we were implementing the sixed test, a few
additional tests came to mind, so we need to add
them to our test list.
We want to add tests to verify that the Stack works
when the arguments are equal to null. The new tests
are as follows:
Push null onto the Stack and verify that IsEmpty returns false.
Push null onto the Stack, Pop the Stack, and verify that the value returned is
null.
Push null onto the Stack, call Top, and verify that the value returned is null.
30. WHY DON’T YOU DO TDD, STILL
Why, when TDD was born a decade ago?
The one and only reason: #1: Learning curve…
So why am I telling you this today?
Something happened in the last year…
31. TECHNIQUES YOU NEEDED TO KNOW ABOUT
Interfaces
Dependency Injection
Test Doubles (Mock Objects)
Mocking Framework.
The builder and fluent interface patterns.
…
Not a chance – you still need to know about:
Refactoring
32. THE OLD WAY VS THE NEW WAY
Either (the old way)
“Mock”
Using Interfaces, Dependency Injection and
Test Doubles (Mock Objects)
Or (the new way)
“Isolate” and “Fake”
Using Typemock Isolator
and AAA - The quot;Arrange-act-assertquot; pattern
33. WHY “ISOLATE” AND / OR “FAKE” AT ALL
… when you can hand-write mocks yourself.
ASP.NET MVC example
34. WHY “ISOLATE” AND / OR “FAKE” AT ALL
… when you can hand-write mocks yourself.
ASP.NET MVC
AccountControllerTest file contains 25 tests.
It's a waste of time.
The mocking code starts at line 376 and goes on until line 668 (the end of
the file). That's using an isolation frameworkit contains logic.
Start 293 lines of mocking code, some of now.
Rewriting all this with Isolator code
Ends at line 392
I'll let you do the math.
I wrote mock code like that before. Can you believe my mocking code
even contained bugs? I had to fix those as well.
35. WHY BUY WHEN YOU CAN GET IT FOR FREE
Typemock (Commercial) vs. other frameworks.
The quot;freequot; products are not called free, they are open-source projects.
They are built in most cases by a single person, and maintained by the
community if they are successful.
There's a lot of effort and love put into that. What's the return? There's the
great satisfaction someone finds your software useful (Hey, that also goes for
commercial products).
Ayende, creator of Rhino Mocks and Daniel, creator of Moq, put a lot of
hours into feature requests and support, but there's a limit to what they can
do.
Take a look at Ayende's slogan on his blog: quot;Send me a patch for thisquot;.
Don't be a whiner. Take responsibility. Compare the good, bad and ugly.
And pick what is right for you, not because it's what you can afford, but for
what it will save you, give you back or help you outperform your
competitors.
Of course you get what you pay for (Nothing + More nothing = Nothing).
36. TYPEMOCK™
Established 2005, privately owned
Typemock Isolator
Thousands of customers (Fortune 500)
Tens of thousands licenses sold
37. TYPEMOCK.NET HISTORY
The Typemock Isolator product supports three sets of
API in order to fake dependencies:
Reflective Mocks
String based API (Oldest framework).
Natural Mocks
Record-Replay but strongly typed (Old framework).
Typemock Isolator
Arrange Act Assert (AAA) Syntax (Latest API version - you are encouraged
to use this).
38. ARRANGE ACT ASSERT (AAA)
The “Arrange-act-assert” pattern in the field of mock
frameworks represents us trying to return to basics.
Moq did that nicely by showing a way that leads
there, and it is being taken gladly by Rhino and
Typemock Isolator.
AAA is guidance because there was an outcry (a
silent, vote of feet) that record-replay is not cutting it
– it’s too confusing for non-experts. It’s too technical.
and it does not lend itself to the way people want to
work. So most people didn’t use it.
42. TOP FIVE EXCUSES FOR NOT UNIT TESTING
I don’t have time to unit test.
1.
The client pays me to develop code, not write unit
2.
test.
I am supporting a legacy application without unit
3.
tests.
QA and User Acceptance Testing is far more
4.
effective in finding bugs.
I don’t know how to unit test, or I don’t know how to
5.
write good unit tests.
43. WHEN DO YOU THINK YOU'LL INTRODUCE
UNIT TESTING
A common answer to this question:
quot;We're in a middle of a project right now. We'll wait two months until it
completes, then we'll have timequot;.
If you gave me this answer, I won't believe you. Here's
why:
If I came to you in two months and asked what has changed since last
time, you'll give me the same answer.
That's because development is always done under
pressure.
44. WHEN DO YOU THINK YOU'LL INTRODUCE
UNIT TESTING
In two months time, you'll be up to your neck in fixing
bugs, running away from QA reports. You'll fix those
bugs, and eat away at the time you thought you'd
have when the project completes. And when it does
complete (late), and you think it's over, you'll start
receiving bug reports from the customer. Guess
what? no time to start unit testing then either.
Let's face it, there is never a good time to start unit-
testing, or making any change, for that matter.
So, start today. Write your first unit tests. Change is
painful, and you'd rather delay that. But in agile, we
say: if it's painful, do it first.
45. TEST CODE IS JUST CODE - COMMON TRAPS
Some Anti-Patterns to avoid and some techniques for
making sure Test Code doesn't slow you down:
Cut & Paste
Refactor test code
Poor Encapsulation
The builder and fluent interface patterns are very useful here
Bloated SetUp
Isolation framework / Dependency Injection and Test Doubles
Too hard to write the Test
Refactor production code
Code Integration Test Pain
Remember Integration Testing as well
46. CLASSICISTS V MOCKIST V ISOLATOR
Classicists
The classical TDD style isdoes White-box Integrationa double if it's
The Classicists to use real objects if possible and testing
awkward to use the real thing. So a classical TDDer would use a real
First generation TDD
warehouse and a double for the mail service. The kind of double doesn't
really matter that much.
Mockist
A mockist TDD practitioner, however, will always use a mock for any object
The Mockist does White-box Unit testing
with interesting behavior. In this case for both the warehouse and the mail
Sencond generation TDD
service.
Isolator and Fake
An isolator TDD practitioner, will always “isolate” or “fake” any object with
The Isolator and Fake does Black-box Unit testing
interesting behavior. In this case for both the warehouse and the mail
Third generation TDD
service.
47. INTRODUCING BDD
Behaviour-Driven Development (BDD)
By Dan North
BDD is another variation on TDD that tends to use mockist testing
Test method names should be sentences
A simple sentence template keeps test methods focused
This sentence template – The class should do something – means you can only
define a test for the current class. This keeps you focused. If you find yourself
writing a test whose name doesn’t fit this template, it suggests the behaviour may
belong elsewhere.
An expressive test name is helpful when a test fails
“Behaviour” is a more useful word than “test”.
Determine the next most important behaviour.
Requirements are behaviour, too.
BDD provides a “ubiquitous language” for analysis.
Acceptance criteria should be executable.
48. WHEN TO USE TDD/BDD
When you have to implement a new functional
requirement, or make a requirement up yourself.
Note: When you want to change existing code, first
write covering Unit Tests (white box testing).
Then use TDD to add new functionality.
49. TOOLS YOU NEED TO KNOW ABOUT
Continuous Integration
Build Automation Tools
MSBuild
Nant
FinalBuilder
CI Servers
Team System / Team Foundation Server
TeamCity (R#)
CCnet (CruiseControl.NET)
FinalBuilder Server
50. TOOLS YOU NEED TO KNOW ABOUT
Visual Studio Integration
Refactoring
R# (ReSharper)
Code Rush
51. TOOLS YOU NEED TO KNOW ABOUT
Isolation / Mocking Frameworks for .net
Open Source
Rhino Mocks for .NET
NMock for .NET
Moq for .Net
Commercial (costs money but worth it)
Typemock Isolator
Typemock Isolator For SharePoint
53. WHERE TO GO FROM HERE
You don’t have to start big
Start new tasks with TDD
Add Tests to code that you need to change or
maintain – but only to small parts
Proof of concept
If it's worth building, it's worth testing.
If it's not worth testing,
why are you wasting your time working on it?
54. LINKS
Books
Test-Driven Development in Microsoft® .NET (http://www.amazon.co.uk/gp/product/0735619484)
Test-Driven Development by Kent Beck (C++) (http://www.amazon.co.uk/gp/product/0321146530)
Blog
The Typemock Insider Blog (http://blog.typemock.com/)
Unit test study from Microsoft Research:
http://research.microsoft.com/en-us/projects/esm/nagappan_tdd.pdf
Typemock
http://www.typemock.com/
Unit testing Silverlight:
http://www.codeplex.com/CThru
Other links:
http://en.wikipedia.org/wiki/Test-driven_development
http://www.testdriven.com/
http://www.mockobjects.com/ - Online TDD book: http://www.mockobjects.com/book/index.html
http://www.martinfowler.com/articles/mocksArentStubs.html
http://dannorth.net/introducing-bdd
http://behaviour-driven.org/Introduction