Subscribe to my feed

As part of my tasks at Verizon Business I’ll be evangelizing about Test-Driven Development, due to some teams in my area are interested into implement this wonderful technique but they never use it before. This is very positive, I think, because they usually take care about the quality of his work and the use of TDD helps a lot with this task.

Doing some research to prepare my presentations I found that lot of people has the wrong idea that if they work with TDD they will be losing time. They has the crazy idea that if they don’t write tests they are saving time, they see the write of tests as and expense rather than an investment.

If I don’t use TDD I’ll have the things faster

To believe that if you don’t use TDD you will have the things faster is a big mistake. First of all, to compare velocity and times of different processes the outcome of these must be the same for all. This belief is assuming that the result will be the same with or without TDD and that’s simply wrong. TDD brings a lot of benefits: clean and decoupled code, reduced use of debug, and the most important: certainty.

It is true for the short-term, if don’t write tests and you go directly to the implementation you probably (at least in trivial cases) got the code written faster that if you use TDD.

In the other hand, you should see the things for the long-term, and if you have experience working at the software industry you will probably know that a big problem at many software projects is the rework (I recommend you to read this paper about software quality and the cost of rework). The certainty that TDD brings to you will make you to avoid a lot of rework and debugging or at least make it easier.

A picture worth more than thousand words:

roulette-table

In a few words, working without TDD seems like gambling, you can win a lot and faster, it is very tempting, but due to the uncertainty there is a lot losing possibilities: risk.

TDD will not solve the changing requirements problem, it will not solve the existence of functional bugs due to requirements misunderstanding, etc, what I’m trying to say is that TDD will not eliminate the risk inherent to any software project, but It will reduce it, at least a little, providing a little of certainty.

Continuing with the analogy, using TDD is like gambling but cheating (having a little more of certainty)…

 B0016IXMPU!w234

Regards!

In order to create maintainable and flexible architectures you must start to split your code responsibilities into several components, each of them with a single responsibility, but also low coupled.

Let me show you what it means. To make it clear lets choose a common scenario:

di.components1

UsersRepository is a component that has the responsibility of Users persistence and storage, and UserService is a component that has the responsibility of applying business rules, like validation for example. As you can see in the diagram UsersService maintains a dependency with UsersRepository, this is how it looks in the code:

di.usersrepository1

di.usersservice1

This is a poor design, due that it creates a hard dependency between both components and that’s no good for maintain and test reasons.

It’s clear that this hard dependency will create problems at maintain time, or if we need to do changes, in the other hand if you work with TDD, or you just want to use automated tests, you probably should test each component separately. This means to test the UsersService without testing the UsersRepository and vice versa.

Let’s start to decouple these components, to do that I need to introduce to you the Design by contract approach. We will start by creating an interface for the UsersRepository that will act as contract. The UsersService will use the UserRepository through this contract:

IUsersRepository 

By using a contract we are changing the rules of the game, instead of using the component we are using his functionality through an interface. It means that if we need to migrate our repository from ADO.NET to LinqToSQL or instead of use a database to save our objects we use xml files or webservices or whatever, we just need to create a component that implements this contract and change only one line of code in the service. Let me show you how looks the service with this new design:

di.usersrepository2

We did it. We have removed the hard dependency, and now our components are low coupled. This is our UML components diagram updated:

di.components2 

Ok, now let’s take it to the next level, by making the UsersService friendly for unit tests, to allow test it without testing the UsersRepository. We need a mechanism that allow us to replace the real UserRepository for an mock in testing time. Let me quote Martin Fowler, from his article Mocks aren’t Stubs:

A mock is and objects pre-programmed with expectations which form a specification of the calls they are expected to receive.

Here is where dependency injection comes to play. Dependency injection, also known as Inversion of Control, is a great solution to create testable components and his implementation is really simple. We just need to provide a constructor that accepts an IUsersRepository as parameter, and also, for practical reasons, a default constructor with the default implementation. This is how it looks:

di.usersservice3

Note that the constructor that provides the dependency injection ability is marked as internal. This is because we don’t want to any body from any where be able to use it, from outside they will only view the public constructor, that constructs the service using the default implementation.

Here goes one little trick: to make your internal types visible form other assembly, like a test project, you need to add this line in your AssemblyInfo.cs file:

InternalsVisiblesTo

Just replace “DependencyInjection.Service.Test” by your test project and it’s done.

That’s all, now our components are low coupled, and also we have a testable UsersService, we can even test and create (note I said test before create) our UsersService without have the real implementation of the UsersRepository,  and it is just how it must be.

Hope be useful!

Test-Driven Development (TDD) is an advanced development technique that propose to write automated tests before functionality implementation. Notice I’ve written”development technique” and not “testing technique”, one of the most common mistakes that people made is to believe that TDD is about testing.

In my opinion the main goals of TDD are to provide a little of certainty to one so uncertain task like software development it’s and also to impulse continuous improvement.

TDD is easy to adopt and I think that it’s an invaluable tool that every single developer should use. TDD allows me to sleep better at night, because I know that my code works, and I can prove it with a simple button click.

It also allows me to improve the design of my existing code without fear of breaking functionality inadvertently because, as I said before, I’ve got the power of prove that my code works by clicking a button. This is what I mean when I say certainty.

Did I convince you to start with TDD? This is the first you must know, this are the two simple rules of TDD, quote from Kent Beck’s book Test-Driven Development: by example.

  • Never write a singe line of code unless you have a failing automated test.
  • Eliminate duplication.
  • Let’s start with the first one.

    Never write a singe line of code unless you have a failing automated test

    You sits facing your monitor and you have to write some code. Why? because you have a requirement, If you didn’t have one, probably you’d be reading this blog or using facebook.

    Each time we have to write code is because we have a requirement to fit, what TDD says is: before you write the code to fit it, create a new test method to test it and do this for each requirement you going to fit. Run your tests, they will fail, this means that you didn’t fit the requirement yet, and just now you are enabled to implement your code.

    The requirement is completed when your test/s pass.

    One thing I learned from James W. Newkirk and Alexei A. Voronstov’s book, Test-Driven Development in Microsoft .NET is the fact of TDD is not about unit testing alone. There is other kind of test to specify customer requirements, commonly called functional or integration tests (but let this to another post).

    Eliminate duplication (from XP rule: “Once and only once”)

    Duplication is the common characteristic of bad designs. So after you made your tests pass, refactor your code to eliminate duplication. This is one of the keys of TDD, you can improve your code and design without fear of breaking functionality inadvertently.

    This is why TDD helps to continuous improvement.

    Red, Green, Refactor

    Summarizing this is the flow you should follow when working with TDD (from the Extreme Programming Explored book) :

    tddlife

    Final tips

    • Work in what I call “baby steps”, small test, small pieces of code, remember if you want to be an agile developer your work should be iterative and incremental.
    • Keep It Simple. Fit only the requirements you need to fit, no more, no less.
    • Use mocking frameworks like moq to mock pieces of code that you don’t want to test.

    Hope you find this helpful!