Reputation: 20643
This question has been bugging me for a while.
I am looking for a testable architectural design pattern for a MFC application. Please don't tell me MFC is already MVC or something like that because it does not make any sense as long as we can't test the app.
I understand the rule of thumb is to make it View/Document as dumb as possible and make other classes testable. But I want more details on that. How can I make View/Document as dumb as possible and connect them to other testable classes?
First I thought about MVP since I had some success with it for Windows .NET and Android app. But in this MFC case, we need to make Document dumb too. That complicates things.
I need an effective architecture which is maintainable in long term. Any advice from experienced developer would be appreciated.
Upvotes: 4
Views: 1128
Reputation: 12227
You mean MVC? It's there in doc/view architecture but the controller part is somewhat missing. You can still accomplish good things separating GUI from data but the real advantage of separating model from view is that you can use it elsewhere but that doesn't come easy with doc/view to say the least.
Edit: Add on: As for as testing capabilities, MFC application comes with command line processing. You could build on that and send testing commands to the application from command prompt.
Upvotes: 1
Reputation: 20643
I don't think you may need any special design pattern to separate logics from UI. MVP can help but may not be practically necessary. The separation would be enough for testing if you can make your logics into separate dlls or static libraries and make them accessible from other applications. That will be a good start to practically make your logics to be testable.
But even before that, I would find a good testing framework for your development environment. I had some success with Google Testing framework or Boost Testing in case of MFC.
As for design patterns, they are very good to make your program maintainable and maximize code reuse, but I am not sure it's a good practice to use them to make your program testable. Testability is a good property of your program but it may not be the goal of your design.
Upvotes: 0
Reputation: 13065
Testing GUI's ist still a terrible task. There are tools to help you track and replay interactive input. I used some of this API (code stolen from Perl) to inject keypress events into another application (to open a new url in firefox without always open a new tab). But it's not really good enough for testing.
Advanced tools costs multi kilo dollar and come with external script languages and usability reports are divided. http://en.wikipedia.org/wiki/List_of_GUI_testing_tools
There are two different areas in GUI testing. One is filling out dialogs with user options and the other is the model/view testing.
The first can easily solved with a few coding rules. For example dialogs do not modify anything but take and return classes with all the options. In this case you can simply replace the dialog code with your own code. This is the easy part. In my code dialogs modify the ini file settings and then just notify the model with a few hints what has changed.
Testing the view and model is much harder. If it is a about drawing you can try to use the WM_PRINT message to capture the view and then run your test and compare its output with the previous captured data. If the bitmaps are the same the test passes. I've never really seen this technique applied in real world, except in one toolkit where it used it to test pixel exact drawing on multiple platforms.
Next is testing a model based on interactive code. As mentioned before key events are easier to emulate most translate directly to separated command handling code anyway, so you just test the commands not the key event handler. Mouse selection and manipulation, for example object selection on a canvas is much harder. Either use one of this test tools that promise to capture and replay mouse actions or pray.
There are many different ways depending on your own code base, if you abstract from MFC good enough to use mock GUI objects instead of real MFC windows. And if you already embedd a script language which can help you to test things etc. I'm sorry there are no simple pattern. It has to be decided case by case.
My own experience is that i don't like unit testing GUI's and unit testing at all. It's often not worth the time. I'm using Eiffel and Design by Contract (this means lots of assert statements) and do extensive beta tests with customers and let the customers find the remaining bugs. Most bugs are untestable usability bugs anyway.
Upvotes: 2