Benito Serna
Trying to build software that works

Using end-to-end tests in your TDD cycle

Maybe you have always thought that TDD is about making unit/micro test first… And that is true for some people, other people feel more comfortable starting the cycle with an end-to-end test… And you could be one of them.

But sometimes is not very clear how to do it, because when you are doing TDD…

You write a small test and see an error, then you write some code to make it pass, then you write a new test and you make the implementation to make it pass, etc… You are not suppose to write code until there’s a test that fail, and you don’t write a new test until the last tests is green…

But when you start with an end-to-end test…

And you follow this rule, you will write all the code, in all layers to make that test pass, ending with code that is all tested by you end-to-end test…

Then you won’t need unit test anymore, because you have a test that covers your code, and you should not write a test that already pass, right?

So, what should you do?

Two different practices…

Well I know two different practices…

… And maybe something in the middle.

And as everything, this two approaches have pros and cons…

Actually don’t write unit tests…

This happens normally with people that are using a framework that already provides a way to test everything in integration. For example the “system” tests in Ruby on Rails or the “acceptance” tests in Ember.js.

This tools have made the process of testing the whole thing so easy that you can actually test business logic and edge cases at the end-to-end level.

This has the advantage that it can gives you a lot of confidence because you are testing everything!

But has the also disadvantages, like…

Actually I recommend this path just for small apps or parts of an app, that are either mostly in the server or mostly in the client, but that do not share a lot of behavior.

Using the end-to-end test to know that everything has been correctly wired…

To accomplish this you will change the TDD process a little.

First you will write your end-to-end test and watch it fail…

At this stage you have start to imagine the components that you will need to make that end-to-end pass. Now for each one of this components you can write them in a regular TDD style.

This has advantages like…

But has the disadvantage of not having every path tested at the end-to-end level, although in reality this will be hard even in the previous method.

I think that this method scales better, and I have seen that is what most people do, but depends much more in your ability to design the components that take place in a feature.

More about this…

I have an article that you could use if you need some guide on how to write your feature specs or end-to-end tests.

I don’t really use a lot of end-to-end tests in my TDD workflow… I normally do TDD on unit/micro tests for my use case functions and for a more focused integration tests for the adapters of the use case functions… Then for some important features I write end-to-end tests after…

… But I have used the end-to-end tests in the TDD workflow in the past, and I know that some people fill very comfortable with it. I think that is good for everyone to try it at least once =)

Also if you want to know more about end-to-end tests on the TDD cycle you can read more about it from the guys at thoughtbot, and specially in the book Growing Object Oriented Software Guided by Tests.

Do you need some help with TDD?

I have an email course with with a guide to help you start with TDD!


Do you want to know more?