"Dave, I think you're using the term "unit testing" to refer to all kinds of testing. It's not -- there are tons of different testing techniques besides unit testing. Yes, unit testing tests variation of inputs, and traditional QA testing tests variation of inputs, and the difference between the two is a matter of scale."
Actually, I'm thinking of the Unit Testing environments I use on a daily basis to get my work done: JUnit, NUnit and RUnit, from the command line and inside Eclipse. I'm thinking of a variety of "asserts" I've written for load testing iterations through large recordset returns, using Schema objects and SQL to test for constraints, missing foreign keys, missing relational records, any number of weird edge cases I can think of.
Can I think of all of them, all the time? No. Have I EVER thought of a database or filesystem situation that I couldn't test for with an assertion from any one of the libraries I've mentioned?
"It is bad testing practice to verify that an API call results in such-and-such database modifications and such-and-such XML being sent over the network. Because that's testing implementation details, details which are the first things to break once any refactoring happens. You should test what goes IN to an API and what comes OUT of it only."
This is another Red Herring. Yes, Unit Testing only guarantees that -- Shock! -- the I/O for the method in question is correct. It doesn't guarantee integration will be perfect and it doesn't put QA departments all over the world out of work. We know this.
But if there's an edge case you're worried about -- missing PKID's, missing constraints, missing records, questions of volume (maybe not TDD best practice, but I can do it, so sue me), in general you can write an assertion for it, and the overhead for doing so is minimal. It literally takes me seconds to write a decent unit test for 99% of the methods I code. And then after that it saves me many minutes, maybe hours, as I don't have to run the whole exe to test any changes -- I just have to compile the class and its test class and execute the test. No clicking through GUIs, no setting up watch varibles or breakpoints, no relying on my own "eyeballing" of the output through several iterations, hoping I remembered to check everything the same every time. Unit Testing simply automates and speeds up the things I'd be doing anyway.
Yes, if the recordsets are large and complex, the setups will take a little longer, but, once again, this is NOT the fault of the unit tests. The tests are STILL making my life easier by AUTOMATING what I'd be DOING ANYWAY.