はじめに
googletestをcmakeで動かす必要があったのでまとめました.googletestはc++のテストフレームワークで,cmakeはコンパイラに依存しないビルド自動化のソフトです.tjunさんが既に記事を書いてくれていますが,私は生Makefileはゆとりすぎて読めないのでcmakeで焼き直しました.
GoogleTestでC++のコードをテストする - Qiita
テスト用に簡単なサンプルプロジェクトをgithubにアップしました.READMEに最低限書いてますが,それを説明します.
github.com
プロジェクト構成
今回はこのようなフォルダ構成にしてみました.src/の下にmy_mathという自作のライブラリを作ってあります.それをtest/下のテストクラスで叩いてバグがないか確認してみる,という設定です.
. |-- CMakeLists.txt |-- src | |-- CMakeLists.txt | |-- main.cc | |-- my_math.cc | `-- my_math.h `-- test |-- CMakeLists.txt `-- test.cc
この中のmy_mathライブラリのsum関数はあえて間違って実装しています.
#include "my_math.h" double sqr(double v) { return (v*v); } double sum(double v1, double v2) { return v1 - v2; // Oops! bug! }
cmakeファイル
CMakeLists.txtはフォルダ毎に用意して疎に書いておくのが良いと思っています.
ルート直下のCMakeLists.txt
ここでやっていることはadd_subdirectoryで下位フォルダのCMakeLists.txtを読み込みに行きます.またenable_testingでctestを有効にし,add_testで具体的なテストを指定しています.ctestとはcmakeについているテスト実行の支援ツールです.
cmake_minimum_required(VERSION 2.8) project (MYTEST) add_subdirectory(src) add_subdirectory(test) enable_testing() add_test(NAME MyTest COMMAND Test)
src/のCMakeLists.txt
ここではmy_mathライブラリを作り,mainのプログラムでlibmy_math.aをリンクしています.リンク時のライブラリ名の指定の時に'lib'のプレフィックスは省略できます.またこのlibmy_math.aはテストにも利用します.
cmake_minimum_required(VERSION 2.8) add_library(my_math STATIC my_math.cc) add_executable(demo main.cc) target_link_libraries(demo my_math)
test/のCMakeLists.txt
少し長いですが,難しいことはありません.googletestライブラリのインクルードディレクトリ及びライブラリディレクトリを指定し,test.ccに対してlibgtest.a,libgtest_main.a,pthreadをリンクしているだけです.pthreadはgoogletestで必要になりますので忘れないように.またGTEST_ROOTで指定しているgoogletestのインストールディレクトリは適宜読み替えてください.
cmake_minimum_required(VERSION 2.8) # set runtime directory set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) # declare GTEST_ROOT set(GTEST_ROOT ~/googletest/googletest/) # Include files directory include_directories(${GTEST_ROOT}/include/) # Library directory link_directories(${GTEST_ROOT}/build/) # Generate executable file add_executable(Test ${CMAKE_CURRENT_SOURCE_DIR}/test.cc) # Link libraries target_link_libraries(Test my_math gtest gtest_main pthread)
テストファイルと実行
それではテストファイルです.SqrFuncCheckとSumFuncCheckの2つのテストを用意して,sqrとsum関数をテストしてみます.sum関数の実装は間違っているので,テストは通らないはずです.
#include "../src/my_math.h" #include <gtest/gtest.h> namespace { class MyLibTest : public ::testing::Test{}; TEST_F(MyLibTest, SqrFuncCheck) { EXPECT_EQ(sqr(3.0), 9.0); EXPECT_EQ(sqr(4.0), 16.0); } TEST_F(MyLibTest, SumFuncCheck) { EXPECT_EQ(sum(1.0, 2.0), 3.0); } }
実行してみます.ちゃんと失敗しています.make後にbuild/test/Testを直接叩いても大丈夫です.
$ git clone https://github.com/jojonki/googletest-with-cmake-sample/ $ cd googletest-with-cmake-sample/ $ mkdir build $ cd build $ cmake .. $ make $ make test # or ctest --verbose $ ctest --verbose (略) test 1 Start 1: MyTest 1: Test command: /path/to/googletest-with-cmake-sample/build/test/Test 1: Test timeout computed to be: 9.99988e+06 1: Running main() from gtest_main.cc 1: [==========] Running 2 tests from 1 test case. 1: [----------] Global test environment set-up. 1: [----------] 2 tests from MyLibTest 1: [ RUN ] MyLibTest.SqrFuncCheck 1: [ OK ] MyLibTest.SqrFuncCheck (0 ms) 1: [ RUN ] MyLibTest.SumFuncCheck 1: /path/to/googletest-with-cmake-sample/test/test.cc:13: Failure 1: Expected: sum(1.0, 2.0) 1: Which is: -1 1: To be equal to: 3.0 1: Which is: 3 1: [ FAILED ] MyLibTest.SumFuncCheck (0 ms) 1: [----------] 2 tests from MyLibTest (1 ms total) 1: 1: [----------] Global test environment tear-down 1: [==========] 2 tests from 1 test case ran. (1 ms total) 1: [ PASSED ] 1 test. 1: [ FAILED ] 1 test, listed below: 1: [ FAILED ] MyLibTest.SumFuncCheck 1: 1: 1 FAILED TEST 1/1 Test #1: MyTest ...........................***Failed 0.00 sec 0% tests passed, 1 tests failed out of 1 Total Test time (real) = 0.01 sec The following tests FAILED: 1 - MyTest (Failed) Errors while running CTest
まとめ
cmakeでgoogletestを使ったプロジェクトを作ることができるようになりました.どんどんテストしましょう.googletestをもう少し使い込みたいところです.