You're almost right, but the main problem is when a team gets obsessed with other issues than actually writing code. You want as little time as possible to be spent on debugging and rewriting. In order to achieve that you need some tools. To avoid rewriting you need some way of specifying what the software is supposed to do before actually making it. UML can be used for that, but it's not a goal in itself. To avoid endless debugging session you need tests, unit tests can be used, but I've found it far more productive to write code that has a lot of debugging code in it. Since I'm mainly writing C/C++, this will be in the form of asserts and #if DEBUG ... #endif, but the main idea is to catch errors as early as possible during program execution. In my experience it's far more productive to get dedicated testers to test end-user functionality and file bugs than to make the programmers who wrote the code write code that checks if the code they wrote did what they thought it should do. The reason is that most bugs occur because the programmers who wrote the code failed to consider some particular corner case when they wrote the code, and they will likewise fail to write a test to test it...
In conclusion, the primary goal is to develop a product, not to write tests, not to make specifications and not to make clean revision histories. However, when used right, specifications, testing and version control enables you to develop the product faster and with higher quality.