はじめに
CI環境を個人で構築してみようと考えていて、CIのログに「helloworld」とだけ表示されるのも実益には遠いと思い、CIで実行するためのテストモジュールを作成する環境を先に構築した話です。
やったこと
-
git submodule
でGoogle Testをリポジトリに追加した - CMakeLists.txtでGoogle Testを
add_subdirectory
した - ソースコード用ディレクトリにテスト対象関数として「足し算を行うCの関数」を作成した
- テストコード用ディレクトリに、テストコードを作成した
- CMakeLists.txtでテストモジュールをビルドするようにした
構築後の構成
$ tree
.
└── helloworld
├── CMakeLists.txt
├── Dockerfile
├── include
│ └── calc.h
├── src
│ ├── calc.cpp
│ └── main.cpp
├── test
│ ├── test_calc.cpp
│ └── test_main.cpp
└── third_party
└── gtest
├── (略)
Google Testをリポジトリに追加
cd helloworld
mkdir third_party
cd third_party/
git submodule add git@github.com:google/googletest.git gtest
cd gtest
git checkout release-1.8.1
git add ../../../.gitmodules
git commit
「gtest」という名前をつけた理由を思い出せない。リポジトリ名の「googletest」でいいと思う。release-1.8.1
は2019/09/21地点の最新リリースタグです。
CMakeLists.txtでGoogle Testをadd_subdirectory
add_subdirectory(third_party/gtest/googletest)
これでgoogletestをcmakeで自プロジェクトとともにビルドできるようになる。
足し算を行うCの関数
int add(const int a, const int b);
#include "calc.h"
int add(const int a, const int b) {
return a + b;
}
変数名a, bは関数名から自明だったのでいいかなって・・。
テストコード
#include <gtest/gtest.h>
int main(int argc, char *argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
#include <gtest/gtest.h>
#include "calc.h"
class TestCalc : public ::testing::Test {
};
TEST_F(TestCalc, add) {
EXPECT_EQ(3, add(1, 2));
EXPECT_EQ(-2, add(1, -3));
}
評価用マクロのEXPECT_EQ
などの使い方や類似マクロは、公式の入門ガイドのお世話に良くなります。公式によるとEXPECT_EQ(expected, actual);
なので、第一引数に期待値を入れるように統一すると良いかと思います。
テストモジュール
add_executable(test_calc
test/test_main.cpp
test/test_calc.cpp
src/calc.cpp)
target_link_libraries(test_calc
gtest_main
pthread)
target_include_directories(test_calc PUBLIC
include
third_party/gtest/googletest/include)
pthread
が必要であることがハマリポイントかもしれません。テストに必要なコードとライブラリのみの最小構成ではないかと思います。
実行結果
./test_calc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from TestCalc
[ RUN ] TestCalc.add
[ OK ] TestCalc.add (0 ms)
[----------] 1 test from TestCalc (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.
所感
業務で使用したことがあるので簡単に作れると考えていたところ、細かい記述法を忘れていたりでソラでは書けなかった。知っていることでも、書いてミスして修正しておいて損はないと思った。また、Webからコピペしてきたコードがマイコーディングルールに沿っていなかったことに気づかなかった事案もあったので、lintツールも自分の環境に入れておきたいなと思った。コードも提示するような記事はとても時間がかかることを身を持って知った。