TDD’ing the GUI
Can’t be done, right?
We have some patterns that help us do this: MVP, Passive View, Supervising Controller, Presenter First. Rolling your own implementation of these patterns is challenging and time consuming. Additionally, we haven’t had any frameworks to make it any easier.
So that’s the problem I set out to solve. I’ve reached a point where I’ve been able create a proof of concept application with this framework I’ve been writing. I’m hoping to get some feedback from the community on this.
So what did I do?
I chose to solve the problem using the Passive View pattern. I wanted to be able to design a form with the Delphi form designer but I didn’t want to put any code in the form implementation. That left me with the problem of controlling the GUI from the controller object. Since the point of this exercise is to keep everything testable from a unit test I couldn’t have the controller interacting with the concrete GUI elements. So I came up with the following:
IView = interface
GetViewElement(const ID : string) : IViewElement;
end;
IView has the responsibility of providing access to the view elements to the controller. So the controller can interact with these IViewElement interfaces instead of the concrete GUI elements (like TButton, TEdit, etc.).
What I didn’t want is to have to use special VCL components to make this work. First, because it would be too much trouble to create a full suite of components that implemented IViewElement and second because I wanted to be able retro fit an existing application to this style of design. To accomplish this I did the following:
TGuiAdaptor = class(TInterfacedObject, IViewElement)
public
constructor Create(AControl : TControl)
end;
In GetViewElement the concrete view wraps concrete GUI elements with the TGuiAdaptor and returns it to the controller. So now we can choose to mock the view or, more appropriately to the purpose, use the concrete view for testing.
Having got this far I can now use TDD to express behavioral requirements in the form of unit tests. Have a look at the demo application included in the archive.
Why would I do this?
- I find that using TDD produces better code faster
- Automated testing has been my friend
- I hope I can convince someone at CodeGear that this is style of development is a Good Thing ™ and to enable the IDE to directly support this type of development
Be aware: This is a proof of concept release. I know there’s a great deal more work to go before this would be viable for production.
Here is the code: PassiveViewFramework.rar
Recent Comments