static void

On Testing/TDD

Published Saturday 30 January 2010

I spent some time working in quite agile, test-focussed environment, but lately I've been in organisations that like the idea of testing, but don't really practice it.

Trying to use testing helps both in proving something works, and because it makes you structure your code so it can be tested (more modular code, reduce coupling) which makes it easier to understand and maintain.

"Pure" test-driven development is a big step, and the existing code base may make it very difficult. So start small, pick the battle fronts where you can win, refactor, organise your tests. Use integration tests but focussed and well structured.

Tests vs time

The standard argument is "Writing tests takes lots of time so only do it if you have time at the end".
Initially it takes time, but unless your code is bugless first time, the iterations of manual testing/ fixing may take more time. So it's (time to code automated test) vs (time to manual test). The latter can add up over the lifetime of the software, and the major win of automated tests is finding regressions. Assess the cost-benefit, it's doesn't have to be 100% coverage full TDD vs nothing.

"You have to F5 and manually use your application anyway".
True, but automated tests can cover all the permutations you don't do in manual tests.

TDD vs Visual Studio

Autocomplete make test-before-code difficult. The consume first mode in Visual Studio 2010 looks like it will help. Up until now, the closest to real TDD that I've done involved stubbing the classes and methods before writing the tests.

TDD is more than testing of course. It's supposed to force you to design simple loosely coupled components. It certainly makes you focus on your API.

Tests vs refactoring

Refactoring tools (Resharper, CodeRush) mitigate some of this, but most major refactoring will have a big impact on a large bank of tests. So yes, many of your tests may be thrown away and you start again. The solution to to keep the tests well structured and named (yes, easier said than done).

Unit tests structure and readability

Things I've found helpful:

Unit tests vs Integration tests

Developers often have the idea that they should only do unit tests, and integration tests are a really bad thing. Of course you can and should refactor to use interfaces with DI / mocks so code can be unit tested without dependencies.

But data access and UI (at least non MVC flavours) are by definition mostly integrations and not easily testable. If you can test them with integration tests, you often have the most interesting and useful tests (unless you love manual testing). All those individual classes are pretty dumb and unit testing doesn't reveal as much.

Integration tests tend to be much longer and more complicated- there's almost always setup/ class or testInitialize and teardown / cleanup. But structure it well and after the writing the initial setup and first test, other tests just follow the same pattern and become very easy.

Integration tests tips

Previously: TFS 2010- workspaces, team projects (13 Dec 2009)