c++ - CMake:單元測試的項目結構




unit-testing boost (2)

對於問題1和2,我建議從非測試文件(不包括main.cpp)(在本例中只是src / sqr.cpp和src / sqr.h)中創建一個庫,然後避免列出(更重要的是重新編譯)所有源碼兩次。

對於問題3,這些命令會添加一個名為“MyTest”的測試,它會在沒有任何參數的情況下調用可執行文件“test”。 但是,由於您已經添加了這些命令來測試/ CMakeLists.txt而不是您的頂級CMakeLists.txt,因此您只能從構建樹的“test”子目錄中調用測試(嘗試cd test && ctest -N )。 如果您希望測試可以從頂級構建目錄運行,您需要從頂級CMakeLists.txt調用add_test 。 這也意味著您必須使用更詳細的add_test形式,因為您的測試exe未在相同的CMakeLists.txt中定義

就你而言,由於你在根文件夾中運行cmake,所以你的構建樹和源碼樹是一樣的。 這被稱為源內構建,並不理想,這導致問題4。

生成構建樹的首選方法是執行源外構建,即在源樹外創建一個目錄並從那裡執行cmake。 即使在項目的根目錄下創建“build”目錄並執行cmake ..也會提供一個乾淨的結構,不會干擾源代碼樹。

最後一點是避免調用可執行文件“測試”(區分大小寫)。 為什麼,請看這個答案 。

為了實現這些變化,我會做以下事情:

的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)


測試/的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}
                       )

我正在嘗試構建我的項目以包含生產源(在src子文件夾中)和測試(在test子文件夾中)。 我正在使用CMake來構建它。 作為一個最小的例子,我有以下文件:

的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 - 使用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)

測試/ 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,在某種意義上它更容易)
  2. 我不喜歡我必須從test/CMakeLists.txt文件中的src文件夾中列出所有文件的事實。 如果這是一個圖書館項目,我會鏈接圖書館。 有沒有辦法避免從其他項目列出所有的cpp文件?
  3. enable_testing()add_test(MyTest test)在做什麼? 我沒有看到任何效果。 我如何從CMake(或CTest)運行測試?
  4. 到目前為止,我只是跑了cmake . 在根文件夾中,但是這造成了臨時文件到處亂七八糟。 如何在合理的結構中獲得編譯結果?

我喜歡@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)

測試/的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)




boost-test