我正在尝试将测试的传递作为构建过程的一部分。
在这里,我使用add_custom_command
将测试作为POST_BUILD
步骤运行。
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()
此方法存在的问题是测试仅在构建目标时运行:
$ 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
如果不需要构建目标,则不会运行测试,并且构建通过。
在这里,我不做任何更改,只需重新运行构建过程
$ make
[ 50%] Built target lib1 [100%] Built target lib1_test
但是,如果实际运行lib1_test
,则测试失败。
$ ./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"
更好的方法是创建一个取决于lib1_test.passed
的{{1}}目标,运行测试,并且仅在测试通过时创建。
我尝试了什么:
我尝试使用lib1_test
创建一个取决于add_custom_target
的目标lib1_test.passed
,如果成功,则会创建一个文件lib1_test
:
lib1_test.passed
我目前取得了两个不足之处:
add_custom_target(${NAME}.passed
DEPENDS ${NAME}
COMMAND ${NAME}
COMMAND ${CMAKE_COMMAND} -E touch ${NAME}.passed)
不会"构建" make
; lib1_test.passed
make lib1_test.passed
将始终执行make lib1_test.passed
,无论lib1_test
是否比lib1_test.passed
更新问题:
如何使测试的运行成为构建的一部分,在哪里将始终重新运行失败的测试?
答案 0 :(得分:2)
这是我到目前为止所得到的。实施非常快速和肮脏,但它仍然有效。请检查并告知它是否满足您的需求。
的CMakeLists.txt:
$search_course = "
SELECT title, id, wyl, overview, module, course, careers
FROM course
LEFT JOIN cm
ON course.id=cm.course
WHERE id LIKE '%".$_POST['submitcourseselection']."%'";
$result = $mysqli->query($search_course) or die($mysqli->error);
$display_course = $result->fetch_assoc();
//Searches the module table in the DB for modules within the course
$Search_Module = "
SELECT id, title, level, credits
FROM module
WHERE id LIKE '".$search_course['module']."'";
$M_Results = $mysqli->query($Search_Module) or die($mysqli->error);
$ModuleList = '';
while ($MResults = $M_Results->fetch_assoc()) {
$ID = $MResults['id'];
$Title = $MResults['title'];
$Level = $MResults['level'];
$Credits = $MResults['credits'];
$ModuleList.='<div><h2>'.$Title.'</h2></div>';
}
为了完整起见,源文件:
lib.c:
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
)
lib.h:
#include "lib.h"
#include <time.h>
int lib_func() {
return time(NULL) % 2;
}
test.c的:
#pragma once
int lib_func();
不幸的是,由于CMake bug而无法直接依赖#include "lib.h"
int main() {
return lib_func();
}
目标,所以我们必须手动执行日落。
答案 1 :(得分:0)
如@ user3159253中所示,您需要一个输出文件(带有时间戳),以便构建环境检查是否必须构建&#34;构建&#34;有问题的目标再次出现。因此,如果您的可执行文件已成功构建 - 即使后续运行它的调用失败 - 也不会再次构建。
我想添加一个只有一个目标的解决方案。它将重命名测试可执行输出,运行它 - 如果成功 - 再次将其重命名为其原始名称,以便将其标记为&#34;传递&#34;:
function(register_test NAME)
add_test(NAME ${NAME} COMMAND ${NAME})
set(TMP "$<TARGET_FILE_DIR:${NAME}>/tmp_$<TARGET_FILE_NAME:${NAME}>")
set(ORG "$<TARGET_FILE:${NAME}>")
# make the test run as part of the build process
add_custom_command(
TARGET ${NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E rename "${ORG}" "${TMP}"
COMMAND ${TMP}
COMMAND ${CMAKE_COMMAND} -E rename "${TMP}" "${ORG}"
)
endfunction()