My tests aren’t for me. They are for you… and you, and you, and you!
Writing tests for me isn’t about trying to prove correctness in my program - at least when you get down the core of why I write tests. Sure, while I’m writing the test and before I write the corresponding production code I do so to verify my assumptions about what I’m about to create or edit. This is otherwise known as Test Driven Development. Though TDD keeps me honest, I’m not positive the time and effort spent doing TDD is really worth it if keeping myself honest is the only reason.
The time savings for me ultimately come further down the road. The benefit is gained when I or someone else comes back a week later, or perhaps even or a month later, and makes some changes to production code covered by those tests I wrote during TDD and those changes fail existing tests. That is a sign that what is being coded now is trampling over code that enforces assumptions that have previously been made. If those test failures didn’t occur because the tests weren’t there, or heaven forbid if the tests were inadequate, then you are asking for that new feature/bugfix to be implemented but are then introducing 0..N bugs in the process of doing so.
That’s why I like to have tests. I want my build system and my CI server to a raise a bloody fit if a test breaks.
The tests breaking should be a conversation starter about what expect the code under test to do when those tests fail and then consider how the new feature/bugfix can coexist with or peacefully change the assumptions those failing tests are protecting. That ultimately leads to a cleaner code base, a code base that is more widely understood across the team, and fewer bugs introduced. That’s where the time saved. That is why I write tests.