cmake:使测试成功通过部分构建过程 [英] cmake: make tests successfully passing part of the build process
问题描述
我在这里使用 add_custom_command
作为 POST_BUILD
步骤运行测试。
)
add_test($ {NAME} $ {NAME})
#使测试作为构建过程的一部分运行
add_custom_command(TARGET $ {NAME} POST_BUILD COMMAND $ {NAME})
endfunction()
这种方法是测试仅在目标构建时运行:
$ make
[50%]
链接CXX可执行文件../../Debug/bin/lib1_test
运行1个测试用例...
main.cpp(8):fatal error:inlib1_test:
严重检查lib1()==lib1失败[错误!= lib1]
***在测试模块Master Test Suite中检测到1个错误
make [2]:*** [lib1 / test / lib1_test]错误201
make [1]:*** [lib1 / test / CMakeFiles / lib1_test.dir / all]错误2
make:*** [all]错误2
如果目标不需要构建,则测试不会运行,并且构建通过。
这里我不做任何更改,只需重新运行构建过程
$ make
[50%]内置目标lib1
[100%]内置目标lib1_test
但是,如果 lib1_test
$ ./lib1/test/lib1_test
运行1个测试用例...
main.cpp ):致命错误:在lib1_test中:
严重检查lib1()==lib1已失败[error!= lib1]
***在测试中检测到1个错误模块主测试套件
要创建一个取决于 lib1_test
的 lib1_test.passed
目标,运行测试,并且仅在测试
我已尝试使用 add_custom_target
创建一个取决于 lib1_test
的目标 lib1_test.passed
如果成功,则创建一个文件 lib1_test.passed
:
add_custom_target $ {NAME} .passed
DEPENDS $ {NAME}
COMMAND $ {NAME}
COMMAND $ {CMAKE_COMMAND} -E touch $ {NAME} .passed)
目前有两个缺点:
- 测试的运行不是正常构建过程的一部分。
也就是说,make
不会 c>lib1_test.passed
;
我必须显式声明make lib1_test.passed
lib1_test.passed
比lib1_test1
更新或
问题:
如何使运行测试成为构建的一部分,总是重新运行?
这里是我到目前为止。实现是相当快速和脏,但尽管如此,它的工作原理。请检查并告诉它是否满足您的需要。
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.12)
project(test)
enable_testing()
set(lib1_SRC lib.c)
add_library(lib1 $ {lib1_SRC})
set(test_SRC test.c)
add_executable(libtest $ {test_SRC})
target_link_libraries(libtest lib1)
add_test(NAME libtest COMMAND libtest)
add_custom_command(
OUTPUT _libtest_completed
COMMAND ctest -C $< CONFIGURATION> - 输出失败
COMMAND cmake -E touch _libtest_completed
DEPENDS libtest
)
add_custom_target(
libtest_force ALL
DEPENDS _libtest_completed
)
源文件为了完整起见:
lib.c: / p>
#includelib.h
#include< time.h>
int lib_func(){
返回时间(NULL)%2;
}
lib.h:
#pragma once
int lib_func();
test.c:
#includelib.h
int main(){
return lib_func();不幸的是,不可能直接依赖 test
$ b 目标,因为 CMake错误,所以我们必须执行手动日落。
I am trying to make the passing of tests part of the build process.
Here I use add_custom_command
to run the test as a POST_BUILD
step.
function(register_test NAME)
add_test(${NAME} ${NAME})
# make the test run as part of the build process
add_custom_command(TARGET ${NAME} POST_BUILD COMMAND ${NAME})
endfunction()
The problem with this approach is that the test is only run when the target is built:
$ make
[ 50%] Built target lib1 Linking CXX executable ../../Debug/bin/lib1_test Running 1 test case... main.cpp(8): fatal error: in "lib1_test": critical check lib1() == "lib1" has failed [error != lib1] *** 1 failure is detected in the test module "Master Test Suite" make[2]: *** [lib1/test/lib1_test] Error 201 make[1]: *** [lib1/test/CMakeFiles/lib1_test.dir/all] Error 2 make: *** [all] Error 2
If the target doesn't need to be built, then the test is not run, and the build passes.
Here I don't make any changes, just rerun the build process
$ make
[ 50%] Built target lib1 [100%] Built target lib1_test
However, if lib1_test
is actually run, the test fails.
$ ./lib1/test/lib1_test
Running 1 test case... main.cpp(8): fatal error: in "lib1_test": critical check lib1() == "lib1" has failed [error != lib1] *** 1 failure is detected in the test module "Master Test Suite"
A better way to do this would be to make a lib1_test.passed
target which depends on lib1_test
, runs the tests, and is only created if the tests pass.
What I have tried:
I have tried using add_custom_target
to create a target lib1_test.passed
which depends on lib1_test
, and if successful, creates a file lib1_test.passed
:
add_custom_target(${NAME}.passed
DEPENDS ${NAME}
COMMAND ${NAME}
COMMAND ${CMAKE_COMMAND} -E touch ${NAME}.passed)
There are 2 shortfalls with what I have currently achieved:
- The running of the test is not part of the normal build process.
That is,make
will not "build"lib1_test.passed
;
I have to explicitly statemake lib1_test.passed
make lib1_test.passed
will always executelib1_test
, regardless of whetherlib1_test.passed
is newer thanlib1_test1
or not
Question:
How can I make the running of tests part of the build, where a failing test will be always rerun?
Here what I've got so far. The implementation is pretty quick and dirty but nevertheless it works. Please check and tell if it satisfies your needs.
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.12)
project(test)
enable_testing()
set(lib1_SRC lib.c)
add_library(lib1 ${lib1_SRC})
set(test_SRC test.c)
add_executable(libtest ${test_SRC})
target_link_libraries(libtest lib1)
add_test(NAME libtest COMMAND libtest)
add_custom_command(
OUTPUT _libtest_completed
COMMAND ctest -C $<CONFIGURATION> --output-on-failure
COMMAND cmake -E touch _libtest_completed
DEPENDS libtest
)
add_custom_target(
libtest_force ALL
DEPENDS _libtest_completed
)
Source files for the sake of completeness:
lib.c:
#include "lib.h"
#include <time.h>
int lib_func() {
return time(NULL) % 2;
}
lib.h:
#pragma once
int lib_func();
test.c:
#include "lib.h"
int main() {
return lib_func();
}
Unfortunately it's impossible to depend directly on test
target due to CMake bug so we have to perform sunset manually.
这篇关于cmake:使测试成功通过部分构建过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!