TDD
I still remember first time i heard about TDD, i was curious and a little suspicious;
my first thought was how spending time and money writing more code that doesn’t add functionality
to the product could be beneficial???
First answer I come up with to this question was reducing
maintenance cost, I mean it will cost probably more to create the product but
on the long run it will be advantageous and we will get a good ROI (return on
investment) but couldn’t we reduce the maintenance cost by usual unit tests? Aren’t
they enough? Unit tests (test after) are less expensive, why should we create
tests first which imply of course creating mocks, interfaces, fakes (which
costs more time and more money). To
answer these question I decided to give it a try in a pet project, I fired visual studio and I started (tried to start)
coding.
Simple Remind of TDD steps:
1/ Write test
2/ Test should fail
3/ Write code to make test pass
So the first step consists of writing a test that fails and
it should focus on one feature and suddenly I started thinking
differently, focusing only on the feature and the requirements, use cases, scenarios,
trying to isolate this feature, trying to define its responsibility then
define interfaces needed for mocking purposes and using IOC container and
dependency injection. Repeating the steps 2,3,4 made me realize the difference
between unit tests and the added value of TDD.
In fact doing TDD pushes the developer to focus on the
requirement, and to produce high quality code that respects many practices and
principles of good software design.
It pushes the developer to focus on the single responsibility
of the feature and develop only the functionality needed to pass the test
(avoiding YAGNI), using the mocks will force the design by contract
(interfaces) and, the step of refactoring is very important trying to keep your
code dry and probably using design patterns in order to make your tests pass
and more resilient to change as adding more feature, tests and changes will
affect precedent tests.
I think of TDD as way to automate producing a good code, maintainable
and resilient to change but of course it requires some discipline and writing good
tests as Roy Osherove said bad tests (specially false green tests) are
worse than no tests at all, at least with no tests you don’t assume your code
is correct.
TDD fits well with Agile since it is a repetitive and
incremental process that focuses on single feature at a time. Logically related
features can be grouped to represent the portion of the final product released
in each iteration.
BDD
After TDD I heard about BDD, at first look from a developer perspective
I found them similar
TDD
|
BDD
|
Arrange
|
Given
|
Act
|
When
|
Assert
|
Then
|
There
is no big changes, personally I found BDD useful for workflows and business
rules and process. It forces the developer to think about the functionality of the
code not the code itself.
I will try to explain the difference with an example:
Let's take, Crediting an account scenario
-In TDD it will result in writing a code that tests focuses
on the add operation rather than its context.
-In BDD it will result in a code to test crediting the
account though hiding the technical details about the implementation, it
focuses more on why the code is created and putting it in a context usually using
ubiquitous language that can be understood by stakeholders, QA and Devs .
This is why i said from a developer perspective there is no
difference but in workflows and complex
business operation having a lot of business rules BDD is more convenient.
Usually workflows define the business and can be represented by a state
machine. State machine can be represented by:
Given the actual state when an event happen then trigger action X and update state.
Also BDD can represent a living documentation describing business rules and processes.
This is a huge advantage especially in DDD and complex applications with
complex business rules. Greg Young have elaborated a simple testing framework
that gives this magnificent output (note that this output is a result of a whole
architecture and design decision (CQRS and ES) that made generating such
results easy) :
Creating
customer opens bill - Passed
Date
Is(2011, 10, 6)
When:
Create customer 'Northwind' with id 7
Expectations:
[Passed] Created customer 7 'Northwind'
[Passed] Opened bill 7/1 from 20111006
Imagine all the value you can get by this, developers can
understand easily what is going on, completely understandable by stakeholders that can sign the acceptance based on this output.
Even more, tests can be written by business team than passed to developers, BDD
frameworks like Specflow generate the corresponding code for unit tests and then developers code the functionality.
Summary
Even if TDD contains the word test on it, it is really
different from testing and unit testing, its goal is much more than ensuring regression,
it pushes developers to code better and produces good software. As a successor
BDD isn’t different from TDD it just abstract how functionality is coded and
focus on why code is created, making this understandable by different actors in
an agile Team. In the end it is important to master the art of unit testing and
avoid bad tests as they are worse than no tests at all.
0 comments :
Post a Comment