Struggling to TDD a GUI application
Oct 28th, 2007 by klimek
CMake is one of the best build tools out there. It has a nice command line interface and comes with an even nicer GUI. Unfortunately the GUI is MFC based, which means you need a VC professional license to build it for windows and you can't use it in linux.
Since Trolltech released it's wonderful GUI framework Qt for windows open source development some time ago, I decided to combine my eagerness to learn TDDing GUI apps with my need for a nice cmake GUI - and to start developing qcmake.
The first priority for me was to learn how to TDD a GUI application. CMakeSetup, the MFC application qcmake should be able to replace, has a very simple single-window interface, so this should be the ideal playground to get an idea of the basic GUI testing problems.
Setting up the testing framework.
The first step to successful TDD is to set up a test environment where you can execute your tests with a single keystroke from within your development environment. I spent some time integrating Qt's testing framework qtestlib into ctest. Hitting F5 from my Visual Studio Express executes all the tests. If something goes wrong, the qtestlib framework prints the debug output into the Visual Studio output window. This way I can just click on the error message to find the offending code, or just enable a breakpoint step through my personal mess...
Top-Down or Bottom-Up - the duck's decision
The testing framework is ready and eagerly waiting for it's first real test. But somehow I don't know where to start. The options are quite simple: either the good ol' bottom-up approach, implementing one layer upon each other until I reach the top, or the top-down development 2.0 methodology where everything is faked or mocked, slicing the whole vegetable vertically until the feature is finished.
Since the top-down approach resembles the design-driven process the most (plus the running tests, minus some heavy documents) and Heusser & McMillan's presentation Interaction Based Testing at GTAC made my mouth water (I really like chocolate flakes), I thought I'd go for the top-down method.
My first user interface test
And finally my first test looks like this:
#include "QCMakeTest.h"
#include "QCMakeWidget.h"
#include <QtTest/QTestMouseEvent>
void QCMakeTest::shouldEmitConfigureSignalOnConfigurePressed()
{
QCMakeUi::QCMakeWidget* qCMake = new QCMakeUi::QCMakeWidget();
QSignalSpy configurePressed(qCMake, SIGNAL(configure()));
QTest::mousePress(qCMake->getConfigureButton(), Qt::LeftButton);
QCOMPARE(configurePressed.count(), 1);
}
QTEST_MAIN(QCMakeTest)
#include "QCMakeTest.moc"
That was a lot of work just to get started with a simple test and basically no functionality. Fortunately I have some TDD experience to build upon, and right now this experience tells me that the up-front effort will pay of in the short run due to not debugging a lot. Up-front effort, quicker development, isn't that what BDUF was all about? I'm curious where all this will lead me to...









