BLT has a built-in copy of the Google Test framework (gtest) for C and C++ unit tests and the Fortran Unit Test Framework (FRUIT) for Fortran unit tests.
Each gtest or FRUIT file may contain multiple tests and is compiled into its own executable
that can be run directly or as a make
target.
In this section, we give a brief overview of GTest and discuss how to add unit tests using the blt_add_test
macro.
The contents of a typical Google Test file look like this:
#include "gtest/gtest.h"
#include ... // include headers needed to compile tests in file
// ...
TEST(<test_case_name>, <test_name_1>)
{
// Test 1 code here...
// ASSERT_EQ(...);
}
TEST(<test_case_name>, <test_name_2>)
{
// Test 2 code here...
// EXPECT_TRUE(...);
}
// Etc.
Each unit test is defined by the Google Test TEST()
macro which accepts a
test case name identifier, such as the name of the C++ class being tested,
and a test name, which indicates the functionality being verified by the
test. Within a test, failure of logical assertions (macros prefixed by ASSERT_
)
will cause the test to fail immediately, while failures of expected values
(macros prefixed by EXPECT_
) will cause the test to fail, but will
continue running code within the test.
Note that the Google Test framework will generate a main()
routine for
each test file if it is not explicitly provided. However, sometimes it is
necessary to provide a main()
routine that contains operation to run
before or after the unit tests in a file; e.g., initialization code or
pre-/post-processing operations. A main()
routine provided in a test
file should be placed at the end of the file in which it resides.
Note that Google test is initialized before MPI_Init()
is called.
Other Google Test features, such as fixtures and mock objects (gmock) may be used as well.
See the Google Test Primer for a discussion of Google Test concepts, how to use them, and a listing of available assertion macros, etc.
After writing a unit test, we add it to the project's build system
by first generating an executable for the test using the blt_add_executable()
macro.
We then register the test using the blt_add_test()
macro.
blt_add_test
This macro generates a named unit test from an existing executable and allows users to pass in command line arguments.
Returning to our running example (see :ref:`AddTarget`),
let's add a simple test for the calc_pi
library,
which has a single function with signature:
double calc_pi(int num_intervals);
We add a simple unit test that invokes calc_pi()
and compares the result to \pi, within a given tolerance (1e-6
).
Here is the test code:
.. literalinclude:: tutorial/calc_pi/test_1.cpp :language: cpp :lines: 11-19
To add this test to the build system, we first generate a test executable:
.. literalinclude:: tutorial/calc_pi/CMakeLists.txt :language: cmake :lines: 45-50
Note that this test executable depends on two targets: calc_pi
and gtest
.
We then register this executable as a test:
.. literalinclude:: tutorial/calc_pi/CMakeLists.txt :language: cmake :lines: 52-53
To run the tests, type the following command in the build directory:
$ make test
This will run all tests through cmake's ctest
tool
and report a summary of passes and failures.
Detailed output on individual tests is suppressed.
If a test fails, you can invoke its executable directly to see the detailed output of which checks passed or failed. This is especially useful when you are modifying or adding code and need to understand how unit test details are working, for example.
Note
You can pass arguments to ctest via the TEST_ARGS
parameter, e.g. make test TEST_ARGS="..."
Useful arguments include:
-R | Regular expression filtering of tests.
E.g. -R foo only runs tests whose names contain foo |
-j | Run tests in parallel, E.g. -j 16 will run tests using 16 processors |
-VV | (Very verbose) Dump test output to stdout |
Unit testing in BLT is controlled by the ENABLE_TESTS
cmake option and is on by default.
For additional configuration granularity, BLT provides configuration options
for the individual built-in unit testing libraries. The following additional options are available
when ENABLE_TESTS
is on:
ENABLE_GTEST
- Option to enable gtest (default:
ON
). ENABLE_GMOCK
- Option to control gmock (default:
OFF
). Since gmock requires gtest, gtest is also enabled wheneverENABLE_GMOCK
is true, regardless of the value ofENABLE_GTEST
. ENABLE_FRUIT
- Option to control FRUIT (Default
ON
). It is only active whenENABLE_FORTRAN
is enabled.