1 Step 5: Installing and Testing
2 ==============================
4 .. _`Tutorial Testing Support`:
6 Exercise 1 - Install Rules
7 ^^^^^^^^^^^^^^^^^^^^^^^^^^
9 Often, it is not enough to only build an executable, it should also be
10 installable. With CMake, we can specify install rules using the
11 :command:`install` command. Supporting local installations for your builds in
12 CMake is often as simple as specifying an install location and the targets and
13 files to be installed.
18 Install the ``Tutorial`` executable and the ``MathFunctions`` library.
28 * ``MathFunctions/CMakeLists.txt``
34 The starting code is provided in the ``Step5`` directory. In this
35 exercise, complete ``TODO 1`` through ``TODO 4``.
37 First, update ``MathFunctions/CMakeLists.txt`` to install the
38 ``MathFunctions`` and ``tutorial_compiler_flags`` libraries to the ``lib``
39 directory. In that same file, specify the install rules needed to install
40 ``MathFunctions.h`` to the ``include`` directory.
42 Then, update the top level ``CMakeLists.txt`` to install
43 the ``Tutorial`` executable to the ``bin`` directory. Lastly, any header files
44 should be installed to the ``include`` directory. Remember that
45 ``TutorialConfig.h`` is in the :variable:`PROJECT_BINARY_DIR`.
50 Make a new directory called ``Step5_build``. Run the
51 :manual:`cmake <cmake(1)>` executable or the
52 :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
53 with your chosen build tool.
55 Then, run the install step by using the :option:`--install <cmake --install>`
56 option of the :manual:`cmake <cmake(1)>` command (introduced in 3.15, older
57 versions of CMake must use ``make install``) from the command line. This step
58 will install the appropriate header files, libraries, and executables.
61 .. code-block:: console
65 For multi-configuration tools, don't forget to use the
66 :option:`--config <cmake--build --config>` argument to specify the configuration.
68 .. code-block:: console
70 cmake --install . --config Release
72 If using an IDE, simply build the ``INSTALL`` target. You can build the same
73 install target from the command line like the following:
75 .. code-block:: console
77 cmake --build . --target install --config Debug
79 The CMake variable :variable:`CMAKE_INSTALL_PREFIX` is used to determine the
80 root of where the files will be installed. If using the :option:`cmake --install`
81 command, the installation prefix can be overridden via the
82 :option:`--prefix <cmake--install --prefix>` argument. For example:
84 .. code-block:: console
86 cmake --install . --prefix "/home/myuser/installdir"
88 Navigate to the install directory and verify that the installed ``Tutorial``
94 The install rules for our project are fairly simple:
96 * For ``MathFunctions``, we want to install the libraries and header file to
97 the ``lib`` and ``include`` directories respectively.
99 * For the ``Tutorial`` executable, we want to install the executable and
100 configured header file to the ``bin`` and ``include`` directories
103 So to the end of ``MathFunctions/CMakeLists.txt`` we add:
107 <details><summary>TODO 1: Click to show/hide answer</summary>
109 .. literalinclude:: Step6/MathFunctions/CMakeLists.txt
110 :caption: TODO 1: MathFunctions/CMakeLists.txt
111 :name: MathFunctions/CMakeLists.txt-install-TARGETS
113 :start-after: # install libs
114 :end-before: # install include headers
124 <details><summary>TODO 2: Click to show/hide answer</summary>
126 .. literalinclude:: Step6/MathFunctions/CMakeLists.txt
127 :caption: TODO 2: MathFunctions/CMakeLists.txt
128 :name: MathFunctions/CMakeLists.txt-install-headers
130 :start-after: # install include headers
136 The install rules for the ``Tutorial`` executable and configured header file
137 are similar. To the end of the top-level ``CMakeLists.txt`` we add:
141 <details><summary>TODO 3,4: Click to show/hide answer</summary>
143 .. literalinclude:: Step6/CMakeLists.txt
144 :caption: CMakeLists.txt
145 :name: TODO 3,4: CMakeLists.txt-install-TARGETS
147 :start-after: # add the install targets
148 :end-before: # enable testing
154 That is all that is needed to create a basic local
155 install of the tutorial.
157 Exercise 2 - Testing Support
158 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
160 CTest offers a way to easily manage tests for your project. Tests can be
161 added through the :command:`add_test` command. Although it is not
162 explicitly covered in this tutorial, there is a lot of compatibility
163 between CTest and other testing frameworks such as :module:`GoogleTest`.
168 Create unit tests for our executable using CTest.
173 * :command:`enable_testing`
174 * :command:`add_test`
175 * :command:`function`
176 * :command:`set_tests_properties`
177 * :manual:`ctest <ctest(1)>`
187 The starting source code is provided in the ``Step5`` directory. In this
188 exercise, complete ``TODO 5`` through ``TODO 9``.
190 First, we need to enable testing. Next, begin adding tests to our project
191 using :command:`add_test`. We will work through adding 3 simple tests and
192 then you can add additional testing as you see fit.
197 Navigate to the build directory and rebuild the application. Then, run the
198 ``ctest`` executable: :option:`ctest -N` and :option:`ctest -VV`. For
199 multi-config generators (e.g. Visual Studio), the configuration type must be
200 specified with the :option:`-C \<mode\> <ctest -C>` flag. For example, to run tests in Debug
201 mode use ``ctest -C Debug -VV`` from the build directory
202 (not the Debug subdirectory!). Release mode would be executed from the same
203 location but with a ``-C Release``. Alternatively, build the ``RUN_TESTS``
209 Let's test our application. At the end of the top-level ``CMakeLists.txt``
210 file we first need to enable testing with the
211 :command:`enable_testing` command.
215 <details><summary>TODO 5: Click to show/hide answer</summary>
217 .. literalinclude:: Step6/CMakeLists.txt
218 :caption: TODO 5: CMakeLists.txt
219 :name: CMakeLists.txt-enable_testing
221 :start-after: # enable testing
222 :end-before: # does the application run
228 With testing enabled, we will add a number of basic tests to verify
229 that the application is working correctly. First, we create a test using
230 :command:`add_test` which runs the ``Tutorial`` executable with the
231 parameter 25 passed in. For this test, we are not going to check the
232 executable's computed answer. This test will verify that
233 application runs, does not segfault or otherwise crash, and has a zero
234 return value. This is the basic form of a CTest test.
238 <details><summary>TODO 6: Click to show/hide answer</summary>
240 .. literalinclude:: Step6/CMakeLists.txt
241 :caption: TODO 6: CMakeLists.txt
242 :name: CMakeLists.txt-test-runs
244 :start-after: # does the application run
245 :end-before: # does the usage message work
251 Next, let's use the :prop_test:`PASS_REGULAR_EXPRESSION` test property to
252 verify that the output of the test contains certain strings. In this case,
253 verifying that the usage message is printed when an incorrect number of
254 arguments are provided.
258 <details><summary>TODO 7: Click to show/hide answer</summary>
260 .. literalinclude:: Step6/CMakeLists.txt
261 :caption: TODO 7: CMakeLists.txt
262 :name: CMakeLists.txt-test-usage
264 :start-after: # does the usage message work?
265 :end-before: # define a function to simplify adding tests
271 The next test we will add verifies the computed value is truly the
276 <details><summary>TODO 8: Click to show/hide answer</summary>
278 .. code-block:: cmake
279 :caption: TODO 8: CMakeLists.txt
280 :name: CMakeLists.txt-test-standard
282 add_test(NAME StandardUse COMMAND Tutorial 4)
283 set_tests_properties(StandardUse
284 PROPERTIES PASS_REGULAR_EXPRESSION "4 is 2"
291 This one test is not enough to give us confidence that it will
292 work for all values passed in. We should add more tests to verify this.
293 To easily add more tests, we make a function called ``do_test`` that runs the
294 application and verifies that the computed square root is correct for
295 given input. For each invocation of ``do_test``, another test is added to
296 the project with a name, input, and expected results based on the passed
301 <details><summary>TODO 9: Click to show/hide answer</summary>
303 .. literalinclude:: Step6/CMakeLists.txt
304 :caption: TODO 9: CMakeLists.txt
305 :name: CMakeLists.txt-generalized-tests
307 :start-after: # define a function to simplify adding tests