3 ms·
I totally agree that tests aren't a replacement for thoughtful design, but neither is thoughtful design a replacement for tests. I think they complement each ot
by davidcuddeback 14y ago
I totally agree that tests aren't a replacement for thoughtful design, but neither is thoughtful design a replacement for tests. I think they complement each other. Thoughtful design allows you to model how you expect the software to work and your tests help you validate that model.
1) Your tests are just as likely to have bugs anyway.
This is partially addressed by the "red-green" part of TDD's process. I catch many bugs in my unit tests by ensuring that the tests start out red and become green only after writing the code that's supposed to implement what's being tested. Yes, it's possible that some bugs will still exist in your test code, but I think it significantly reduces the probability that a bug exists in your application code.
4) If you design first and test later, you're more likely to have designed real logic into your system. TDD will let you re-factor more easily - DDD (design driven development) will make it so you don't need to spend months re-factoring in the first place.
I agree with the first part, that putting some thought into design upfront is likely to improve the overall quality of your software, but I don't see how that necessarily implies "test last." I like Domain Driven Design [1] (another DDD) for upfront design, but I still use TDD when implementing the design. I've not heard of Design Driven Development before. Is that another name for Domain Driven Design? Its Wikipedia page [2] is lacking substance.
A word about refactoring: I too find that putting thought into design before implementation reduces the need for large refactorings later. I agree with you there. However, I've never found that TDD helps me refactor "later." With TDD, I employ many micro-refactors during implementation. In other words, DDD provides the outline, TDD fills in the details. Alternatively: DDD is designing in-the-large, while TDD is designing in-the-small.
[1] http://en.wikipedia.org/wiki/Domain-driven_design http://en.wikipedia.org/wiki/Domain-driven_design
[2] https://en.wikipedia.org/wiki/Design-driven_development https://en.wikipedia.org/wiki/Design-driven_development
- RyanZAG 14y agoYou and nikita below are both right that having tests is much better than not having tests, and the argument isn't really about choosing design or tests - you definitely want both. I was just trying to address the same point that HeyLaughingBoy above was addressing - tests are not a replacement for design; quality is not about tests. Tests are a tool to improve productivity in a large code base across many developers, and they're also a useful tool for a single programmer to use to focus their development. However, tests themselves are not a mark of quality, and any actual bugs that tests catch are just nice extras - and if you follow TDD, they will never catch bugs, since you will code until the test passes, bugs and all. So my point is very simple: quality is in design and implementation. Tests are just for increasing engineering efficiency - you can have the same quality without tests as long as you have enough time (manual QA). You can't have the same quality without design, even with all the tests in the world.
- nikita 14y agoRight on!
- davidcuddeback 14y ago> Quality is in design and implementation. Tests are just for increasing engineering efficiency. Yes, precisely. I couldn't have said it better myself. Your original comment came across as discounting the importance of tests a lot more than I think you meant it to. But I was also trying to make a couple points about TDD. The first is that watching the tests fail before writing the implementation increases your confidence that there isn't a bug in your test code. This was just to address your #2 bullet point. But this only treats tests as a verification tool, which is orthogonal to good design. Since we agree that tests are for efficiency and we're discussing design, it's not worth dwelling on this point. The second point is that TDD is a useful design tool that can be used in conjunction with upfront design. Upfront design is great for having an overall coherent design, but there are many finer details that are inevitably discovered at implementation time. That's where I think TDD really shines. If you think of building software as sculpting, upfront design is like chiseling out the shape of your statue and TDD is like switching to a more precise tool to etch in small details like hair texture or wrinkles. It's not a perfect metaphor. For example, if you start with a smaller chisel (TDD), you'll end up with the same statue just taking you longer to build. But if you do the same with software development, you'll end up with an arm coming out of the statue's thigh.
- romaniv 14y agoI totally agree that tests aren't a replacement for thoughtful design, but neither is thoughtful design a replacement for tests. Thoughtful design can greatly reduce the number of tests you need by reducing the complexity of your software and moving things to compiler-verified declarations. It can also prevent bugs by the sheer virtue of readability. This is not emphasized in the industry nearly as strongly as it needs to be.