我有一个名为" 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做的那样。那将是第二步。
答案 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}}。