This and your other comment are obviously coming from real experience using these techniques on production systems. (In fact, they're so lucid that I went back and read all your previous HN comments and quite enjoyed them.) They are refreshing since most of the discourse on unit testing falls into binary for/against mode (q.v. the OP). I also agree with you about test maintenance. (That's one reason I believe we can do better than the object-model-plus-unit-tests approach.)

Here's one idea I've come to: test code and production code are different species that need to develop differently. Good production code is a well-factored, abstract machine. Good unit tests are concrete examples illustrating one thing each that are independent of one another. The same principles do not apply, much as a car's manual is not built like a car.

For example, I allow almost no duplicate code in production, but with unit tests my tolerance is much higher. Duplication is bad in either case, but trying to eliminate it from tests has negative consequences that are worse: it prevents them from being simple, self-contained, and independent. A good unit test reads like a story. There are many such stories you might want to tell about your system and typically there is lots of overlap between them, working out different permutations of the same thing and so on (imagine an enormously complicated Venn diagram). Production code is not a story at all (except maybe inside the occasional well-defined function), it's a set of abstractions.

When people treat tests like production code and try to factor out the common bits, they end up creating a whole new set of abstractions that sits between the production and tests. This layer soon becomes a sink for all kinds of bloat (ObjectMotherFactoryManagers, anyone?), eventually so thick that you can't even see the production code from the tests. You spend hours tracking down test failures only to find that the problem was in this test infrastructure. Regardless of what one thinks about unit testing in general, this clearly isn't a good way to scale it.

Here's an analogy that popped into my head one day when helping some people work on a large system that had this problem. In the 1920s it was fashionable to do formal analyses of fairy tales. People discovered all kinds of common patterns and overlaps ("Once upon a time", things come in threes, etc.). Yet each tale is also unique. Now imagine if someone said: All this duplication is bad. Instead of duplicating "Once upon a time" and "In a deep forest there lived...", let's refer the reader to a "setup" section. Of course we'll need to provide some parameters (how many boys, how many girls, etc) because they're not quite identical, only mostly. And witches always do such-and-such, so let's factor out a Witch and then we'll only have to write each witchy action once and can refer to these from different stories. My point is that, if you did this to a book of fairy tales, you'd no longer have a storybook. You'd have a weird assortment of meta fairy tale bits. Critically, you could no longer pick it up and read a chapter at a time. In fact, a person coming in cold would have trouble reading any of it.