cmake:使测试成功通过部分构建过程 [英] cmake: make tests successfully passing part of the build process

查看:172
本文介绍了cmake:使测试成功通过部分构建过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我在这里使用 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已失败[错误!= 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 不会build 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 state make lib1_test.passed
  • make lib1_test.passed will always execute lib1_test, regardless of whether lib1_test.passed is newer than lib1_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