# How I add a test that has multiple commands

**URL:** https://discourse.cmake.org/t/how-i-add-a-test-that-has-multiple-commands/13576
**Category:** Code
**Created:** [February 13, 2025, 10:59pm UTC](https://discourse.cmake.org/t/how-i-add-a-test-that-has-multiple-commands/13576 "2025-02-13T22:59:30Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![LegalizeAdulthood](https://discourse.cmake.org/user_avatar/discourse.cmake.org/legalizeadulthood/32/5282_2.png) [@LegalizeAdulthood](https://discourse.cmake.org/u/LegalizeAdulthood)
#### Post date: [February 13, 2025, 10:59pm UTC](https://discourse.cmake.org/t/how-i-add-a-test-that-has-multiple-commands/13576/1 "2025-02-13T22:59:30Z")

</div>

Sometimes you want to run multiple commands as part of a test. For instance, I wanted to:

- Run my program with command-line arguments to generate an image
- Run a program to compare the generated image with a reference image

I wanted my test to fail if either program fails, or if the images were different according to various metrics.

However, [`add_test`](https://cmake.org/cmake/help/latest/command/add_test.html) only takes a single `COMMAND`. I solved this by having the command supplied to `add_test` be a CMake script that I supply with `-D` arguments to communicate variables from my CMakeLists.txt to the test case. I encapsulate this inside a function so that I can easily add tests.

[My CMake script](https://github.com/LegalizeAdulthood/iterated-dynamics/blob/master/tests/images/image_compare_test.cmake) that runs the test (simplified):

```auto
list(APPEND PARAMETERS "savename=${TEST_SAVE_IMAGE}" "savedir=.")

file(REMOVE "${TEST_SAVE_IMAGE}")
execute_process(COMMAND "${ID}" ${PARAMETERS}
    COMMAND_ERROR_IS_FATAL ANY
    COMMAND_ECHO ${COMMAND_ECHO})
file(RENAME "${TEST_SAVE_IMAGE}" "${TEST_KEEP_IMAGE}/${TEST_SAVE_IMAGE}")

execute_process(COMMAND "${IMAGE_COMPARE}" "${GOLD_IMAGE}" "${TEST_KEEP_IMAGE}/${TEST_SAVE_IMAGE}"
    COMMAND_ERROR_IS_FATAL ANY
    COMMAND_ECHO ${COMMAND_ECHO})

```

My CMake helper function that adds the test case by running the script:

```auto
function(add_image_test name)
    cmake_parse_arguments(IMAGE_TEST "" "" "PARAMETERS" ${ARGN})
    list(APPEND IMAGE_TEST_PARAMETERS "batch=yes" "video=F6")
    add_test(NAME ImageTest.${name}
        COMMAND ${CMAKE_COMMAND}
            "-DID=$<SHELL_PATH:$<TARGET_FILE:id>>"
            "-DIMAGE_COMPARE=$<SHELL_PATH:$<TARGET_FILE:image-compare>>"
            "-DGOLD_IMAGE=${CMAKE_CURRENT_SOURCE_DIR}/gold-${name}.gif"
            "-DPARAMETERS=${IMAGE_TEST_PARAMETERS}"
            "-DTEST_SAVE_IMAGE=test-${name}.gif"
            "-DTEST_KEEP_IMAGE=${CMAKE_CURRENT_BINARY_DIR}"
            -P "${CMAKE_CURRENT_SOURCE_DIR}/image_compare_test.cmake"
        WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/home"
    )
    set_tests_properties(ImageTest.${name} PROPERTIES LABELS "image")
endfunction()

```

An example of adding a test case:

```auto
add_image_test(fractint-formula
    PARAMETERS "type=formula" "formulafile=example2.frm" "formulaname=fractint")

```

---

<div class="post-metadata">

### Author: ![benthevining](https://discourse.cmake.org/user_avatar/discourse.cmake.org/benthevining/32/1924_2.png) [@benthevining](https://discourse.cmake.org/u/benthevining)
#### Post date: [February 14, 2025, 7:52pm UTC](https://discourse.cmake.org/t/how-i-add-a-test-that-has-multiple-commands/13576/2 "2025-02-14T19:52:53Z")

</div>

This is the way, you need to run a script that executes your commands

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [February 14, 2025, 10:34pm UTC](https://discourse.cmake.org/t/how-i-add-a-test-that-has-multiple-commands/13576/3 "2025-02-14T22:34:45Z")

</div>

If you need it to be one test, then putting it in a script is what I’d do too. However, you could also consider splitting this into two tests and use a test fixture to express the dependency between the two commands. Make the first test generate the image, and set that test’s FIXTURES\_SETUP property. Make the command that compares images the second test, and set its FIXTURES\_REQUIRED property.

An advantage of this arrangement is that you can easily run either step independently if you ever want to. For example, you might be working on just the part that compares images, so you don’t need to regenerate the same image each time. It will also take care of skipping the image compare step if there’s a problem generating the image.

---

<div class="post-metadata">

### Author: ![kisielk](https://discourse.cmake.org/user_avatar/discourse.cmake.org/kisielk/32/2765_2.png) [@kisielk](https://discourse.cmake.org/u/kisielk)
#### Post date: [February 15, 2025, 5:30pm UTC](https://discourse.cmake.org/t/how-i-add-a-test-that-has-multiple-commands/13576/4 "2025-02-15T17:30:02Z")

</div>

I have a similar setup except using regular tests with their DEPENDS properties. Then if I have many such tests I use a cmake function to generate the test cases and link them together.
