cmakedirectorylocal-variablesctest

CTest: How to set WORKING_DIRECTORY globally?


Recently, I have been building a simple test-suite with CTest. In its most simple form it looked something like this:

cmake_minimum_required(VERSION 3.7)
project(testsuite)
enable_testing()

add_test(NAME test_0
  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  COMMAND script.sh arg-0)

add_test(NAME test_1
  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  COMMAND script.sh arg-1)

add_test(NAME test_2
  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  COMMAND script.sh arg-2)

However, as it was growing, I quickly became tired of having to repeat WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} in every test.

Question: Is there a way to set WORKING_DIRECTORY globally (or, yet better, locally within each test subdirectory)? Something like

cmake_minimum_required(VERSION 3.7)
project(testsuite)
enable_testing()

set(DEFAULT_WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})

add_test(NAME test_0
  COMMAND script.sh arg-0)

add_test(NAME test_1
  COMMAND script.sh arg-1)

add_test(NAME test_2
  COMMAND script.sh arg-2)

The closest to a solution so far is a recommendation of my dear colleague to define a test-generating function:

cmake_minimum_required(VERSION 3.7)
project(testsuite)
enable_testing()

function(add_my_test TEST_NAME TEST_COMMAND TEST_ARGUMENTS)
  add_test(NAME ${TEST_NAME}
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    COMMAND ${TEST_COMMAND} ${TEST_ARGUMENTS})
endfunction()

add_my_test(test_0 script.sh arg-0)
add_my_test(test_1 script.sh arg-1)
add_my_test(test_2 script.sh arg-2)

This works fine but it feels like an unnecessary level of indirection.

In the end, I opted for using a fixture to copy the necessary parts into the build folder, test there and clean up again; this is probably a cleaner and more idiomatic solution. Nevertheless, out of curiosity I would still be interested in a solution to the original problem.


Solution

  • Is there a way to set WORKING_DIRECTORY globally

    No. The default WORKING_DIRECTORY for add_test is specified in documentation.

    This works fine

    Do it. I would do:

    macro(add_my_test)
      add_test(
        WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
        ${ARGV}
      )
    endmacro()
    
    add_my_test(
      NAME test_1
      COMMAND script.sh arg-1
    )
    

    You can also roll your own functionality 'Overwrite' cmake command using a macro and restore its default behavior , but I believe just a wrapper function is great and clean.