Since this is about unit tests in their intended form, I can only agree with you. Unit testing small things tend to cause an insane amount of them to be created in any half-decent application which eventually only become a maintenance nightmare. Nice idea with good intentions, but in my opinion not really “realistic” in the long run. I especially dislike ruling that exists around it, like “if you fix a bug you MUST prove it with a unit test”. Such black and white rules tend to lead to utterly useless tests…
I much prefer to stick to the larger functional tests; in fact they are the tool I use to actually develop most (enterprise) applications; all from the tests (which tend to be in the form of one “happy flow” and a great number of tests that deal with failure paths). I tend to have 90% of the code properly tested before I even deploy a single thing, the remaining 10% is usually configuration and environment related (like FTP transfers not being handled properly, etc. etc.) or something as minor as a mistake in a web resource, and not so often for example an architectural mistake.
The real benefit comes when RFCs come into play that actually alter architecture. After modifying the application I end up with a number of tests that fail because their test conditions no longer apply; usually only tests from the same test suite by the way. Through adapting them to the changes I have a far greater insurance that I actually did it right than if I didn’t have the tests to inform me of my misgivings (and perhaps even design flaws; when it is difficult to get something into a test I treat that as something suspect). Plus I have again the benefit of seeing it all happen by simply running a specific test through testng and seeing what happens under the set conditions, either through logging generated or by stepping through. I wouldn’t have to for example deploy, go through a web interface and follow a very specific routine to get things to happen, the test does it as a sort of prebuilt script.
I don’t diss unit tests entirely, I just don’t use them for what the programming gods intended. In for example graphically oriented applications; be it a game or for example a Swing application, I tend to use them to quickly try out code before I start to see them work when firing up the application/game itself. Just to check the numbers and make sure I didn’t screw up on calculations and such. Call them disposable unit tests - saves plenty of time.