Search This Blog


Saturday, September 19, 2009

Unit Testing the GUI and the Database

I stumbled upon an interesting question from StackOverflow: Philisophical Questions about Test-Driven Development

  1. How do you handle large changes? When it comes to testing single functions (some parameters, a result value, few side effects), TDD is a no-brainer. But what about when you need to thoroughly overhaul something large, e.g. switching from a SAX parsing library to a DOM parsing library? How do you keep to the test-code-refactor cycle when your code is in an intermediate state? Once you start making the change , you will get a bevy of failed tests until you've fully finished the overhaul (unless you maintain some kind of mongrel class that uses both DOM and SAX until you're done converting, but that's pretty weird). What happens to the small-step test-code-refactor cycle in this case? During this whole process you will no longer be moving in small, fully-tested steps. There must be some way people deal with this.

  2. When testing GUI or database code with mocks, what are you really testing? Mocks are built to return exactly the answer you want, so how do you know that your code will work with the real-world database? What is the benefit of automated tests for this kind of thing? It improves confidence somewhat, but a) it doesn't give you the same level of confidence that a complete unit test ought to, and b) to a certain extent, aren't you simply verifying that your assumptions work with your code rather than that your code works with the DB or GUI?

Here's my answer to the second part of the question:

This is my approach: For database applications, I don't use mock for my unit test. Instead, I run the tests on a real database, albeit a different one than the production database. So in this sense you can say that I don't run unit test on database. For NHibernate applications, I maintain two databases with same schema, but different database type (ORM makes this easy). I use sqlite for my automated testing, and a real MySQL or SQL server database for ad-hoc testing.
Only once did I use mock for unit testing the DAL; and that's when I was using strongly typed dataset as the ORM ( a big mistake!). The way I did this was to have Typemock returned me a mocked copy of the complete table so that I can perform select * on it. Later as I looked back I wished I never do this, but that was long time ago, and I wished I used a proper ORM.
As for the GUI, it is possible to unit test the GUI interaction. The way I did this was to use the MVP pattern to separate out the Model, View and Presenter. Actually for this type of application I test on the Presenter and the Model, in which I use Typemock ( or dependency injection) to isolate the different layers so that at one time I can concentrate on only one layer. I don't test the view, but I do test Presenter ( where the majority of interaction and bugs are happening) a lot .

No comments: