CMake:包含公寓测试的项目结构

y1aodyip  于 2022-11-11  发布在  其他
关注(0)|答案(2)|浏览(133)

我试图构建我的项目,使其包含生产源代码(在src子文件夹中)和测试(在test子文件夹中)。我使用CMake来构建这个项目。作为一个最小的示例,我有以下文件:
CMakeLists.txt:

cmake_minimum_required (VERSION 2.8) 
project (TEST) 

add_subdirectory (src) 
add_subdirectory (test)

您可以使用以下命令:

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 -使用sqr,实际上并不重要
测试/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)

测试/测试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));
}

几个问题:
1.这个结构有意义吗?在构造这个代码时,最好的做法是什么?(我来自C#和Java,在某种意义上,这更容易)
1.我不喜欢在test/CMakeLists.txt文件中列出src文件夹中的所有文件。如果这是一个库项目,我会直接链接库。有没有方法可以避免列出其他项目中的所有cpp文件?

  1. enable_testing()add_test(MyTest test)行在做什么?我还没有看到任何效果。我如何从CMake(或CTest)运行测试?
    1.到目前为止,我只是在根文件夹中运行了cmake .,但是这造成了到处都是临时文件的混乱。我如何才能得到结构合理的编译结果呢?
watbbzwu

watbbzwu1#

对于问题1和2,我建议从非测试文件(不包括main.cpp)(在本例中仅包括src/sqr.cpp和src/sqr.h)创建一个库,这样就可以避免两次列出(更重要的是重新编译)所有源代码。
对于问题3,这些命令添加了一个名为“MyTest”的测试,该测试调用您的可执行文件“test”,而不带任何参数。(尝试cd test && ctest -N)。如果您希望测试可以从顶层构建目录运行,您需要从顶层CMakeLists.txt调用add_test。这也意味着您必须使用add_test的更详细的形式,因为您的测试exe不是“在相同的CMakeLists.txt中定义
在你的例子中,因为你在根文件夹中运行cmake,所以你的构建树和源代码树是同一个,这就是所谓的源代码内构建,这并不理想,这就引出了问题4。
生成构建树的首选方法是进行源代码外构建,即在源代码树之外的某个地方创建一个目录,然后从那里执行cmake。即使在项目的根目录中创建一个“build”目录,然后执行cmake ..,也会提供一个干净的结构,不会干扰源代码树。
最后一点是避免调用可执行文件“test”(区分大小写),原因请参见this answer
为了实现这些改变,我会做以下几点:
CMakeLists.txt:

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

您可以使用以下命令:

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

测试/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}
                       )
nimxete2

nimxete22#

我喜欢@Fraser的例子,但是我会在test/CMakeLists.txt中使用add_test命令,并在add_subdirectory(test)之前使用enable_testing。
这样,您就可以在test/CMakeLists.txt中指定测试的同时,从最上层建置目录执行测试。
结果如下所示(我重新使用了@Fraser的示例):
CMakeLists.txt

cmake_minimum_required (VERSION 2.8)
project (TEST)
add_subdirectory (src)

enable_testing ()
add_subdirectory (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}
                       )
add_test (NAME MyTest COMMAND Test)

相关问题