CMakeとgtest:gtestの自動ダウンロードとテスト駆動環境の構築

5614 ワード

次のCMake命令はすでに魔法のようにUnixの世界に刻まれている.
./configure
make
make install

前回Bazelとgtest:最も簡単なテスト駆動開発環境を構築する中で、BazelはGithubからgoogletestをダウンロードすることができますが、CMake 3.11にはFetchContentモジュールがあり、同様にネットワークからのダウンロードをサポートしています.
プロジェクト構造
CMakeLists.txt(大文字と小文字に注意)は、最上位ディレクトリのファイルとして、対応するプラットフォームの構築ファイルの生成を指導します.異なるBazelでは、Google家の単体哲学を厳格に使用する必要はないようです.そのため、コードとテスト用例はそれぞれsrctestsのフォルダに配置されます.
├── CMakeLists.txt
├── src
└── tests

CMakeLists.txt
まず、CMakeバージョンの要件と、対応するプロジェクト名:
# 3.11    FetchContent
cmake_minimum_required(VERSION 3.11 FATAL_ERROR)

#     
project(cmake-gtest LANGUAGES CXX)

GoogletestはC++11を要求しているので:
# C++11
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

ソースコードフォルダを追加します.また、ここではヘッダファイルと実装を分割しないので、include_directoriessrcのままです.ヘッダーファイルが露出していない場合、googletestはテストされたコードを取得できません.
include_directories(src)
add_subdirectory(src)

オープンユニットテストを設定します(オプション):
option(ENABLE_UNIT_TESTS "Enable unit tests" ON)
message(STATUS "Enable testing: ${ENABLE_UNIT_TESTS}")

次の内容は、次のifに含まれます.
if (ENABLE_UNIT_TESTS)
#           
endif()
FetchContentモジュールのインポート:
include(FetchContent)

Googletestのバージョンとアドレスを指定します.
FetchContent_Declare(
  	googletest
  	GIT_REPOSITORY https://github.com/google/googletest.git
  	GIT_TAG release-1.10.0
)

CMake 3.14以降は、
FetchContent_MakeAvailable(googletest)

それでいいです.
3.14以前の場合は、より具体的な構築プロセスを使用する必要があります.
	
FetchContent_GetProperties(googletest)

if(NOT googletest_POPULATED)
  	FetchContent_Populate(googletest)
		set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
		set(gtest_disable_pthreads ON CACHE BOOL "" FORCE)
		# add the targets: gtest、gtest_main、gmock、gmock_main
		add_subdirectory(
			${googletest_SOURCE_DIR}
			${googletest_BINARY_DIR}
		)

  endif()

サンプルアイテム
まず簡単なテスト項目を書いて、srcフォルダにCMakeListsを新規作成します.txt、書き込み:
# example library
add_library(sum_integers sum_integers.cpp)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build/bin)
# main code
add_executable(sum_up main.cpp)

target_link_libraries(sum_up sum_integers)

sum_integers.hpp:
#pragma once

#include 
int sum_integers(const std::vector integers);

sum_integers.cpp:
#include "sum_integers.hpp"

#include 

int sum_integers(const std::vector integers)
{
  auto sum = 0;
  for (auto i : integers)
  {
    sum += i;
  }
  return sum;
}

main.cpp
#include 
#include 
#include 

#include "sum_integers.hpp"

int main(int argc, char *argv[])
{
  std::vector integers;
  for (auto i = 1; i < argc; i++)
  {
    integers.push_back(std::stoi(argv[i]));
  }

  auto sum = sum_integers(integers);

  std::cout << sum << std::endl;
  return 0;
}
testsフォルダは非常に簡単です.テストは1つだけです.
test.cpp:
#include "sum_integers.hpp"
#include "gtest/gtest.h"
#include 

TEST(example, sum_zero)
{
  auto integers = {1, -1, 2, -2, 3, -3};
  auto result = sum_integers(integers);
  ASSERT_EQ(result, 0);
}

TEST(example, sum_five)
{
  auto integers = {1, 2, 3, 4, 5};
  auto result = sum_integers(integers);
  ASSERT_EQ(result, 15);
}

なお、gtest_mainは後述するため、テンプレートコードを明示的に使用する必要はありません.
int main(int argc, char **argv)
{
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}


最後に最上位のCMakeLists.txtには、テストのサポートが追加されています(ifendif()の間に配置されています).
add_executable(cpp_test "")
target_sources(cpp_test
	PRIVATE
		tests/test.cpp
)

target_link_libraries(cpp_test
  	PRIVATE
    	sum_integers
    	gtest_main
)

enable_testing()
add_test(
  	NAME google_test
  	COMMAND $
 )

これで最も簡単なgoogletestテストプロジェクトが完成しました.ちなみに、CMake自身が持っているCTestはGoogle Testをサポートしています.
テストの実行
次に、使用の一環として、クラシックな操作に属します.
mkdir -p build
cd build
cmake ..

その後、makeコマンドでプロジェクトを構築できます.
make

テストの実行ctestを使用して、テスト結果(レポート)を直接取得できます.
ctest

出力:
    Start 1: google_test
1/1 Test #1: google_test ......................   Passed    0.02 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   0.04 sec

または、コンパイルされたテストエントリを使用します.
./cpp_test

具体的なテスト状況を出力します.
[==========] Running 2 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 2 tests from example
[ RUN      ] example.sum_zero
[       OK ] example.sum_zero (0 ms)
[ RUN      ] example.sum_five
[       OK ] example.sum_five (0 ms)
[----------] 2 tests from example (0 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 1 test suite ran. (0 ms total)
[  PASSED  ] 2 tests.


小結
現代のCMakeにも自動ダウンロード機能があることを知らない人が多いのではないでしょうか.もちろん、再入力性を引っ張らなければならないなら、ローカルソースが一番頼りです.