The answer to the question is:
Unit testing means less development time.
That's the wrong question of course.
Also, an answer to this question really requires a "how do you get to a point where unit testing is giving me benefits" - I cover this in the "my story" portion of my answer.
Here's the real answer:
Unit testing creates a shorter development cycle, it eases refactoring allowing better reuse of existing software, it allows unweildy legacy codebases to be brought under control, and it enables the fast development of high quality software.
It should be a requirement of all investors in public companies that all software in which their company invests time and money that the software include unit tests because it improves the quality of those investments which translates to greater profitability.
Stack exchange wanted to know if I am contributing something new to the conversation.
yes I am.
Early testing - which can only mean unit testing - solves many of the problems that plague managers of software, far beyond the tests themselves.
The excuse that "we have a final test where we check the whole system" is inexcusable and I would fire anyone who worked for me who said that. It's mathematically provable (not here though) that that statement is objectively negligent.
There are studies of software development showing that a bug that makes it to production costs something like 20 times what a bug caught in design costs.
So my story
I worked on a code base that was millions of LOC.
It was well organized, thankfully.
But it had...zero automated tests but lots of manual ones.
Problem:
The knowledge of how to do the manual tests was in the heads of engineers, and engineers leave and retire and die. You can't have your IP in the head of an engineer, but SO MANY organizations do.
Problem:
There were features of this system that were not commonly used, so it took a while to remember how they were supposed to behave.
Problem:
The path for data from acquisition to presentation to end user was convoluted and there were multiple binaries making unpredictable changes to the data, based on other external inputs controlled by other entities.
Problem:
The entire system consisting of some 10s of binaries - maybe 40 - had to be run in order to exercise any portion of the system, due to the required interactions.
Problem:
Every change to the system required a day of testing. Our dev cycle made us afraid to change anything that wasn't absolutely necessary. Consequently we didn't remove dead code, we didn't improve and refactor, and we built up technical debt to unsustainable levels.
Problem:
It was considered impossible to build automated tests. Those who believed this will be proven absolutely wrong by the facts.
Time to problem solve.
Problem:
The entire system consisting of some 10s of binaries - maybe 40 - had to be run in order to exercise any portion of the system, due to the required interactions. This sort of test took up to a day due to the nature of the processing we were doing.
Problem: We have so much to do, how can we take the time to set up the testing environment?
I spent maybe 16 hours researching google test, I downloaded the google test gtest library, it took about 2 hours to figure out how to install it and write my first test and have it included in our build system. Now I was able to test functions without running the whole system.
2 Problems solved. 18 hours.
So the belief that it was "impossible" was wrong. It was possible, if you didn't incorrectly constrain the question to "is it possible to get every single function under a unit test regime".
I just said, "of course it's possible" and I did it.
Then I found places where not only could I write tests, I could use the library to debug problems and speed up my productivity immediately. I had 2 hours back within the day, and in fact by the end of that week I had recovered all 18 hours invested and was up about an hour in productivity, and every week I added 18 hours to that.
Multiply that by my hourly rate and that's how much money I saved the company.
Now I was able to debug more quickly - instead of putting in logging and running the whole system and looking at log files, I just had to write a 10-line test and let the framework handle the details. The test ran in 2 minutes.
Problem: I have existing functions, this isn't greenfield development - if I have to change an existing function how do I make sure I didn't break it?
Problem:
Every change to the system requires a day of testing. Our dev cycle makes us afraid to change anything that's not absolutely necessary. Consequently we don't remove dead code, we don't improve and refactor, and we are building up technical debt to unsustainable levels.
With tests I was able to refactor more confidently - I just wrote tests for the existing function, refactored it, and made sure the refactored function passed the tests. The test runs at compile time, I remove all dead code, i improve and refactor at will, and technical debt never has a chance to build up.
2 Problems solved. Hundreds of thousands of dollars saved.
Problem: How do I test complex functions?
Once I had most of my "leaf-node" functions under test (the ones that didn't require much refactoring to test them and that did not use other functions) I looked at the more complex ones. I picked a library that mostly depended on my leaf-node functions, wrote as many tests as I could for it as is, and then refactored and manually tested functions that were not easily automated. I used mocking and stubbing wherever it helped, and soon I had a complex library refactored, simplified, and testable.
Problem solved.
Problem: How do you get most of the codebase under test?
I continued working through the codebase like that, making sure each investment in test effort returned a benefit immediately.
Problem solved.
Problem:
The knowledge of how to do the manual tests was in the heads of engineers.
Problem:
There were features that were not commonly used, so it took a while to remember how they were supposed to behave.
Now I was able to reproduce tests accurately, and for years to come those tests will be available for others to use. The knowledge of the expected behavior is out of the engineers' heads and is now in written code in a repository. The tests themselves were a few lines of code, so I could put in lots of documentation about how the tests worked.
2 Problems solved.
My conclusion:
Testing (with a good library like gtest) Does not cost anything or take more time.
It is not only free, it has a huge roi on that non-investment.
It costs more and is slower to not unit test.
This is a solved problem folks, let's get to the hard ones please.