CMake的:项目结构单元测试 [英] CMake: Project structure with unit tests

查看:331
本文介绍了CMake的:项目结构单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图构建我的项目包括生产源(在的src 子文件夹),并测试(在测试子文件夹)。我使用的CMake建立这个。作为一个小例子,我有以下文件:

的CMakeLists.txt:

  cmake_minimum_required(版本2.8)
项目(TEST)add_subdirectory(SRC)
add_subdirectory(测试)

的src /的CMakeLists.txt:

  add_executable(演示main.cpp中sqr.cpp)

的src / sqr.h

 的#ifndef SQR_H
#定义SQR_H
双SQR(双);
#ENDIF // SQR_H

的src / sqr.cpp

 的#includesqr.h
双SQR(双X){返回X * X; }

的src / main.cpp中 - 使用SQR,并没有真正的问题。

测试/的CMakeLists.txt:

  find_package(升压组件的系统文件系统unit_test_framework必填)include_directories($ {} TEST_SOURCE_DIR / SRC)ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK)add_executable(测试TEST.CPP $ {} TEST_SOURCE_DIR /src/sqr.cpp)target_link_libraries(测试
                      $ {} Boost_FILESYSTEM_LIBRARY
                      $ {} Boost_SYSTEM_LIBRARY
                      $ {} Boost_UNIT_TEST_FRAMEWORK_LIBRARY
                      )enable_testing()
add_test(MyTest的测试)

测试/ TEST.CPP:

 的#define BOOST_TEST_MODULE SqrTests
#包括LT&;升压/测试/ unit_test.hpp>#包括sqr.hBOOST_AUTO_TEST_CASE(FailTest)
{
    BOOST_CHECK_EQUAL(5,SQR(2));
}BOOST_AUTO_TEST_CASE(PassTest)
{
    BOOST_CHECK_EQUAL(4,SQR(2));
}

几个问题:


  1. 这是否构成有意义吗?构建这个code时,什么是最好的做法? (我从C#和Java来了,还有它在一定意义上是比较容易)

  2. 我不喜欢的事实,我必须列出从测试/的CMakeLists.txt的的src 文件夹文件。如果这是一个库项目,我只想链接库。有没有办法避免从其他项目中列出了所有的cpp文件?

  3. 什么是行 enable_testing() add_test(MyTest的测试)在做什么?我还没有看到任何效果。我怎样才能运行CMake的(或CTEST)?测试

  4. 到目前为止,我只是跑 cmake的。在根文件夹,但他创造了无处不在的临时文件乱七八糟。我怎样才能在一个合理的结构,编译结果?


解决方案

有关问题1安培; 2,我会建议让您排除的main.cpp(本例中仅有的src / sqr.cpp和src / sqr.h)非测试文件库,然后你就可以避开上市(更重要的是重新编译)所有来源的两倍。

有关问题3,这些命令添加一个名为MyTest的,它调用可执行的测试不带任何参数的测试。不过,既然你已经添加了这些命令测试/的CMakeLists.txt,而不是顶层的CMakeLists.txt,你只能从构建树的测试子目录中调用测试(试 CD测试&放大器;&安培; CTEST -N )。如果你想测试是从顶层build目录下运行的,你需要从顶层的CMakeLists.txt叫 add_test 。这也意味着你必须使用的更详细的形式<一个href=\"http://www.cmake.org/cmake/help/v2.8.10/cmake.html#command%3aadd_test\"><$c$c>add_test因为你的测试是exe文件不在同一的CMakeLists.txt定义

在你的情况,因为你在根文件夹中运行cmake的,你的构建树,你的源代码树是同一个。这就是所谓的中源构建和不理想,从而导致问题4。

有关生成构建树的preferred方法是做外源的构建,即地方创建一个目录源代码树之外,并从那里执行cmake的。即使是在你的项目的根目录下创建构建目录并执行 cmake的.. 将提供一个干净的结构不会与你的源代码树干扰。

最后一点是要避免调用可执行文件测试(区分大小写)。对于原因,请参见这个答案

要实现这些改变,我会做到以下几点:

的CMakeLists.txt:

cmake_minimum_required(版本2.8)
项目(TEST)
add_subdirectory(SRC)
add_subdirectory(测试)
enable_testing()
add_test(NAME MyTest的命令来测试)



SRC /的CMakeLists.txt:

add_library(SQR sqr.cpp sqr.h)
add_executable(演示main.cpp中)
target_link_libraries(演示SQR)



测试/的CMakeLists.txt:

find_package(升压组件的系统文件系统unit_test_framework必填)
include_directories($ {} TEST_SOURCE_DIR / SRC
                     $ {} Boost_INCLUDE_DIRS
                     )
add_definitions(-DBOOST_TEST_DYN_LINK)
add_executable(测试TEST.CPP)
target_link_libraries(测试
                       SQR
                       $ {} Boost_FILESYSTEM_LIBRARY
                       $ {} Boost_SYSTEM_LIBRARY
                       $ {} Boost_UNIT_TEST_FRAMEWORK_LIBRARY
                       )

I am trying to structure my project to include the production sources (in src subfolder) and tests (in test subfolder). I am using CMake to build this. As a minimal example I have the following files:

CMakeLists.txt:

cmake_minimum_required (VERSION 2.8) 
project (TEST) 

add_subdirectory (src) 
add_subdirectory (test) 

src/CMakeLists.txt:

add_executable (demo main.cpp sqr.cpp) 

src/sqr.h

#ifndef SQR_H
#define SQR_H
double sqr(double);    
#endif // SQR_H

src/sqr.cpp

#include "sqr.h"
double sqr(double x) { return x*x; }

src/main.cpp - uses sqr, doesn't really matter

test/CMakeLists.txt:

find_package(Boost COMPONENTS system filesystem unit_test_framework REQUIRED)

include_directories (${TEST_SOURCE_DIR}/src) 

ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK) 

