I suppose it depends on what you want out of testing. Frequently, unit testing is OK in simple applications. But in an application whose job it is to communicate with a mainframe or back-end databases, frequently the tests you might perform are based on some previous persistent state of the database.
It takes a lot of effort in other words. For example, 2-3 programmers could easily get away (through normal testing) with sharing a database. But generally if you require each programmer to have their own database and their own system completely where they are constantly wiping the state of the database to perform a test suite, this can get time consuming and entails a lot of infrastructural overhead. I've seen some articles that demonstrate doing something with test XML backends to emulate database retrieval results, but these seem quite hard to set up also. I agree that testing is great, but I think it is quite hard in practice. Also, I don't think programmers are good to be the main people to write their own tests. It is "OK" for programmers to write their own tests but frequently it is the user or a non-technical person who is best at doing the unexpected things that are really were the bug lies. The other annoying thing about programmers writing tests is deciding where to stop. I believe the HTTP level for tests is really good. But I see much unit testing being done on the basis of writing a test class for every class you write. Ugh! That means that any time you refactor you throw away the 2x the coding you did. To some degree, there should be intelligent rules of thumb as to which interfaces tests should be written to because the extreme of writing tests for everything is quite bad. Finally, unit tests do not guarantee an understanding of the specs because the business people generally do not read test code. So all the time spent writing the test AND then writing the program AND ONLY THEN showing it to the users, then you discover it wasn't what the user actually wanted. So 2x the coding time has been invalidated when if the user was shown a prototype BEFORE the testing coding commenced, then the user could have confirmed or denied the basic logic. The same frequently and especially is true for UIs. Later, Gunther