TDD is particularly great, though, as it's an in-code description of what the program should do. If it doesn't pass the tests it doesn't do what you thought it should do--ie, there are bugs.
(Of course, then we have to figure out how to write the tests... but hey...)
on the other hand, for (young) programmers learning the latest web 2.0 tools andtweaking if not changing the product frequently, iteration, and thus speed is incredibly useful.
i think both approaches, heavily simplified here, could work--assuming the folks involved aren't just following a recipe but engaging with the process and committed to making it work for their particular circumstance.
It's a much stricter requirement than most people will ever deal with, but wow do you not ever want to get that wrong.
BUT, that general argument, in and of itself, doesn't say testing or strong-typing or asserts whatever is the answer. It seems to me that what is needed is checks that are highly tuned to the situation at hand. Just as simple unit tests are limited, Strong typing is limited to catching a small portion of bugs. I want a language in which I can add only verifications that I need, when I need them and skip the rest. I've never tried it myself but the automatic typing of some functional languages seems like the appropriate next step (and I'm currently programming in a strongly-typed language that is generally a pain in that way).
Except for unit testing, I question most of it. The problem with too much redundancy is that it slows you down. If you create too much ceremony, it takes 20 mediocre programmers to do poorly what 5 good programmers can do well.
I would much prefer good tools to redundancy, for example type inference over Java style type repetition. Maybe you can use asserts as a programming aid, but not in production. If you may get null values, deal with them; try not to create an exception for someone else to deal with. And if we used NASA style coding, it would take 5 years to get a web site up.