Installing and Testing.rst 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. Step 5: Installing and Testing
  2. ==============================
  3. .. _`Tutorial Testing Support`:
  4. Exercise 1 - Install Rules
  5. ^^^^^^^^^^^^^^^^^^^^^^^^^^
  6. Often, it is not enough to only build an executable, it should also be
  7. installable. With CMake, we can specify install rules using the
  8. :command:`install` command. Supporting local installations for your builds in
  9. CMake is often as simple as specifying an install location and the targets and
  10. files to be installed.
  11. Goal
  12. ----
  13. Install the ``Tutorial`` executable and the ``MathFunctions`` library.
  14. Helpful Materials
  15. -----------------
  16. * :command:`install`
  17. Files to Edit
  18. -------------
  19. * ``MathFunctions/CMakeLists.txt``
  20. * ``CMakeLists.txt``
  21. Getting Started
  22. ---------------
  23. The starting code is provided in the ``Step5`` directory. In this
  24. exercise, complete ``TODO 1`` through ``TODO 4``.
  25. First, update ``MathFunctions/CMakeLists.txt`` to install the
  26. ``MathFunctions`` and ``tutorial_compiler_flags`` libraries to the ``lib``
  27. directory. In that same file, specify the install rules needed to install
  28. ``MathFunctions.h`` to the ``include`` directory.
  29. Then, update the top level ``CMakeLists.txt`` to install
  30. the ``Tutorial`` executable to the ``bin`` directory. Lastly, any header files
  31. should be installed to the ``include`` directory. Remember that
  32. ``TutorialConfig.h`` is in the :variable:`PROJECT_BINARY_DIR`.
  33. Build and Run
  34. -------------
  35. Make a new directory called ``Step5_build``. Run the
  36. :manual:`cmake <cmake(1)>` executable or the
  37. :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
  38. with your chosen build tool.
  39. Then, run the install step by using the :option:`--install <cmake --install>`
  40. option of the :manual:`cmake <cmake(1)>` command (introduced in 3.15, older
  41. versions of CMake must use ``make install``) from the command line. This step
  42. will install the appropriate header files, libraries, and executables.
  43. For example:
  44. .. code-block:: console
  45. cmake --install .
  46. For multi-configuration tools, don't forget to use the
  47. :option:`--config <cmake--build --config>` argument to specify the configuration.
  48. .. code-block:: console
  49. cmake --install . --config Release
  50. If using an IDE, simply build the ``INSTALL`` target. You can build the same
  51. install target from the command line like the following:
  52. .. code-block:: console
  53. cmake --build . --target install --config Debug
  54. The CMake variable :variable:`CMAKE_INSTALL_PREFIX` is used to determine the
  55. root of where the files will be installed. If using the :option:`cmake --install`
  56. command, the installation prefix can be overridden via the
  57. :option:`--prefix <cmake--install --prefix>` argument. For example:
  58. .. code-block:: console
  59. cmake --install . --prefix "/home/myuser/installdir"
  60. Navigate to the install directory and verify that the installed ``Tutorial``
  61. runs.
  62. Solution
  63. --------
  64. The install rules for our project are fairly simple:
  65. * For ``MathFunctions``, we want to install the libraries and header file to
  66. the ``lib`` and ``include`` directories respectively.
  67. * For the ``Tutorial`` executable, we want to install the executable and
  68. configured header file to the ``bin`` and ``include`` directories
  69. respectively.
  70. So to the end of ``MathFunctions/CMakeLists.txt`` we add:
  71. .. raw:: html
  72. <details><summary>TODO 1: Click to show/hide answer</summary>
  73. .. literalinclude:: Step6/MathFunctions/CMakeLists.txt
  74. :caption: TODO 1: MathFunctions/CMakeLists.txt
  75. :name: MathFunctions/CMakeLists.txt-install-TARGETS
  76. :language: cmake
  77. :start-after: # install libs
  78. :end-before: # install include headers
  79. .. raw:: html
  80. </details>
  81. and
  82. .. raw:: html
  83. <details><summary>TODO 2: Click to show/hide answer</summary>
  84. .. literalinclude:: Step6/MathFunctions/CMakeLists.txt
  85. :caption: TODO 2: MathFunctions/CMakeLists.txt
  86. :name: MathFunctions/CMakeLists.txt-install-headers
  87. :language: cmake
  88. :start-after: # install include headers
  89. .. raw:: html
  90. </details>
  91. The install rules for the ``Tutorial`` executable and configured header file
  92. are similar. To the end of the top-level ``CMakeLists.txt`` we add:
  93. .. raw:: html
  94. <details><summary>TODO 3,4: Click to show/hide answer</summary>
  95. .. literalinclude:: Step6/CMakeLists.txt
  96. :caption: CMakeLists.txt
  97. :name: TODO 3,4: CMakeLists.txt-install-TARGETS
  98. :language: cmake
  99. :start-after: # add the install targets
  100. :end-before: # enable testing
  101. .. raw:: html
  102. </details>
  103. That is all that is needed to create a basic local
  104. install of the tutorial.
  105. Exercise 2 - Testing Support
  106. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  107. CTest offers a way to easily manage tests for your project. Tests can be
  108. added through the :command:`add_test` command. Although it is not
  109. explicitly covered in this tutorial, there is a lot of compatibility
  110. between CTest and other testing frameworks such as :module:`GoogleTest`.
  111. Goal
  112. ----
  113. Create unit tests for our executable using CTest.
  114. Helpful Materials
  115. -----------------
  116. * :command:`enable_testing`
  117. * :command:`add_test`
  118. * :command:`function`
  119. * :command:`set_tests_properties`
  120. * :manual:`ctest <ctest(1)>`
  121. Files to Edit
  122. -------------
  123. * ``CMakeLists.txt``
  124. Getting Started
  125. ---------------
  126. The starting source code is provided in the ``Step5`` directory. In this
  127. exercise, complete ``TODO 5`` through ``TODO 9``.
  128. First, we need to enable testing. Next, begin adding tests to our project
  129. using :command:`add_test`. We will work through adding 3 simple tests and
  130. then you can add additional testing as you see fit.
  131. Build and Run
  132. -------------
  133. Navigate to the build directory and rebuild the application. Then, run the
  134. ``ctest`` executable: :option:`ctest -N` and :option:`ctest -VV`. For
  135. multi-config generators (e.g. Visual Studio), the configuration type must be
  136. specified with the :option:`-C \<mode\> <ctest -C>` flag. For example, to run tests in Debug
  137. mode use ``ctest -C Debug -VV`` from the build directory
  138. (not the Debug subdirectory!). Release mode would be executed from the same
  139. location but with a ``-C Release``. Alternatively, build the ``RUN_TESTS``
  140. target from the IDE.
  141. Solution
  142. --------
  143. Let's test our application. At the end of the top-level ``CMakeLists.txt``
  144. file we first need to enable testing with the
  145. :command:`enable_testing` command.
  146. .. raw:: html
  147. <details><summary>TODO 5: Click to show/hide answer</summary>
  148. .. literalinclude:: Step6/CMakeLists.txt
  149. :caption: TODO 5: CMakeLists.txt
  150. :name: CMakeLists.txt-enable_testing
  151. :language: cmake
  152. :start-after: # enable testing
  153. :end-before: # does the application run
  154. .. raw:: html
  155. </details>
  156. With testing enabled, we will add a number of basic tests to verify
  157. that the application is working correctly. First, we create a test using
  158. :command:`add_test` which runs the ``Tutorial`` executable with the
  159. parameter 25 passed in. For this test, we are not going to check the
  160. executable's computed answer. This test will verify that
  161. application runs, does not segfault or otherwise crash, and has a zero
  162. return value. This is the basic form of a CTest test.
  163. .. raw:: html
  164. <details><summary>TODO 6: Click to show/hide answer</summary>
  165. .. literalinclude:: Step6/CMakeLists.txt
  166. :caption: TODO 6: CMakeLists.txt
  167. :name: CMakeLists.txt-test-runs
  168. :language: cmake
  169. :start-after: # does the application run
  170. :end-before: # does the usage message work
  171. .. raw:: html
  172. </details>
  173. Next, let's use the :prop_test:`PASS_REGULAR_EXPRESSION` test property to
  174. verify that the output of the test contains certain strings. In this case,
  175. verifying that the usage message is printed when an incorrect number of
  176. arguments are provided.
  177. .. raw:: html
  178. <details><summary>TODO 7: Click to show/hide answer</summary>
  179. .. literalinclude:: Step6/CMakeLists.txt
  180. :caption: TODO 7: CMakeLists.txt
  181. :name: CMakeLists.txt-test-usage
  182. :language: cmake
  183. :start-after: # does the usage message work?
  184. :end-before: # define a function to simplify adding tests
  185. .. raw:: html
  186. </details>
  187. The next test we will add verifies the computed value is truly the
  188. square root.
  189. .. raw:: html
  190. <details><summary>TODO 8: Click to show/hide answer</summary>
  191. .. code-block:: cmake
  192. :caption: TODO 8: CMakeLists.txt
  193. :name: CMakeLists.txt-test-standard
  194. add_test(NAME StandardUse COMMAND Tutorial 4)
  195. set_tests_properties(StandardUse
  196. PROPERTIES PASS_REGULAR_EXPRESSION "4 is 2"
  197. )
  198. .. raw:: html
  199. </details>
  200. This one test is not enough to give us confidence that it will
  201. work for all values passed in. We should add more tests to verify this.
  202. To easily add more tests, we make a function called ``do_test`` that runs the
  203. application and verifies that the computed square root is correct for
  204. given input. For each invocation of ``do_test``, another test is added to
  205. the project with a name, input, and expected results based on the passed
  206. arguments.
  207. .. raw:: html
  208. <details><summary>TODO 9: Click to show/hide answer</summary>
  209. .. literalinclude:: Step6/CMakeLists.txt
  210. :caption: TODO 9: CMakeLists.txt
  211. :name: CMakeLists.txt-generalized-tests
  212. :language: cmake
  213. :start-after: # define a function to simplify adding tests
  214. .. raw:: html
  215. </details>