Has anyone worked at a large company, or on a very large project, that successfully used unit testing?
Our current database has ~300 tables, with ~100 aggregate roots. Overall there are ~4000 columns, and we’ll have ~2 Million lines of code when complete. I was wondering – do companies with databases of this size (or much larger) actually go through the effort to Mock/Stub their domain objects for testing? It’s been two years since I worked in a large company, but at the time all large applications were tested via integration tests. Unit testing was generally frowned upon if it required much set up.
I’m beginning to feel like Unit testing is a waste of time for anything but static methods, as many our test methods take just as long or longer to write than the actual code … in particular, the setup/arrange steps. To make things worse, one of our developers keeps quoting how Unit Testing and Agile methods was such an abject failure on Kent Beck’s Chrysler project … and that it’s just not a methodology that scales well.
Any references or experiences would be great. Management likes the idea of Unit Testing, but if they see the amount of extra code we’re writing (and our frustration) they’d be happy to back down.
I’ve seen TDD work very well on large projects, especially to help us get a legacy code base under control. I’ve also seen Agile work at a large scale, though just doing Agile practices alone isn’t sufficient I think. Richard Durnall wrote a great post about how things break in a company as Agile gains ground. I suspect Lean may be a better fit at higher levels in an organisation. Certainly if the company culture isn’t a good match for Agile by the time it starts being used across multiple projects, it won’t work (but neither will anything else; you end up with a company that can’t respond effectively to change either way).
Anyway, back to TDD… Testing stand-alone units of code can sometimes be tricky, and if there’s a big data-driven domain object involved I frequently don’t mock it. Instead I use a builder pattern to make it easy to set that domain object up in the right way.
If the domain object has complex behaviour, I might mock that so that it behaves predictably.
For me, the purpose of writing unit tests is not really for regression testing. It helps me think about the behaviour of the code, its responsibilities and how it uses other pieces of code to help it do what it does. It provides documentation for other developers, and helps me keep my design clean. I think of them as examples of how you can use a piece of code, why it’s valuable and the kind of behaviour you can expect from it.
By thinking of them this way I tend to write tests which make the code easy and safe to change, rather than pinning it down so nobody can break it. I’ve found that focusing on mocking everything out, especially domain objects, can cause quite brittle tests.
The purpose of TDD is not testing. If you want to test something you can get a tester to look at it manually. The only reason that testers can’t do that every time is because we keep changing the code, so the purpose of TDD is to make the code easy to change. If your TDD isn’t making things easier for you, find a different way to do it.