At the start of my career I avoided writing tests wherever possible. I could start my application, and see that it worked for me. Why write tests for something I already know works? I get nothing out of it! This mindset is really okay for your own projects. Where you’re the boss, if you want to work like this and noone else is dependent on it - fine. No worries.
I think about tests radically differently now though. Selfishly, I get a lot out of tests. They save me a lot of time, but they also help me save face. That’s on top of all of the usability and financial benefits for the other developers on the project and the companies I work for.
How do I know this works?
Whenever you introduce new functionality to a repository, someone else is likely going to want to use it. And when they do, there is a chance it doesn’t work for them. Guaranteed. So many issues arise when running code on another computer. From different environments and system variables to missing packages, something will come up. If you push new code without tests demonstrating at least a success case, then it just looks like you committed broken code. That sucks! Especially because it might be a configuration issue on their end. If you committed your new code with a passing test case, you can point to it. If it didn’t work for someone else, maybe it’s a problem on their end. Tell them to go look at the test. What are they doing differently?
By writing that test, you are automating away blame.
Moreover, if I’m a code reviewer for a repository, just looking at the code alone I have absolutely no idea if this thing does what it’s meant to. I would have to read some description of the expected behaviour, pull the code, run the application and then manually test it. At scale, when iteratively developing software, with a team of full-time developers, this is unfeasible. A test does all of these things for you. It describes the things that need to happen, runs the software, and then confirms that it did what was required. Be kind to your code reviewers, and decrease the chances of your pull request being rejected - write tests!
Vanquishing bugs forever
A cool way to think about testing when fixing a bug is this:
When you add a test to your automated test suite that checks for a specific bug, and then you fix that bug, you are vanquishing that bug from the face of the Earth. It will never appear again. Noone else will be able to reintroduce that bug because your regression tests will recognise it forever.
Look how fast this is
Profile before you start making optimisations to existing code. The amount of times I have assumed that a certain part of the code was slow, micro-optimised it like crazy and found that I shaved off almost nothing… is too many. Write tests first, know for certain what the bottleneck is, and then fix it. Save your own time.
And the best part, the most self-boosting thing of all: There is absolutely nothing better than posting a screenshot of a test that used to run in 30 seconds and now runs in under 1 second thanks to your work. Staple that screenshot to the top of your pull request.
I think developers mostly consider testing to be something that is done for someone else. To meet contribution guidelines or appease reviewers. In reality, it serves the developer him/herself more than anyone. It’s a slightly narcissistic idea, but it definitely helps me write better code!