Google Testの使い方
Google Testとは
正式にはGoogle C++ Testing Frameworkというそうで、Googleが提供するC++用の単体テストの自動実行を可能にするフレイムワークです。
単体テストに関して
そもそも単体テストって何?
単体テストは、プログラムを構成する比較的小さな単位が個々の機能を正しく果たしているかどうかを検証するテストです。
私のようにアカデミックで働いている人間が研究の中で単体テストなんてやる必要あるのか?
必要あります。
単体テストとは文字通りプログラムの部品ごとにその機能をチェックすることです。言い換えれば、単体テストをするためには部品ごとに分解可能なプログラムでなければなりません。残念ながら、アカデミックで作成されたコードのほとんどは、特にコンピュータサイエンスの分野を除き、分解可能という基準を満たしていません。
私のいる学部の先生で、Sandia National Laboratoriesで7年間研究していた方曰く、
99% of academic codes is SHIT!!!
(学究分野で作られたコードの99%はクソだ!)
だそうですw
実際、他学生の作ったコードを再利用して研究をしようとしたとき、ある機能を別の機能に入れ替えたくてもコードがお互いに関係しすぎていてほとんど不可能ということが往々にしてあります。(実は今まさにそんな状況です)
単体テストを行う場合、機能が関数やクラス単位で明確に分離されていなければならず、単体テストを行いながらコードを書いていくことで結果的に綺麗な構造を持ったコードが作られます。綺麗なコードができるということは読みやすいということで、他の人との連携も取りやすくなります。
利用方法
公式ドキュメントにプロジェクト内でGoogle Testを利用する方法が書いてあります。大きく分けて以下の4つの方法があります。
- Googlet Testを手動でダウンロードしてビルドし利用する。
- Google Testをプロジェクト内にコピーして利用する。
- Google Testをgit submoduleに加えて利用する。
- CMakeのconfigureの一環として自動でGoogle Testをダウンロードして利用する。
公式ドキュメントでは4の方法を推奨しています。
Google Testを手動でダウンロードして利用する方法
Google Testのダウンロード
GithubにあるGoogle Testのレポジトリから最新リリースをダウンロードします。ここでは~/Downloads
で作業することにします。2021年7月27日現在の最新バージョンは1.11.0です。
$ cd ~/Downloads
$ wget https://github.com/google/googletest/archive/refs/tags/release-1.12.0.zip
$ unzip release-1.12.0.zip
これでgoogletest-release-1.12.0
というディレクトリができます。
Google Testのビルドとインストール
CMakeとNinjaを事前にインストールしておきましょう。CMake 3.13以上なら下記コマンドでビルドおよびインストールができます。
$ cd googletest-release-1.12.0
$ cmake -S . -B build -G Ninja
$ cmake --build build
$ cmake --install build
管理者権限がなく、ローカルディレクトリにインストールする場合は、CMAKE_INSTALL_PREFIX
でインストールするディレクトリを指定することができます。
$ cmake -S . -B build -G Ninja -DCMAKE_INSTALL_PREFIX=$HOME/.local
テストへリンク
CMakeでfind_package(GTest REQUIRED)
を使えば簡単にGoogle Testを自分のプログラムにリンクできます。CMake 3.20以上の場合はGTest::gtest
およびGTest::gtest_main
を使うことが推奨されています。
cmake_minimum_required(VERSION 3.5)
project(cmake_example CXX)
find_package(GTest REQUIRED)
enable_testing()
# 単体テスト
add_executable(mytest mytest.cpp)
target_link_libraries(mytest
PRIVATE
$<IF:$<VERSION_GREATER_EQUAL:${CMAKE_VERSION},3.20>,
GTest::gtest GTest::gtest_main,
GTest::GTest GTest::Main
>
)
# CTestに単体テストを登録
include(GoogleTest)
gtest_discover_tests(mytest)
CMakeのconfigureの中で自動でGoogle Testをダウンロードさせて利用する方法
CMakeのFetchContentというモジュールを使います。例えばmylibというプロジェクトがあるとします。Google Testを自動でダウンロードするにはCMakeLists.txt
で単体テストを定義する前に以下のスクリプトを追加します。
# GoogleTestをダウンロード
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/refs/tags/release-1.12.0.zip
)
# Google Testの不要なキャッシュ変数をオフにしておく
set(BUILD_GMOCK CACHE BOOL OFF "" FORCE)
set(INSTALL_GTEST CACHE BOOL OFF "" FORCE)
# 親プロジェクトのコンパイラ・リンカ設定を上書きするのを防ぐ(Windowsのみ)
if(WIN32)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
endif()
# googletestをターゲットとして使えるようにする
FetchContent_MakeAvailable(googletest)
そして単体テストを定義するCMakeスクリプトは以下のように書きます。
enable_testing()
# 単体テストの定義
add_executable(MyLibTest MyLibTest.cpp)
target_link_libraries(MyLibTest PRIVATE mylib gtest_main)
# CTestへ単体テストを登録
include(GoogleTest)
gtest_discover_tests(MyLibTest)
使用方法
Google Testドキュメント日本語訳を参照してください。最新版はGitHubの公式ドキュメント(英語)です。。
ざっくりした説明
テスト用ソースコードにgtest/gtest.h
をインクルードします。
#include <gtest/gtest.h>
テストケースを作成します。テストケースの作成方法は
- TEST()マクロを利用する。
- テストフィクスチャを作りTEST_F()マクロを利用する。
の2つがあります。テストフィクスチャは複数のテスト間で同じデータを使用するときに使います。
#include <gtest/gtest.h>
// TESTマクロを使う場合
// 第1引数がテストケース名、第2引数がテスト名
TEST(MyLibraryTest, Function1Test) {
...
}
TEST(MyLibraryTest, Class1Test) {
...
}
#include <gtest/gtest.h>
// テストフィクスチャとTEST_Fマクロを使う場合
class MyLibraryTest : public ::testing::Test {
protected:
// データメンバーの初期化
void SetUp() override {
data1_ = 2.0;
}
// データメンバー
double data1_;
}
// テストフィクスチャを使うには、テストケース名とテストフィクスチャ名が一致していなければならない。
TEST_F(MyLibraryTest, Function1Test) {
double result = Function1(data1_); // data1_にアクセスできる
...
}
TEST_F(MyLibraryTest, Class1Test) {
Class1 obj(data1_); // data1_にアクセスできる
...
}