10

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.

Beep beep
  • 18,873
  • 12
  • 63
  • 78
  • Just curious, do you find unit testing useful for regression testing? – Extrakun Jan 25 '10 at 07:42
  • To some degree, sure. But we have integration tests as well that are relatively detailed ... I don't really see the problem with waiting 2 minutes for a set of 30 specific integration tests to run before passing it to the full-system build testing compared with waiting 2 seconds for the unit test to run. I don't really follow TDD (I like to design first, then code, then test) ... so the instant feedback isn't a huge plus. – Beep beep Jan 25 '10 at 07:46
  • No, you have things reversed: Normally, management is concerned about unit testing, while developers want to do it ;) – Mark Seemann Jan 25 '10 at 07:47
  • Mark - we have a whole team of developers who currently hate it. We want to do testing, we hate stubbing/mocking data. All but one or two of us (of 11 developers) would prefer to just write low level integration tests against a sample database and forget about trying to mock/stub all the dependencies, then needing to change our tests every time we add additional dependencies (which happens all the time). It just isn't productive. – Beep beep Jan 25 '10 at 07:55
  • 1
    My comment was tounge-in-cheek, but I did understand the question (and voted it up). As a general observation, it sounds like you are suffering from high maintainence cost of Fixture Setup. Although not a light read, I can only recommend that you read xUnit Test Patterns for strategies of dealing with such issues: http://www.amazon.com/xUnit-Test-Patterns-Refactoring-Code/dp/0131495054 – Mark Seemann Jan 25 '10 at 08:09
  • This question is unanswerable as-asked, notwithstanding the answers. The logical answer to the question is "yes." The rest is opinion. – theMayer Nov 14 '17 at 22:13
  • Also, generally speaking, it does not make financial sense to unit-test existing, accepted code, unless you plan to modify it. And, from a career longevity standpoint, it often does not make sense to question poor judgement from "management" - so there's that. – theMayer Nov 14 '17 at 22:15

4 Answers4

2

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.

Lunivore
  • 17,277
  • 4
  • 47
  • 92
1

I've had some good experiences with mock objects and unit testing in projects where there was a lot of upfront design and a comfortable timeline to work with -- unfortunately that is often a luxury that most companies won't afford to take a risk on. GTD and GTDF methodologies really don't help the problem either, as they put developers on a release treadmill.

The big problem with unit tests are that if you don't buy-in from a whole team what happens is one developer looks at the code with rose colored glasses (and through no fault of their own) implements only the happy path tests which are what they can think of. Unit tests don't always get kept up as well as they should because corner cases slip by, and not everyone drinks the Kool-Aid. Testing is a very different mindset than coming up with the algorithms, and many developers really just don't know how think that way.

When iterations and development cycles are tight, I find myself gaining more confidence in the code quality by relying on static analysis tools and complexity tools. (FindBugs, PMD,Clang llvm etc) Even if they are in areas that you can't directly address, you can flag them as landmines and help better determine risk in implementing new features in that area.

David Sowsy
  • 1,680
  • 14
  • 13
1

If you find that mocking/stubbing is painfull and takes a long time then you probably have a design that is not made for unit-testing. And then you either refactor or live with it.

I would refactor.

I have a large application and see no trouble in writting unit-tests and when I do I know it's time to refactor.

Of course ther is nothing wrong with integration test. I actualy have those too to test the DAL or other parts of the application.

All the automated test should form a whole, unittest are just a part of those.

chrissie1
  • 5,014
  • 3
  • 26
  • 26
  • Hi Chrissie. Here's a super simple example. Let's say I have a single line of code to get an order type based on a passed in code. The simplified call using Linq is: OrderTypeObject orderType == FetchOrderTypes().Where(x => x.IsSaleable && x.IsTaxable && x.SubType == subType).First();. I can test this against the database with 3 LOC (1 for each assert), but testing against mocked data requires 8-10 extra LOC. 11 LOC to test 1 hardly seems efficient ... and it's hard to argue that the single line presented needs refactoring. – Beep beep Jan 25 '10 at 18:00
  • I just see that you need an ordertype object which would be easily got in one line of code if FetchOrderTypes is Mockable (Interface/Baseclass) But I guess it isn't. And perhaps you only need 3 LOC but you also need to setup the database with the correct data which you don't seem to acount for, or do they magically appear? – chrissie1 Jan 25 '10 at 19:38
0

Yes they do. Quite extensively.

The hard part is getting the discipline in place to write clean code - and (the even harder part) the discipline to chip away at bad code by refactoring as you go.

I've worked in one of the world's biggest banks on a project that has been used from New York, London, Paris and Tokyo. It used mocks very well and through a lot of discipline we had pretty clean code.

I doubt that mocks are the problem - they're just a fairly simple tool. If you've got to rely on them super-heavily, say it looks like you need mocks of mocks returning mocks - then something has gone wrong with the test or the code...

Dafydd Rees
  • 6,941
  • 3
  • 39
  • 48