James W. Grenning provides a process how to get legacy C code into a test harness. This process is also known as the crash-to-pass algorithm. In this repository, you'll find add-ons like tools, examples and tips how to make this process smoother. These add-ons come from the legacy code workshops James and I are running.
Many add-ons should also be useful for writing new code with TDD, that is, for test-driving code. As described, the process is geared towards C code. The post TDD How-To: Get Your legacy C into a Test Harness gives a list of common problems and their solutions for legacy C code. My goal is to provide a similar list for C++, Qt and QML.
The prerequisite to use the add-ons is to clone the repository, say, to /path/to/tdd-training-add-ons
.
git clone https://github.com/bstubert/tdd-training-add-ons.git
Creating a test file is always the first step in the process of getting legacy code under test. This repository provides setup scripts to generate the test file and the CMake files to build and run the first tests. The setup scripts and the generated test project should run on Linux, macOS and Windows.
You want to install the test project in the directory /path/to/project/module-1/tests
. You call the setup script for GoogleTest as follows:
/path/to/tdd-training-add-ons/starter-kits/googletest/setup-googletest /path/to/project/module-1/tests
The script generates the following subtree:
/path/to/project/module-1/tests/
CMakeLists.txt
my_first_test/
CMakeLists.txt
my_first_test.cpp
The first CMakeLists.txt
defines the project TestContainer
, which adds test projects like my_first_test
as subdirectories. You add more test projects in this file.
The second CMakeLists.txt
defines the project my_first_test
with the test file my_first_test.cpp
. You call the function to test from the test function test1
in my_first_test.cpp
or you instantiate a class in test1
. This is the starting point for the crash-to-pass process.
You can build the project TestContainer
on the command line as follows:
$ cd /path/to/project/module-1/tests/
$ mkdir build
$ cd build
$ cmake ..
$ cmake --build .
You run tests with CTest in the build
directory as follows:
$ ctest -V
With the regular expression <regex>
, ctest -V -R <regex>
specifies which test files and test functions to run.
Of course, you can use your favourite IDE (e.g., QtCreator, VS Code, CLion) to write, build and run the tests.
The web site Google Test User's Guide is the starting point for all things Google Test.
QtTest requires that you have installed Qt, say, in /path/to/qt
, which contains the subdirectories bin
, include
, lib
and so on. You best use the same version as for your Qt applications. All Qt5 and Qt6 versions are good enough for testing. You can install Qt with the online installer, you can build Qt from the source tarball (found here and described here) or from the Git repository.
You want to install the test project in the directory /path/to/project/module-1/tests
. You call the setup script for QtTest as follows:
/path/to/tdd-training-add-ons/starter-kits/qttest/setup-qttest /path/to/project/module-1/tests
The script generates the following subtree:
/path/to/project/module-1/tests/
CMakeLists.txt
MyFirstTest/
CMakeLists.txt
MyFirstTest.cpp
The first CMakeLists.txt
defines the project TestContainer
, which adds test projects like MyFirstTest
as subdirectories. You add more test projects in this file.
The second CMakeLists.txt
defines the project MyFirstTest
with the test file MyFirstTest.cpp
. You call the function to test from the test function test1
in MyFirstTest.cpp
or you instantiate a class in test1
. This is the starting point for the crash-to-pass process.
You can build the project TestContainer
on the command line as follows:
$ cd /path/to/project/module-1/tests/
$ mkdir build
$ cd build
$ cmake .. -DCMAKE_PREFIX_PATH=/path/to/qt
$ cmake --build .
You run tests with CTest in the build
directory as follows:
$ ctest -V
With the regular expression <regex>
, ctest -V -R <regex>
specifies which test files and test functions to run.
Of course, you can use your favourite IDE (e.g., QtCreator, VS Code, CLion) to write, build and run the tests.
The web site Qt Test is the starting point for all things Qt Test.
The directory examples
contains some examples how to deal with problems in legacy code. The file examples/CMakeLists.txt
has a list of add_subdirectory
commands for the example projects. Uncomment those examples that you are interested in and comment out those that you are not interested in. Some examples like incompatible-c-cpp do not build. Comment out these examples if you want to run other examples.
You build all examples from the command line with the following commands:
$ cd examples
$ mkdir build
$ cd build
$ cmake ..
$ cmake --build .
The above commands use the default C and C++ compilers and the default Makefile generator of your system. If you need
different build settings, pass the appropriate CMake variables and options to the cmake
calls. You run the tests
with CTest.
$ ctest -V
Of course, you can load examples/CMakeLists.txt
in your favourite IDE (e.g., QtCreator, VSCode, CLion), and
build and run the test projects from there.
The example incompatible-c-cpp
is explained in the post Is the Header Included from extern “C” Compiled as C or C++?.