4 The main goal of unit tests in |Gromacs| is to help developers while developing
5 the code. They focus on testing functionality of a certain module or a group
6 of closely related modules. They are designed for quick execution, such that
7 they are easy to run after every change to check that nothing has been broken.
9 Finding, building and running
10 -----------------------------
12 As described in :ref:`dev-source-layout`, ``src/gromacs/`` is divided into modules,
13 each corresponding to a subdirectory. If available, unit tests for that module
14 can be found in a ``tests/`` subdirectory under the top-level module directory.
15 Typically, tests for code in :file:`{file}.h` in the module is in a corresponding
16 :file:`tests/{file}.cpp`. Not all files have corresponding tests, as it may not
17 make sense to test that individual file in isolation. Focus of the tests is on
18 functionality exposed outside the module. Some of the tests, in particular for
19 higher-level modules, are more like integration tests, and test the
20 functionality of multiple modules.
21 Shared code used to implement the tests is in ``src/external/googletest/`` and
22 ``src/testutils/`` (see below).
24 The tests are built if ``BUILD_TESTING=ON`` (the default) and
25 ``GMX_BUILD_UNITTESTS=ON`` (the default) in CMake. Each module
26 produces at least one separate unit test binary
27 (:file:`{module}-test`) under ``bin/``, which can execute tests for
30 The tests can be executed in a few different ways:
32 - Build the ``test`` target (e.g., ``make test``):
33 This runs all the tests using CTest. This includes also the regression
34 tests if CMake has been told where to find them (regression tests are not
35 discussed further on this page).
36 If some of the tests fail, this only prints basic summary information (only
37 a pass/fail status for each test binary or regression test class).
38 You can execute the failing test binaries individually to get more
39 information on the failure.
40 Note that ``make test`` does not rebuild the test binaries if you have changed
41 the source code, so you need to separately run ``make`` or ``make tests``.
42 The latter only builds the test binaries and their dependencies.
43 - Build the ``check`` target (e.g., ``make check``):
44 This behaves the same as the ``test`` target, with a few extensions:
46 1. Test binaries are rebuilt if they are outdated before the tests are run.
47 2. If a test fails, the output of the test binary is shown.
48 3. If unit tests and/or regression tests are not available, a message is
51 - The implementation of ``make check`` calls CTest via the ``ctest`` binary
52 to run all the individual test binaries. More fine-grained control is available
53 there, e.g. filtering by test name or label, or increasing verbosity.
54 - Directly executing a test binary. This provides the most useful
55 output for diagnosing failures, and allows debugging test failures.
56 The output identifies the individual test(s) that fail, and shows
57 the results of all failing assertions. Some tests also add extra
58 information to failing assertions to make it easier to identify the
59 reason. Some tests are skipped because they cannot run with the
60 number of MPI ranks or GPU devices detected. Explicit information
61 about such cases can be obtained by using the ``-echo-reasons`` flag
62 to the test binary. It is possible to control which tests are run
63 using command line options. Execute the binary with ``--help`` to
64 get additional information.
66 When executed using CTest, the tests produce XML output in
67 ``Testing/Temporary/``, containing the result of each test as well as failure
68 messages. This XML is used by GitLab CI for reporting the test status for
69 individual tests. Note that if a test crashes or fails because of an assert or
70 a gmx_fatal() call, no XML is produced for the binary, and CI does not
71 report anything for the test binary. The actual error is only visible in the
74 Unit testing framework
75 ----------------------
77 The tests are written using `Google Test`_, which provides a framework for
78 writing unit tests and compiling them into a test binary. Most of the command
79 line options provided by the test binaries are implemented by Google Test. See
80 the `Google Test Primer`_ for an introduction.
81 Some tests also use `Google Mock`_, which provides a framework for creating
82 mock implementations of C++ classes. Both components are included in the
83 source tree under ``src/external/googletest/``, and are compiled as part of the
86 ``src/testutils/`` contains |Gromacs|-specific shared test code. This includes
89 - CMake macros for declaring test binaries. These take care of providing the
90 ``main()`` method for the test executables and initializing the other parts of
91 the framework, so that the test code in modules can focus on the actual
92 tests. This is the only part of the framework that you need to know to be
93 able to write simple tests: you can use ``gmx_add_unit_test()`` in CMake to
94 create your test binary and start writing the actual tests right away.
95 See ``src/testutils/TestMacros.cmake`` and existing CMake code for examples
98 - Generic test fixtures and helper classes. The C++ API is documented on
99 `Doxygen page for testutils`__. Functionality here includes
100 locating test input files from the source directory and constructing
101 temporary files, adding custom command line
102 options to the test binary, some custom test assertions
103 for better exception and floating-point handling, utilities
104 for constructing command line argument arrays, and
105 test fixtures for tests that need to test long strings for correctness
106 and for tests that execute legacy code where
107 ``stdin`` reading etc. cannot be easily mocked.
109 __ doxygen-module-testutils_
111 - Some classes and functions to support the above. This code is for internal
112 use of the CMake machinery to build and set up the test binaries, and to
113 customize Google Test to suit our environment.
115 - Simple framework for building tests that check the results against reference
116 data that is generated by the same test code. This can be used if it is not
117 easy to verify the results of the code with C/C++ code alone, but manual
118 inspection of the results is manageable. The general approach is
119 documented on the `Doxygen page on using the reference data`__.
121 __ doxygen-page-refdata_
123 In addition to ``src/testutils/``, some of the module test directories may
124 provide reusable test code that is used in higher-level tests. For example,
125 the ``src/gromacs/analysisdata/tests/`` provides test fixtures, a mock
126 implementation for gmx::IAnalysisDataModule, and some helper classes
127 that are also used in ``src/gromacs/trajectoryanalysis/tests/``.
128 These cases are handled using CMake object libraries that are linked to all the
129 test binaries that need them.
131 .. _gmx-make-new-tests:
133 Getting started with new tests
134 ------------------------------
136 To start working with new tests, you should first read the `Google Test`_
137 documentation to get a basic understanding of the testing framework, and read
138 the above description to understand how the tests are organized in |Gromacs|.
139 It is not necessary to understand all the details, but an overall understanding
140 helps to get started.
142 Writing a basic test is straightforward, and you can look at existing tests for
143 examples. The existing tests have a varying level of complexity, so here are
144 some pointers to find tests that use certain functionality:
146 - ``src/gromacs/utility/tests/stringutil.cpp`` contains very simple tests for
148 not use any fancy functionality, only plain Google Test assertions.
149 The only thing required for these tests is the ``TEST()`` macro and the block
150 following it, plus headers required to make them compile.
151 - The same file contains also simple tests using the reference framework to
152 check line wrapping (the tests for ``gmx::TextLineWrapper``). The test fixture
153 for these tests is in ``src/testutils/include/testutils/stringtest.h``/``.cpp``. The string test
154 fixture also demonstrates how to add a custom command line option to the
155 test binary to influence the test execution.
156 - ``src/gromacs/selection/tests/`` contains more complex use of the
157 reference framework. This is the code the reference framework was
158 originally written for.
159 ``src/gromacs/selection/tests/selectioncollection.cpp`` is the main file to
161 - For more complex tests that do not use the reference framework, but instead
162 do more complex verification in code, you can look at
163 ``src/gromacs/selection/tests/nbsearch.cpp``.
164 - For complex tests with mock-up classes and the reference framework, you can
165 look at ``src/gromacs/analysisdata/tests/``.
167 Here are some things to keep in mind when working with the unit tests:
169 - Try to keep the execution time for the tests as short as possible, while
170 covering the most important paths in the code under test. Generally, tests
171 should take seconds instead of minutes to run, so that no one needs to
172 hesitate before running the tests after they have done some changes.
173 Long-running tests should go somewhere else than in the unit test set.
174 Note that CI will run the tests in several build configuration and
175 slow tests will significantly slow down the pipelines and can even cause
177 - Try to produce useful messages when a test assertion fails. The assertion
178 message should tell what went wrong, with no need to run the *test itself*
179 under a debugger (e.g., if the assertion is within a loop, and the loop
180 index is relevant for understanding why the assertion fails, it should be
181 included in the message). Even better if even a user can understand what
182 goes wrong, but the main audience for the messages is the developer who
183 caused the test to fail.
185 .. _Google Test: http://code.google.com/p/googletest/
186 .. _Google Test Primer: http://code.google.com/p/googletest/wiki/V1_7_Primer
187 .. _Google Mock: http://code.google.com/p/googlemock/
189 .. include:: /fragments/doxygen-links.rst
194 If your test makes specific requirements on the number of MPI ranks,
195 or needs a communicator as part of its implementation, then there are
196 GROMACS-specific extensions that make normal-looking GoogleTests work
197 well in these cases. Use ``GMX_TEST_MPI(RankRequirement)`` and declare
198 the test with ``gmx_add_mpi_unit_test`` to teach ``CTest`` how to run
199 the test regardless of whether the build is with thread-MPI or real
200 MPI. See ``src/testutils/include/mpitest.h`` for details.