3 ms·
I don't know everyone else's experience, but I found unit testing encouraged me to write better quality code. Testable code is better code. Methods are smalle
by Consultant32452 7y ago
I don't know everyone else's experience, but I found unit testing encouraged me to write better quality code. Testable code is better code. Methods are smaller and have more focused purpose, leading to more reusability. Writing unit tests with >98% coverage forces me to think more deeply about and have a greater understanding of the code I'm writing and how it all interacts. I am more likely to consider edge cases where things might go awry and deal with them. So even if someone believes that tests don't buy them anything directly, I can only speak for myself but the second and third order effects have been great for my career.
- eesmith 7y agoI found that unit testing with small methods meant I was writing my tests to those methods. But the methods were specific to one implementation approach. If I wanted to rewrite the algorithm, eg, for clarity or performance, I ended up replacing many of the tests, which felt like test churn. I prefer trying to figure out where the semi-permanent/API-like interface are in the code, and test through that. The result is closer to integration testing than unit testing, although I use a unit test testing framework for it.
- Consultant32452 7y agoI had the opposite experience. One of the many good practices unit testing encourages is encapsulation. With encapsulation and mocking during testing, there is very little chance of a cascade affect when changing a method or doing some refactoring.
- eesmith 7y agoThe question is, what's the encapsulation level? If you only change the internals of a method, then it's clear that the method call is the API. But the specific method calls are rarely the deliverable (outside of library packages). Those are usually much higher, eg, web API or command-line options. Instead, the methods can be rather fluid. My experience is that the "unit testing with small methods" approach usually emphasizes testing each method. The analogy I use is that of building a bridge, where you don't care what sort of bridge is made, only that it can handle a specific amount of traffic. So I build a truss bridge, with tests that each of the struts is correct. But this is programming, and I decide it's better to replace the truss with a suspension bridge, so I do that. Which means I have to throw away all the strut tests, since I don't have them. While if I had only used load tests from the start - integration tests for what the customer actually wants - then I could do wholesale rewrites without changing much of the tests.
- Consultant32452 7y agoI want to be clear I'm not disagreeing with you here. But I would like to point out if you were building a real bridge every component would be inspected individually. They wouldn't just let you build a whole bridge and do a final load test. Whether that level of robustness/ confidence is important will be highly contextual.
- eesmith 7y agoYes, and part of the mythos of unit testing - especially around small methods - is based on that real-world analogy, when "this is programming", and many of the rules are quite different. As another analogy, if you breadboard a device you can test each individual component directly. Once it's on a chip, most of those individual tests can no longer be used. That's not to say they can't be tested, only that the testing must be done on a higher interface level. So, do you use those higher-level tests, which are more like intergration tests, or do you write the low-level unit tests and expect to throw the away at any sort of non-trivial code changes?