Extreme Programming with QtTest
-
I'm a believer in the XP model of software development, which is basically that for every new feature or bug fix, these steps are followed:
- Write a unit test for the feature/bug
- Confirm that the test fails (because you haven't implemented the feature or fixed the bug yet)
- Implement the feature/fix the bug
- Confirm that the test now passes
- Refactor the test code and/or application code if needed
- Confirm the test still passes
- Commit code to source repository
I'd like to use QtTest for my unit tests because it's already there in Qt and doesn't require me to install/set up another unit testing utility. As far as I can tell, though, QtTest doesn't seem suited for this task. XP involves very fast iteration and running your test suite constantly, but QtTest has two main problems which is that it requires a main function and therefore must exist as a completely separate program from your main application, and also that to write tests for a large project, it requires either all the tests to be contained in a single QtTest class, which becomes unwieldy, or to have a number of separate QtTest classes, all of which must have a main function and therefore be kept separate from each other.
Has anyone come up with an elegant solution to using QtTest as their unit testing library that allows them to easily run their entire suite of tests, possibly as part of the build procedure? Or should I just go use CppUnit or some other solution?
-
QTestLib only does the testing part, not the running part. There's a small "test.pl" script in the Qt sources that just runs all the tests in a subdir and puts XML reports into a directory. Another option would be a CI system that runs the tests and reports automatically when a developer commits something into his own branch.
-
I consider the QtTestlib way of having many small tests to be great, especially when you need fast turnaround times. It is way easier to run tests/foo/bar to test the bar functionality of the foo module than to fight with command line parameters to get the same result from one gigantic test application. And you do not want to run all tests when working on the bar functionality, do you?
Running all tests is very straight forward, too: Just use a script to execute all executables found in the directory containing your tests or use a continuous integration system (which does make sense anyway:-). Some buildsystems even automatically set up a target for you to run all your tests (e.g. CMake) and upload the results to some central server.
Finally nobody stops you from including tests into your application: Check the documentation in QTest::qExec(...).
-
Any example practices inside Qt code itself to follow this ?. Because i'm having difficulty to use qtestlib as a part of unit testing when I've nested qgraphicswidgets in application.
Any inputs about using this for nested qgraphicswidget is appreciated ( I've 4 levels of controls) -
Ahem ;-)
For the question of how to run the entire test suite in one go, assuming you are using QMake, the correct answer is: If you mark an executable as a test case by adding
@
CONFIG += testcase
@to the .pro file, it will be added for execution by the make check target. The test suite is represented by what make check executes, and contains all the unit test binaries marked as a test case. If any of the tests fail, make check returns an error code as expected, so this can be hooked into a CI system. For information on how to set the necessary library paths, see here: https://www.agile-workers.com/web/2012/05/qmake-unit-tests-dynamic-libraries
The second question is how to create test executables that contain the application code. There multiple ways to do that. They all depend on the overall application code being written in a way where inter-dependencies are minimized. That is good practice anyway. Your options are:
- Use a convenience library that contains all application code, and separate the applications main() function from it. Now you can create a test that links this library, and has access to all the code but main().
- Create a .pri file that contains all your application sources except main, and include it both for the application and the test. The advantage is that you need no convenience library. The disadvantage is that your sources will be compiled multiple times for each target.