Installing and Testing.rst 8.8 KB

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