 |
With a
test-driven development (TDD) approach, part
of the overall
Agile Model Driven Development (AMDD)
approach, your tests effectively become detailed
specifications which are created on a
just-in-time (JIT) basis. Like it or not
most programmers don’t read the written
documentation for a system, instead they
prefer to work with the code. And there’s
nothing wrong with this. When trying to
understand a class or operation most programmers
will first look for sample code that already
invokes it. Well-written unit/developers
tests do exactly this – they provide a working
specification of your functional code – and as a
result unit tests effectively become a
significant portion of your technical
documentation.
Similarly, acceptance tests can
form an important part of your requirements documentation.
This makes a lot of sense when you stop and think about it.
Your acceptance tests define exactly what your
stakeholders expect of
your system, therefore they specify your critical requirements.
|
|
Test-Driven Development
(TDD)
The
steps of test first development (TFD) are overviewed in the UML activity diagram of Figure 1.
The first step is to quickly add
a test, basically just enough
code to fail. Next you run
your tests, often the complete
test suite although for sake of
speed you may decide to run only
a subset, to ensure that the new
test does in fact fail.
You then update your functional
code to make it pass the new
tests. The fourth step is
to run your tests again.
If they fail you need to update
your functional code and retest.
Once the tests pass the next
step is to start over.
Figure
1. Test-first development (TFD).

I like to describe TDD with this simple formula:
TDD =
Refactoring
+ TFD.
TDD completely turns traditional development around.
When you first go to implement a new feature, the first question that you ask is
whether the existing design is the best design possible that enables you to
implement that functionality. If so, you proceed via a TFD approach.
If not, you refactor it locally to change the portion of the design affected by
the new feature, enabling you to add that feature as easy as possible. As
a result you will always be improving the quality of your design, thereby making
it easier to work with in the future.
Instead of writing functional code first and then your testing code as an
afterthought, if you write it at all, you instead write your test code before
your functional code. Furthermore, you do so in very small steps – one test and a
small bit of corresponding functional code at a time. A programmer taking a TDD approach refuses to write a new
function until there is first a test that fails because that function isn’t
present. In fact, they refuse to
add even a single line of code until a test exists for it.
Once the test is in place they then do the work required to ensure that
the test suite now passes (your new code may break several existing tests as
well as the new one). This sounds simple in principle, but when you are first
learning to take a TDD approach it proves require great discipline because it is
easy to “slip” and write functional code without first writing a new test.
Tests as Requirements
Figure 2 depicts a customer
acceptance test description (it is shortened for
the sake of brevity, it would need to be expanded with
more steps to truly
validate the functionality described). As you'd
expect, the test has instructions for setting up and
then running it. Additionally, a description, test
ID (optional), and expected results are also indicated.
Acceptance tests should be fully
automated so that you can run them as part of your
application's regression test suite. The
FITNesse testing
framework is a popular choice for doing so.
Figure 2. Acceptance test for
validating a business rule.
| ID |
T0014 |
| Description |
Checking accounts have an overdraft limit of
$500. As long as there are sufficient
funds (e.g. -$500 or greater) within a checking
account after a withdrawal has been made the
withdrawal will be allowed. |
| Setup |
- Create account 12345 with an initial
balance of $50
- Create account 67890 with an initial
balance of $0
|
| Instructions |
- Withdraw $200 from account #12345
- Withdraw $350 from account #67890
- Deposit $100 into account #12345
- Withdraw $200 from account #67890
- Withdraw $150 from account #67890
- Withdraw $200 from account #12345
- Deposit $50 into account #67890
- Withdraw $100 from account #67890
|
| Expected Results |
Account #12345:
- Ending balance = -$250
- $200 Withdrawal transaction posted
against it
- $100 Deposit transaction posted against
it
- $200 Withdrawal transaction posted
against it
Account #67890:
Ending balance = -$500
- $350 Withdrawal transaction posted
against it
- $150 Withdrawal transaction posted
against it
- $50 Deposit transaction posted against
it
Errors logged:
- Insufficient funds in Account #67890
(balance -$350) for $200 Withdrawal
- Insufficient funds in Account #67890
(balance -$450) for $100 Withdrawal
|
Tests as Design
Specifications
Similarly developer test can
form the majority of your
detailed design specification.
Developer tests are typically
written with xUnit family of open source tools, such as JUnit
or VBUnit. These tests can be used to
specify both application code as
well as your
database schema.
Are Tests Sufficient Documentation?
Very likely not, but they do form an important part of it.
For example, you are likely to find that you still need user, system
overview, operations, and support documentation.
You may even find that you require summary documentation overviewing the
business process that your system supports.
When you approach documentation with an open mind, I suspect that you
will find that these two types of tests cover the majority of your documentation
needs for developers and business stakeholders. Furthermore, they are a
wonderful example of AM's
Single
Source Information practice and an important part of your overall efforts to
remain as
agile as possible regarding documentation.
 |
The Object Primer 3rd Edition: Agile Model Driven
Development with UML 2 is an
important reference book for agile modelers,
describing how to develop 35
types of agile
models including all 13
UML 2 diagrams.
Furthermore, this book describes the techniques
of the
Full Lifecycle Object Oriented Testing
(FLOOT) methodology to give you the fundamental
testing skills which you require to succeed at
agile software development. The book also
shows how to move from your agile models to
source code (Java examples are provided) as well
as how to succeed at implementation techniques
such as
refactoring and
test-driven development
(TDD). The Object Primer also includes a
chapter overviewing the critical database
development techniques (database refactoring,
object/relational mapping,
legacy analysis, and
database access coding) from my award-winning
Agile Database Techniques
book. |
 |
Agile Modeling: Effective Practices for Extreme
Programming and the Unified Process is the seminal
book describing how agile software developers approach
modeling and
documentation. It describes principles and
practices which you can tailor into your existing
software process, such as
XP, the
Rational Unified Process (RUP), or the
Agile Unified Process (AUP), to streamline your
modeling and documentation efforts. Modeling and
documentation are important aspects of any software
project, including agile projects, and this book
describes in detail how to
elicit requirements,
architect, and then
design your system in an agile manner. |
 |
Agile Documentation describes a collection of
patterns for writing effective system documentation. |
|
|
I actively work with clients around the world to
improve their information technology (IT) practices as
both a mentor/coach and trainer. A full description of
what I do, and how to contact me, can be
found here.
|