Tuesday, July 24, 2012

General thoughts about TDD, BDD, SOLID and Agile


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
4/ if test pass, start refactoring and clean the code than run tests of course


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.

Sunday, July 15, 2012

What is a good software ???


By googling this question probably you will get this answer : it must be maintainable, flexible, extensible, scalable, testable, modular, reusable, loosely coupled,…

Personally i define a good software as a software that can be adapted to a change easily.
The change could be of any kind, like change of environment and platform (portability), change of the number of users, number of requests (scalable) and specially change in functionality or requirement (flexible, maintainable)…
As developers we have been always struggling to keep up to these changes specially when we are limited in time and budget which puts us under stress and make our lives miserable. Of course we can’t blame clients for changing their mind we always knew that this will happen and management guys can’t explain how a change cost more than rewriting everything from scratch.
In years many experts have established practices, development processes, and software development methodologies trying to solve this problem (TDD, Agile, SOLID, design patterns(GOF), YAGNI, KISS, DRY(don’t repeat yourself…), used wisely these practices can make our lives much better.

I will post about these different practices and show the relation between them and how they are used to get a good software.

 Stay tuned.