add_executable (test test.cpp ${TEST_SOURCE_DIR}/src/sqr.cpp) 

target_link_libraries(test
                      ${Boost_FILESYSTEM_LIBRARY}
                      ${Boost_SYSTEM_LIBRARY}
                      ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
                      )

enable_testing()
add_test(MyTest test)

test/test.cpp:

#define BOOST_TEST_MODULE SqrTests
#include <boost/test/unit_test.hpp>

#include "sqr.h"

BOOST_AUTO_TEST_CASE(FailTest)
{
    BOOST_CHECK_EQUAL(5, sqr(2));
}

BOOST_AUTO_TEST_CASE(PassTest)
{
    BOOST_CHECK_EQUAL(4, sqr(2));
}

A few questions:

  1. Does this structure make sense? What are the best practises when structuring this code? (I am coming from C# and java, and there it is easier in a sense)
  2. I don't like the fact that I have to list all the files from the src folder in the test/CMakeLists.txt file. If this was a library project, I would just link the library. Is there a way to avoid listing all the cpp files from the other project?
  3. What are the lines enable_testing() and add_test(MyTest test) doing? I haven't seen any effect. How can I run the tests from CMake (or CTest)?
  4. So far I just ran cmake . in the root folder, but his created a mess with temporary files everywhere. How can I get the compilation results in a reasonable structure?

解决方案

For questions 1 & 2, I would recommend making a library from your non-test files excluding main.cpp (in this case just src/sqr.cpp and src/sqr.h), and then you can avoid listing (and more importantly re-compiling) all the sources twice.

For question 3, these commands add a test called "MyTest" which invokes your executable "test" without any arguments. However, since you've added these commands to test/CMakeLists.txt and not your top-level CMakeLists.txt, you can only invoke the test from within the "test" subdirectory of your build tree (try cd test && ctest -N). If you want the test to be runnable from your top-level build directory, you'd need to call add_test from the top-level CMakeLists.txt. This also means you have to use the more verbose form of add_test since your test exe isn't defined in the same CMakeLists.txt

In your case, since you're running cmake in the root folder, your build tree and your source tree are one and the same. This is known as an in-source build and isn't ideal, which leads to question 4.

The preferred method for generating the build tree is to do an out-of-source build, i.e. create a directory somewhere outside of your source tree and execute cmake from there. Even creating a "build" directory in the root of your project and executing cmake .. would provide a clean structure which won't interfere with your source tree.

One final point is to avoid calling executables "test" (case-sensitive). For reasons why, see this answer.

To achieve these changes, I'd do the following:

CMakeLists.txt:

cmake_minimum_required (VERSION 2.8)
project (TEST)
add_subdirectory (src) 
add_subdirectory (test)
enable_testing ()
add_test (NAME MyTest COMMAND Test)


src/CMakeLists.txt:

add_library (Sqr sqr.cpp sqr.h)
add_executable (demo main.cpp)
target_link_libraries (demo Sqr)


test/CMakeLists.txt:

find_package (Boost COMPONENTS system filesystem unit_test_framework REQUIRED)
include_directories (${TEST_SOURCE_DIR}/src
                     ${Boost_INCLUDE_DIRS}
                     )
add_definitions (-DBOOST_TEST_DYN_LINK)
add_executable (Test test.cpp)
target_link_libraries (Test
                       Sqr
                       ${Boost_FILESYSTEM_LIBRARY}
                       ${Boost_SYSTEM_LIBRARY}
                       ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
                       )

这篇关于CMake的:项目结构单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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