views:

131

answers:

2

Hi I started writing some tests with Qt's unit testing system.

How do you usually organize the tests? It is one test class per one module class, or do you test the whole module with a single test class? Qt docs (or some podcast that I recently watched) suggested to follow the former strategy.

I want to write tests for a module. The module provides only one class that is going to be used by the module user, but there is a lot of logic abstracted in other classes, which I would also like to test, besides testing the public class.

The problem is that Qt's proposed way to run tests involved the QTEST_MAIN macro:

QTEST_MAIN(TestClass)
#include "test_class.moc"

and eventually one test program is capable of testing just one test class. And it kinda sucks to create test projects for every single class in the module.

Of course, one could take a look at the QTEST_MAIN macro, rewrite it, and run other test classes. But is there something, that works out of the box?

So far I do it by hand:

#include "one.h"
#include "two.h"

int main(int argc, char *argv[]) 
{ 
    QCoreApplication app(argc, argv); 
    TestOne orm;
    QTest::qExec(&one, argc, argv);
    TestOne two;
    QTest::qExec(&two, argc, argv);
}
+1  A: 

Yeah, QTest forces bit strange test structure and is generally inferior to Google Test/Mock Framework. For one project I'm forced to use QTest (client requirement), and here's how I use it:

  1. I compile all test together as a subdir template project
  2. To make creating new tests easier, I share a lot of project configuration by using common.pri file I include in every test .pro file
  3. If possible I share the object files directory to speed up compilation
  4. I run them all using a batch+awk+sed script.

Setting up this four points is very easy and makes usage of QTest almost pleasant. Do you have some problems with running multiple tests that are not solved by the config described above?

PS: running tests the way you do, i.e. calling multiple QTest::qExec causes problems with -o command line switch - you'll get only results for the last tested class.

chalup
+1  A: 

In our setup with QTest, we did a few things to make it nicer. Mostly it revolves around defining a subclass of QObject that is a base unit test class. In the constructor for that class, we add the instance of the test to a static list of tests, and in the destructor remove it. We then have a static function that loops through the tests and runs them using QTest::qExec(). (We accumulate the values returned each time, and return that from our function.) main() calls this function, and returns the result as the success/failure. Finally, in the compilation unit of the specific test itself, we usually include a static instance of that class. This means that the class will be instantiated before main() is run, so it will be added to the list of classes to test when main runs. The framework means that you just need to inherit your class properly, and instantiate a static instance if you always want it run.

We also occasionally create other optional tests, that are added based on command line switches.

Caleb Huitt - cjhuitt