3 ms·
Damn. The misunderstanding just goes on and on. TDD is not a unit testing religion. It's a way of designing software. Some have even advocated calling it Test-
by DanielBMarkham 11y ago
Damn. The misunderstanding just goes on and on.
TDD is not a unit testing religion. It's a way of designing software. Some have even advocated calling it Test-Driven Design, not Test-Driven Development, because the end result is a design, not a series of tests.
This is important to know, because the key factor in the red-green-blue cycle is the blue step: refactoring. The example given by the author is of a system that kept getting tests -- but was never refactored. Instead, more junk kept got thrown in. In this case, they were not doing the most important thing in TDD, refactoring. Not really sure you can even call this TDD. Looks more like a CF created by a bunch of folks under time pressure who thought it would be easier to add stuff than refactor.
If you don't understand what it is, probably not a good idea to criticize it. TDD is a way at looking at constructing OO programs. It's main competitor is probably more along the lines of Model-Driven Development.
TDD is a response to the large amount of commercial code being written in complex object-oriented environments. The goal is to ensure that changes to the code maintain the economic value of the code. In my opinion it is not appropriate where there is little or no economic value, like personal, academic, and start-up code. In cases where there are not complex object graphs full of dependencies, such as small pure FP projects, it's also not indicated -- there's no OO system for TDD to help you design. And if you're not designing stuff, you're not doing TDD.
People get religious about TDD, yep, and it drives me nuts. But like I said, that's no reason not to understand what the hell is going on before criticizing it. Unfortunately, people getting excited and over-selling things is just the way it is in tech, whether it's TDD or the latest cool programming language.
- blub 11y agoDaniel, there is no misunderstanding, I know about the two definitions of TDD - one focusing on testing and one on design. I think that automated unit testing is a useful method of reducing errors and regressions, however not alone but as part of a series of quality control strategies such as integration and higher level and manual testing, static and dynamic analysis, using higher level programming concepts, etc. I am afraid I do not consider TDD to be a legitimate design method. There's an inherent tension between well designed OO code and testable code. Well designed code is properly encapsulated, does one thing, has a minimal interface and few dependencies. Testable code is often less encapsulated, contains extra complexity for the test machinery, among which we can count extra methods (with potentially non-private visibility) and dependencies between classes (such as strategies, policies, factories, etc). When I design I always start from the closest-to-ideal incarnation of the objects, based on OO principles and the way clients of my components will want to use them. Then I compromise on that design just enough to be able to test it to an acceptable level (which varies per component). It could be that I will write no unit test at all, and instead test several interacting components. Someone following TDD will immediately compromise in favor of testing and automatically add maintenance overhead. Furthermore, while designing at the class level is important, it is much more important to architect at higher levels: component, subsystem, application, system/platform. All of these aren't considered when writing unit tests and what makes perfect sense in a "unit" might only be a local optimum. Designing at the test level is to me as architecting a house at the brick level...
- icebraining 11y agoTestable code is often less encapsulated, contains extra complexity for the test machinery, among which we can count extra methods (with potentially non-private visibility) and dependencies between classes (such as strategies, policies, factories, etc). I think that's a more a consequence of poor testing libraries/frameworks than of TDD itself. A method shouldn't have to be turned non-private to be tested. Furthermore, while designing at the class level is important, it is much more important to architect at higher levels: component, subsystem, application, system/platform. All of these aren't considered when writing unit tests and what makes perfect sense in a "unit" might only be a local optimum. It's TDD, not UTDD.
- dragonwriter 11y ago> There's an inherent tension between well designed OO code and testable code. No, there isn't. Code that is not testable is not well-designed. > Well designed code is properly encapsulated, does one thing, has a minimal interface and few dependencies. And testing tests what the consumer of code will use, using the interface. > Testable code is often less encapsulated, contains extra complexity for the test machinery, among which we can count extra methods (with potentially non-private visibility) and dependencies between classes (such as strategies, policies, factories, etc). Only if you are doing testing wrong; what you should be testing, even for unit testing, is the behavior of the unit under test as provided through its exposed interfaces to consumers of the unit under test. > Furthermore, while designing at the class level is important, it is much more important to architect at higher levels: component, subsystem, application, system/platform. Conventional, unit-test-focused TDD is a practice isolated to a particular level which does not conflict with higher-level practices of the same type that address that concern, like Acceptance Test Driven Development (ATDD).
- DanielBMarkham 11y agoI've had a bit of a journey in my professional career when it comes to writing apps. I started in heavy OO-mode, much as you describe, but I'm a long ways from there right now. We're pretty far down an HN thread, but if you're interested in pursuing this further, I shot about an hour of video to show how I would code a small app. You'll find the three parts here:http://tiny-giant-books.com/blog/technical-story-slicing-1-of-3/ http://tiny-giant-books.com/blog/technical-story-slicing-1-o... I'd enjoy continuing the conversation via email if you'd like. Let me know!
- dllthomas 11y ago"In this case, they were not doing the most important thing in TDD, refactoring. Not really sure you can even call this TDD. Looks more like a CF created by a bunch of folks under time pressure who thought it would be easier to add stuff than refactor." To be fair, this is a common failure mode when people try to do TDD. (to be clear, common amongst failures; not necessarily most common amongst failures, and not necessarily a terribly common outcome overall)