1. In dynamic languages, simple type mismatches, wrong variable names etc. are now caught in "top level system level test". Yes these are bugs that should have been caught by a compiler had we had one.
2. There's no documentation as to how something should work, or what functionality a module is trying to express.
3. No one dares to refactor anything ==> Code rottens ==> maintenance hell.
4. Bugs are caught by costly human beings (often used to execute "system level tests") instead of pieces of code.
5. When something does break in those "top level system tests", no one has a clue where to look, as all the building blocks of our system are now considered equally broken.
6. It's scary to reuse existing modules, as no one knows if they work or not, outside the scope of the specific system with which they were previously tested. Hence re-invention, code duplication, and yet another maintenance hell.
Did I fail to mention something?
UT cannot assert the correctness of your code. But it will constructively assert its incorrectness.