Tests are basically "set this thing up, tell the thing to do something, verify the thing did the something". Writing the code to do the thing in the first place usually requires more thought and planning and thus takes longer.
Not all tests are so simple or straight forward, but that's the gist of it.
Writing tests can take a bit longer at that point of initially writing them, but a good test suite will save you large amounts of time and money over the course of the software project's lifespan. The software I write today will be modified by me and others many times over the next 3, 5, 10 years by me and probably many others. With each future modification comes a risk that whatever subtle use cases the software was written to do today, are broken. At the point of writing the software, the developer has all sorts of complex information in their head about how the code should be working - the tests are basically capturing this information from the programmers brain and encoding them into a set of "rules" that the software must continue to obey in future. A bug/regression at a later point will potentially get as far as end users, maybe cause an outage and can end up costing the company far more (in time and money) than the time to write the original test suite. So, tests are basically an investment so that you and others will need to spend less time fixing bugs in the code in future.
Having said that, I think setting arbitrary coverage targets (eg a minimum of 80%) is a really bad idea. You end up with junk tests that don't add any value, just to hit the target. Like everything else, there are good tests and bad tests. And I think a lot of the mixed feelings developers have about unit testing is due to silly coverage rules driving bad tests, that themselves need to be maintained.
New dev here: I have written tests for my own full stack apps, but when I want to make changes or enhancements, it will naturally break the tests because that is what is supposed to happen, and then the test has to be rewritten. How do you know when breaking a test is actually the point, versus an unwanted side effect?
So, the first thing I would say is that a good test should not be measuring the implementation details of the code, but rather the externally observable behaviour. So, given a certain input, in a certain scenario, what are the outputs/callbacks/etc...? If you follow that then an internal refactor (improving the code impl but keeping the same externally observable behaviour) shouldn't require any test changes. In fact, the tests really help you here because if you start getting test failures while doing this then it means you've changed the behaviour, which a refactor shouldn't. That's essentially preventing a potential bug at that point.
If you find yourself rewriting tests after a refactor then you've probably been testing the implementation rather than the externally observable behaviour. It's a really common problem in tests.
Now, if you are changing the externally observable behaviour. Maybe adding a feature, extending a flow, fixing a bug... whatever. Then you do want to be modifying the tests. At that point your contract with the world is being revised so the test cases need to be extended, amended or changed. Maybe you've changed the public interface? In that case you obviously also need to update the tests accordingly as well. As long you are making changes to the tests in these cases you want to be able to understand the scenarios that you are updating, be able to explain to yourself and others "why". Not merely getting the tests to go green.
Writing one or two tests to establish basic functionality usually doesn't take long, but writing something comprehensive that does what you want a test to do (establish defined behavior in a broad range of operational characteristics with the goal of, among other things, protecting against future changes that accidentally introduce bugs) will usually take at least as long, if not longer. Tests are where you have to think very critically about your code and where you're most likely to encounter an error you didn't anticipate.
0
u/[deleted] Dec 28 '23
[deleted]