Well written. ++!
I have one nit to pick - unit-testing is still black-box testing. One should be testing against the published interface and verifying that the code performs according to spec. Of course, this assumes that one has both well-defined interfaces and a well-defined spec (including error-cases) to work off of.
TDD has a very similar point of view, changing only that the unit-tests combined with the user stories are the spec. The system/integration testing and UAT phases are more verification of the user stories + validation that the user stories are correct. In the terms of the Pragmatic Programmer, TDD is tracer bullets on steroids, with UAT being the iteration.
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?