如何在cmake中使用重定向add_test

时间:2016-03-30 09:07:59

标签: cmake makefile integration-testing

我有一个名为" foo"的控制台应用程序,它将参考文本文件作为输入(in.txt)并在标准输出处生成文本(我希望保持此行为)。

在make(不是cmake)中,我使用一个测试目标,它调用foo并将输出重定向到一个文件(out.txt),如下所示。然后,我使用diff将文件out.txt与预期的refernece(ref.txt)进行比较

test:
    ./foo -a test/in.txt > test/out.txt
    diff test/out.txt test/ref.txt

使用make可以正常工作。现在我的问题是; 如何使用cmake创建类似的Makefile?

在名为build的子目录中,我尝试了

project(foo)
...
add_test(NAME test1 COMMAND ./foo ../test/in.txt > ../test/out.txt)
enable_testing()

使用cmake版本3.5,我得到一个没有错误的Makefile,但是当我调用make test时,测试本身就失败了。似乎cmake命令add_test支持命令行参数,但不支持重定向。我尝试了报价并逃脱了成功。由于我无法通过这部分,我没有尝试使用diff。我想象一下,我可以使用&就像你可以用bash做的那样。那将是第二步。

2 个答案:

答案 0 :(得分:5)

将我的评论转化为答案

正如@Tsyvarev所说,CTest命令不在shell的上下文中运行。但你可以自己添加所需的shell并使用例如sh作为使用add_test()调用的命令。

我已经使用您的示例代码运行了一些测试,以下内容确实成功运行:

add_test(NAME test1 COMMAND sh -c "$<TARGET_FILE:foo> ../test/in.txt > ../test/out.txt")

此解决方案不依赖于平台(取决于sh在搜索路径中可用)。

因此,如果您想要更灵活,可以执行以下操作:

include(FindUnixCommands)

file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/test/in.txt" _in)
file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/test/out.txt" _out)
if (BASH)
    add_test(
        NAME test1 
        COMMAND ${BASH} -c "$<TARGET_FILE:foo> ${_in} > ${_out}"
    )
else()
    if (WIN32)
        add_test(
            NAME test1 
            COMMAND ${CMAKE_COMMAND} -E chdir $<TARGET_FILE_DIR:foo> $ENV{ComSpec} /c "$<TARGET_FILE_NAME:foo> ${_in} > ${_out}"
        )
    else()
        message(FATAL_ERROR "Unknown shell command for ${CMAKE_HOST_SYSTEM_NAME}")
    endif()
endif()

此外,还可以使用diff执行更加独立于平台的${CMAKE_COMMAND} -E compare_files <file1> <file2>。因此,您可以使用以下命令简化CMake中基于makefile的完整示例:

add_custom_command(
    TARGET foo
    POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E echo "Running $<TARGET_FILE_NAME:foo> ..."
    COMMAND foo in.txt > out.txt
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test
)

add_test(
    NAME test1 
    COMMAND ${CMAKE_COMMAND} -E compare_files in.txt out.txt
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test
)

<强>参考

答案 1 :(得分:2)

They say你不能:

  

使用add_test参数没有重定向输出。

add_custom_command中的命令不同,后者作为makefile收据的一部分执行(即,在某些 shell 的上下文中),测试由CTest直接执行,没有涉及任何外壳。因此,shell机制不适用于测试。

您可以创建包装脚本,该脚本调用程序,作为参数给出,并执行重定向,进一步diff等等。然后将此脚本(带有适当的参数)用作COMMAND的{​​{1}}。