1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
|
CMake Tests/RunCMake Directory
******************************
This directory contains tests that run CMake and/or other tools while
precisely checking their return code and stdout/stderr content.
The RunCMake infrastructure is useful for testing error cases and
diagnostic output.
See also `../README.rst`_, the `CMake Testing Guide`_,
and the `CMake Source Code Guide`_.
.. _`../README.rst`: ../README.rst
.. _`CMake Testing Guide`: ../../Help/dev/testing.rst
.. _`CMake Source Code Guide`: ../../Help/dev/source.rst
.. _`CMakeLists.txt`: CMakeLists.txt
Adding a Test
=============
To add a test:
1. Add a subdirectory named for the test, say ``<Test>/``.
2. In `CMakeLists.txt`_ call ``add_RunCMake_test`` and pass the
test directory name ``<Test>``.
3. Create script ``<Test>/RunCMakeTest.cmake`` in the directory containing::
include(RunCMake)
run_cmake(Case1)
...
run_cmake(CaseN)
where ``Case1`` through ``CaseN`` are case names each corresponding to
an independent CMake run and project configuration.
One may also add calls of the form::
run_cmake_command(CaseI ${CMAKE_COMMAND} ...)
to fully customize the test case command-line.
Alternatively, if the test is to cover running ``ctest -S`` then use::
include(RunCTest)
run_ctest(Case1)
...
run_ctest(CaseN)
and create ``test.cmake.in``, ``CTestConfig.cmake.in``, and
``CMakeLists.txt.in`` files to be configured for each case.
Alternatively, if the test is to cover running ``cpack -G`` then use::
include(RunCPack)
run_cpack(Sample1)
...
run_cpack(SampleN)
where ``Sample1`` through ``SampleN`` are sample project directories
in the ``RunCPack/`` directory adjacent to this file.
4. Create file ``<Test>/CMakeLists.txt`` in the directory containing::
cmake_minimum_required(...)
project(${RunCMake_TEST} NONE) # or languages needed
include(${RunCMake_TEST}.cmake)
where ``${RunCMake_TEST}`` is literal. A value for ``RunCMake_TEST``
will be passed to CMake by the ``run_cmake`` macro when running each
case.
5. Create a ``<Test>/<case>.cmake`` file for each case named
above containing the actual test code. Optionally create files
containing expected test results:
``<case>-result.txt``
Regex matching expected process result, if not ``0``
``<case>-stdout.txt``
Regex matching expected stdout content
``<case>-stderr.txt``
Regex matching expected stderr content, if not ``^$``
``<case>-check.cmake``
Custom result check.
To specify platform-specific matches, create files of the form
``<case>-{stdout,stderr}-<platform_lower_case>.txt``.
Note that trailing newlines will be stripped from actual and expected
test output before matching against the stdout and stderr expressions.
The code in ``<case>-check.cmake`` may use the `RunCMake Variables`_.
On failure the script must store a message in ``RunCMake_TEST_FAILED``.
The check script may optionally set ``RunCMake_TEST_FAILURE_MESSAGE``
with additional text to be included in the message if the test fails.
RunCMake Commands
=================
A ``RunCMakeTest.cmake`` script, after ``include(RunCMake)``, may use
the following commands.
``run_cmake(<case>)``
Run CMake or another command and check expected results described by
``<case>-{result,stdout,stderr}.txt`` and ``<case>-check.cmake``.
The command is executed by a call of the form::
execute_process(
COMMAND ${RunCMake_TEST_COMMAND} ${RunCMake_TEST_OPTIONS}
WORKING_DIRECTORY "${RunCMake_TEST_COMMAND_WORKING_DIRECTORY}"
[TIMEOUT "${RunCMake_TEST_TIMEOUT}"]
...
)
Behavior may be customized by setting `RunCMake Variables`_ before
the call.
``run_cmake_command(<case> <command> <args>...)``
Sets ``RunCMake_TEST_COMMAND`` to ``<command>;<args>...``
and calls ``run_cmake(<case>)``.
This is useful to run an arbitrary command.
``run_cmake_script(<case> <args>...)``
Sets ``RunCMake_TEST_COMMAND`` to
``${CMAKE_COMMAND};<args>...;-P;${RunCMake_SOURCE_DIR}/<case>.cmake``
and calls ``run_cmake(<case>)``.
This is useful to run CMake in script mode without configuring a project.
``run_cmake_with_options(<case> <opts>...)``
Sets ``RunCMake_TEST_OPTIONS`` to ``<opts>...``
and calls ``run_cmake(<case>)``.
``run_cmake_with_raw_args(<case> "<args>")``
Calls ``run_cmake(<case>)`` with the underlying ``execute_process()``
call extended with the content of ``<args>`` treated as literal source
code of CMake language command arguments::
execute_process(
COMMAND ${RunCMake_TEST_COMMAND} ${RunCMake_TEST_OPTIONS} <args>
...
)
This is useful to pass arguments to the test command that cannot be
encoded in CMake language ``;``-separated lists.
RunCMake Variables
==================
The behavior of `RunCMake Commands`_ such as ``run_cmake()`` may be
customized by setting the following variables before a call.
``RunCMake_GENERATOR``
CMake generator to use when configuring projects.
This provided to ``RunCMakeTest.cmake`` scripts automatically
when they are executed, based on the CMake generator used to
configure the test suite.
For some generators, additional variables are also provided:
``RunCMake_GENERATOR_PLATFORM``
Specifies the ``CMAKE_GENERATOR_PLATFORM``.
``RunCMake_GENERATOR_TOOLSET``
Specifies the ``CMAKE_GENERATOR_TOOLSET``.
``RunCMake_GENERATOR_INSTANCE``
Specifies the ``CMAKE_GENERATOR_INSTANCE``.
``RunCMake_GENERATOR_IS_MULTI_CONFIG``
Boolean value indicating whether ``${RunCMake_GENERATOR}`` is a
multi-config generator.
This provided to ``RunCMakeTest.cmake`` scripts automatically
when they are executed, based on the CMake generator used to
configure the test suite.
``RunCMake_SOURCE_DIR``
Absolute path to the ``Tests/RunCMake/<Test>`` directory in
the CMake source tree. This provided to ``RunCMakeTest.cmake``
scripts automatically when they are executed.
``RunCMake_BINARY_DIR``
Absolute path to the ``Tests/RunCMake/<Test>`` directory in
the CMake binary tree. This provided to ``RunCMakeTest.cmake``
scripts automatically when they are executed.
``RunCMake_TEST_SOURCE_DIR``
Absolute path to the individual test case's source tree.
If not set, defaults to ``${RunCMake_SOURCE_DIR}``.
``RunCMake_TEST_BINARY_DIR``
Absolute path to the individual test case's binary tree.
If not set, defaults to ``${RunCMake_BINARY_DIR}/<case>-build``.
``RunCMake_TEST_NO_CLEAN``
Boolean value indicating whether ``run_cmake(<case>)`` should remove the
``${RunCMake_TEST_BINARY_DIR}`` directory before running the test case.
If not set, or if set to a false value, the directory is removed.
This is useful to run `Multi-Step Test Cases`_.
``RunCMake_TEST_COMMAND``
The command for ``run_cmake(<case>)`` to execute.
If not set, defaults to running CMake to generate a project::
${CMAKE_COMMAND} ${RunCMake_TEST_SOURCE_DIR} \
-G ${RunCMake_GENERATOR} ... -DRunCMake_TEST=<case>
``RunCMake_TEST_COMMAND_WORKING_DIRECTORY``
The working directory in which ``run_cmake(<case>)`` to execute its command.
If not set, defaults to ``${RunCMake_TEST_BINARY_DIR}``.
``RunCMake_TEST_OPTIONS``
Additional command-line options for ``run_cmake(<case>)`` to pass to
CMake when configuring a project with a default ``RunCMake_TEST_COMMAND``.
If not set, defaults to empty.
If ``RunCMake_TEST_COMMAND`` is set, ``RunCMake_TEST_OPTIONS`` is forced
to empty.
``RunCMake_TEST_OUTPUT_MERGE``
Boolean value indicating whether ``run_cmake(<case>)`` should redirect
the test process's ``stderr`` into its ``stdout``.
``RunCMake_TEST_TIMEOUT``
Specify a timeout, in seconds, for ``run_cmake(<case>)`` to pass to its
underlying ``execute_process()`` call using the ``TIMEOUT`` option.
Multi-Step Test Cases
=====================
Normally each ``run_cmake(<case>)`` call corresponds to one standalone
test case with its own build tree. However, some test cases may require
multiple steps to be performed in a single build tree. This can be
achieved as follows::
block()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/example-build)
run_cmake(example)
set(RunCMake_TEST_NO_CLEAN 1)
set(RunCMake_TEST_OUTPUT_MERGE 1)
run_cmake_command(example-build ${CMAKE_COMMAND} --build . --config Debug)
endblock()
In this example, ``block() ... endblock()`` is used to isolate the
variable settings from later cases. A single build tree is used for
all cases inside the block. The first step cleans the build tree and
runs CMake to configure the case's project. The second step runs
``cmake --build`` to drive the generated build system and merges the
build tool's ``stderr`` into its ``stdout``. Note that each call uses
a unique case name so that expected results can be expressed individually.
Running a Test
==============
Each call to ``add_RunCMake_test(Example)`` in `CMakeLists.txt`_ creates
a test named ``RunCMake.Example`` that may be run with ``ctest``::
$ ctest -R "^RunCMake\.Example$"
To speed up local testing, you can choose to run only a subset of
``run_cmake()`` tests in a ``RunCMakeTest.cmake`` script by using the
``RunCMake_TEST_FILTER`` environment variable. If this variable is set,
it is treated as a regular expression, and any tests whose names don't
match the regular expression are not run. For example::
$ RunCMake_TEST_FILTER="^example" ctest -R '^RunCMake\.Example$'
This will only run cases in ``RunCMake.Example`` that start with
``example``.
To speed up the process of creating a new ``RunCMake`` test, you can run a
script that will automatically perform steps 1 through 4 for you::
cmake -DRunCMake_TEST_SUITE=<test suite name> -P Tests/RunCMake/AddRunCMakeTestSuite.cmake
Be sure to run this from the top-level CMake source directory.
Crafting Expected Output
========================
There is a `regex debugging`_ tool available to help craft regular expressions
to verify output from tests. See its documentation for more.
.. _`regex debugging`: ../../Utilities/cmredbg/README.rst
|