1. ホーム
  2. c++

[解決済み] CMake:ユニットテストによるプロジェクト構造

2022-04-22 13:16:54

質問

私はプロジェクトを構成して、プロダクション・ソース ( 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 を使用していますが、特に問題ではありません。

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));
}

少し質問です。

  1. この構成は意味があるのでしょうか?このコードを構造化する際のベストプラクティスは何でしょうか?(私はC#とJavaから来たのですが、そちらの方がある意味簡単です)
  2. のファイルをすべてリストアップしなければならないのが気に入らない。 src フォルダーを test/CMakeLists.txt ファイルを作成します。これがライブラリプロジェクトであれば、ライブラリをリンクすればいいのですが。他のプロジェクトのすべてのcppファイルをリストアップしないようにする方法はないでしょうか?
  3. という行は何ですか? enable_testing()add_test(MyTest test) しているのか?私は何の効果も見ていません。CMake(またはCTest)からテストを実行するにはどうすればよいですか?
  4. 今のところ、私はただ cmake . をルートフォルダに置くと、一時ファイルがあちこちにできてしまい、混乱します。どうすればコンパイル結果を合理的な構造にできるのでしょうか?

どのように解決するのですか?

質問 1 と質問 2 については、main.cpp を除くテスト以外のファイル (この場合は src/sqr.cpp と src/sqr.h) からライブラリを作成することをお勧めします。

質問3について、これらのコマンドは "MyTest" というテストを追加し、実行ファイル "test" を引数なしで呼び出すものです。 しかし、これらのコマンドはトップレベルの CMakeLists.txt ではなく test/CMakeLists.txt に追加されているので、ビルドツリーの "test" サブディレクトリからしかテストを呼び出すことができません (試しに cd test && ctest -N ). もし、トップレベルのビルドディレクトリからテストを実行できるようにしたいのであれば、そのために add_test をトップレベルの CMakeLists.txt から取得します。 これはまた、より冗長な形式である add_test テスト用の実行ファイルが同じ CMakeLists.txt で定義されていないためです。

あなたの場合、ルートフォルダでcmakeを実行しているため、ビルドツリーとソースツリーが同一になっています。 これはインソースビルドと呼ばれるもので、理想的ではありません。

ビルドツリーを生成するための好ましい方法は、アウトオブソースビルド、つまり、ソースツリーの外のどこかにディレクトリを作成し、そこからcmakeを実行することです。 プロジェクトのルートに "build" ディレクトリを作成して cmake .. を使えば、ソースツリーに干渉しないきれいな構造を提供することができます。

最後のポイントは、実行ファイルを "test" と呼ばないことです (大文字と小文字を区別します)。 その理由については この回答 .

このような変更を実現するために、私なら次のようにします。

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