I think articles like these miss that the appropriate amount of testing is very different for different sorts of applications.<p>If you're building a low-level infrastructure component, like the storage engine for a database, or an encryption library, then basically every line of code, every piece of functionality should be tested. In these situations tests are pretty straightforward to run, the "right thing" for your software to do doesn't change very much, and without tests it's easy to introduce an accidental bug.<p>On the other end of the spectrum is things like video games. If you're scripting the behavior for a new object in a video game, it's often very hard to test it does exactly what you want. And you're likely to change your mind about this behavior, and a test isn't very useful when you simply change the test every time you change the feature. In situations like these, tests often aren't useful.<p>So basically the question of "how much unit testing should I do" is a perfect recipe for the two sides to argue past each other based on very different experiences.
<i>"You might think that unit testing helps you avoid technical problems, but the fact is that unit testing is more about getting a psychological effect rather than a technical one, it's a way to make you feel better about yourself - yes, I said it."</i><p>Probably could not disagree more with this statement. I recently implemented an element-wise hash function over arrays of arbitrary length values. I wanted to be doubly sure that my logic for choosing memory offsets into these arrays was correct. So I tested the function extremely thoroughly on some important examples and also on randomly generated data. I did this because the hashing function was a core component of the system I was building. If it didn't work, especially on subtle edge cases, the consequences would be severe. So what did I get out of testing that function so thoroughly? Psychological effect, as the author puts it? Well, yes I suppose. I get to feel confident that the code works as expected. I get to believe this not just when I originally write it but also when changes are made to it on into the future. I get to believe the same about components built on top of and around it. But calling these benefits "psychological", while technically true, seems to miss the point. I'd also call them essential. If you want to increasingly waste your time chasing issues that pop up because your code isn't properly covered by tests (and do that in production because you deployed before realizing there was a problem), be my guest.
A mature application without a test suite is basically unmaintainable by others, the difference is night and day. It’s almost malpractice to deliver software products without the tests and documentation necessary for clients to maintain them. Please write tests!<p>A lot of junior (and not so junior) engineers write bad tests. Each test is huge, with lots of irrelevant setup, and many assertions. It’s hard to tell which requirement is being verified, and it can break for lots of reasons. So they change code anywhere and lots of tests break and it’s not clear what’s going wrong. Yeah I can understand how people with that kind of experience come to believe tests are a waste of time.<p>When an application is tested from day one, it ends up designed for testability, and individual tests are succinct, often one liners. Testing feels easy and delivers a high ROI.<p>I think of testing as a fundamental skill, like learning good form in a sport like tennis. You can be self taught with bad form and do alright for a while. But pretty soon you’ll hit a skill ceiling and get left behind by those who got coaching and practiced their fundamentals.
I definitely agree that a religious adherence to testing takes the fun out of writing software, for me at least.<p>It’s also driven up the cost of development or slows the time needed to release. That may be an obvious but I think because of the religious aspect people often make the leap to trying to get 100% code coverage instead of focusing on their original objectives.
I think about unit testing like “pouring cement around your house of cards”.<p>If you are good at unit testing you can turn your brain off and the tests write themselves. It’s about preserving any method chain call flows and preserving the integrity of anything that is parsing something, like a Regex or whatever.<p>Focus on testing after you have built a nice little house of cards... it will make it harder for another dev to come along and blow it over in the future.
For me unit testing is very useful during development of new code as a way to ensure you cover all of your bases. But unit tests also give false security later down the road that old code still works fine due to the mocks and fixtures used to test with remain fixed in time.<p>Unless you actively update fixture data for all of your unit tests, you can never be sure that all green check marks means everything will work once in production.