単体テスト フレームワークを cmake に統合する

最近のソフトウェア業界では、自動テストが普及しています。特に大規模なソフトウェアでは、仕様が満たされていることを確認し、回帰バグを防ぐための一連のテストが必要です。この投稿では、なぜテストを行うのかについて退屈させません。代わりに、CMake ビルド システムを使用している場合は、テストをシステムに統合するのがいかに簡単かをお見せします。

このチュートリアルでは、私のディレクトリ構造には 2 つの部分が含まれています:ソース (src 内) サブフォルダー) とテスト (test 内)

私が選んだテスト フレームワークは Catch2 です。ただし、CppUnit、Boost Test Library、doctest、googletest などのさまざまなフレームワークを使用するプロセスは非常に似ているはずです。

セットアップ

まず、main.cpp 以外のすべてのソース コードを追加しました。 common というライブラリに 本番プログラムとテストの両方でリンクします。

./CMakeLists.txt

cmake_minimum_required (VERSION 2.8) 
project (MyAwesomeProject) 

...

add_subdirectory (src)

...

add_executable(MyAwesomeProject src/main.cpp)
target_link_libraries (MyAwesomeProject common)

add_subdirectory (test)

src/CMakeLists.txt

add_library (common a.hpp a.cpp b.hpp)

テスト フレームワークを構成する

test/CMakeLists.txt を作成できます それはテストのものを扱います。その後、単体テスト ライブラリをリポジトリに配置できます。 Catch はヘッダーのみのライブラリであるため、CMake のインターフェイス ライブラリを使用して処理できます。 googletest のようなライブラリの場合は、通常のライブラリとしてリンクするだけです。

# Add catch as an interface library
set(CATCH_INCLUDE_DIR <WHERE YOUR Catch.hpp is>)
add_library(Catch INTERFACE)
target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR})

# Add test executable
add_executable (tests testmain.cpp testA.cpp testB.cpp)
target_link_libraries(tests Catch CommonSourceCode)

代替:CMake 外部プロジェクト

(非推奨) 代替手段は、テスト フレームワークを GitHub から自動的に取得し、それを CMake 外部プロジェクトとして構成することです。このようにして、テスト フレームワークを最新バージョンに更新することを心配する必要はありません。この方法では、CMake が実行されるたびにユニット テスト フレームワークをオンラインで取得しようとするため、インターネットに接続しないとコードをコンパイルできないことに注意してください。

include(ExternalProject)
find_package(Git REQUIRED)

ExternalProject_Add(
    catch
    PREFIX ${CMAKE_BINARY_DIR}/test/catch
    GIT_REPOSITORY https://github.com/philsquared/Catch.git
    TIMEOUT 10
    UPDATE_COMMAND ${GIT_EXECUTABLE} pull
    CONFIGURE_COMMAND ""
    BUILD_COMMAND ""
    INSTALL_COMMAND ""
    LOG_DOWNLOAD ON
   )

# Expose required variable (CATCH_INCLUDE_DIR) to parent scope
ExternalProject_Get_Property(catch source_dir)
set(CATCH_INCLUDE_DIR ${source_dir}/include CACHE INTERNAL "Path to include folder for Catch")

# Add catch as an interface library
add_library(Catch INTERFACE)
target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR})

# Add test executable
add_executable (tests testmain.cpp testA.cpp testB.cpp)
target_link_libraries(tests Catch CommonSourceCode)

ctest サポート

これで、テスト実行可能ファイルを実行して、テスト プログラムを手動で実行できます。コンパイルするたびに実行可能なテストを実行するように IDE を構成することもできます。

それでも、もっとうまくやることができます。 CTest は、CMake が提供するテスト ドライバー プログラムです。 ctest を有効にするには tests を実現するには CMake が必要です 実行可能ファイルはテスト用です。

add_test(NAME tests COMMAND tests)
enable_testing()

CTest を有効にするには 、プロジェクトを定義した後、最上位の CMakeLists ファイルに次の行を追加します。

include(CTest)

パッケージ マネージャー

プロジェクトで Conan や Hunter などのパッケージ マネージャーを使用している場合、ユニット テスト フレームワークの統合は簡単です。ただし、テスト実行可能ファイルをメインの実行可能ファイルと一緒に作成するという考えは引き続き適用されます。

結論

CMake は、業界全体で広く受け入れられているクロスプラットフォーム ビルド ツールです。単体テストや、CI や静的アナライザーなどのその他のサポート ツールを追加するのは非常に簡単です。

C または C++ プロジェクト用の IDE 固有の構成または古き良き Makefile をまだ使用している場合は、CMake の使用方法を学習するのに数時間費やすことをお勧めします。生産の促進になります。


No