27
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Makefileに書くだけでOK! C++で簡単にGoogle testを始めよう

Last updated at Posted at 2021-11-23

はじめに

一緒に42Tokyoで勉強しているyaitoさんにGoogle testの書き方を教えてもらったので、許可を取って書き方をまとめました!

yaitoさん、ありがとうございます\(^o^)/

結論!

結論から言います。gtestディレクトリを作成し、gtest.cppというファイル名でtestを記載し、このMakefileを使えばOKです。

簡単なサンプルを記述したレポジトリを用意したので、クローンしてmake test試してみてください。

kohkubo/google_test_sample

Makefile

gtestdir	=	./test
gtest		=	$(gtestdir)/gtest $(gtestdir)/googletest-release-1.11.0

testdir = ./gtest

$(gtest):
	curl -OL https://github.com/google/googletest/archive/refs/tags/release-1.11.0.tar.gz
	tar -xvzf release-1.11.0.tar.gz googletest-release-1.11.0
	$(RM) -rf release-1.11.0.tar.gz
	python googletest-release-1.11.0/googletest/scripts/fuse_gtest_files.py $(gtestdir)
	mv googletest-release-1.11.0 $(gtestdir)

test_compile = clang++ -std=c++11 \
	$(testdir)/gtest.cpp $(gtestdir)/googletest-release-1.11.0/googletest/src/gtest_main.cc $(gtestdir)/gtest/gtest-all.cc \
	-I$(gtestdir) -I$(includes) -lpthread -o tester

.PHONY: test
test: $(gtest)
	$(test_compile)
	./tester # --gtest_filter=Vector.other

testの書き方

後はGoogletest Primer | GoogleTestなどのドキュメントを参考にガンガンテストを書いていけばOKです。

#include <gtest/gtest.h>
#include <vector>

TEST(Vector, Constructor) {
  std::vector<int> v;
  EXPECT_EQ(v.size(), 0);
  EXPECT_EQ(v.size(), 1);
}

Makefileで行っていること

google testのレポジトリをクローンしてきて、用意されたfuse_gtest_files.pyを実行しています。

Google testの実装は、約30個のファイルから構成されています。それらを一括して使えるgtest/gtest.hgtest-all.ccと作成してくれるスクリプトが最初から用意されています。

python fuse_gtest_files.py OUTPUT_DIR

で指定したディレクトリにファイルを用意してくれます。

これらをコンパイルに巻き込むことで、簡単にtestを実行してくれます。

テスト用おすすめコンパイルオプション

C言語では、clangにコンパイルをオプションをつけることで、実行結果以外のエラーを検出することができます。
system関数とleaksコマンド、デストラクタを使用したリークチェックは実行に時間が掛かるので、brew install llvmをして、-fsanitize=leakを使うのがおすすめです。

おすすめのオプションです。一度に設定することもできます。

オプション 説明
-fsanitize=address buffer overflowなど、アドレス関係のバグチェック
-fsanitize=leak freeし忘れなど、メモリリークのチェック
-fsanitize=undefined 動作が保証されない書き方をチェック

動的チェックのため、実行時間が遅くなることには注意です。

アサーションの種類

他にもいろいろありますが、主なものを紹介します。

致命的なアサーション 致命的ではないアサーション 検証内容
ASSERT_TRUE(condition); EXPECT_TRUE(condition); condition が true
ASSERT_FALSE(condition); EXPECT_FALSE(condition); condition が false
ASSERT_EQ(expected, actual); EXPECT_EQ(expected, actual); expected == actual
ASSERT_NE(val1, val2); EXPECT_NE(val1, val2); val1 != val2
ASSERT_LT(val1, val2); EXPECT_LT(val1, val2); val1 < val2
ASSERT_LE(val1, val2); EXPECT_LE(val1, val2); val1 <= val2
ASSERT_GT(val1, val2); EXPECT_GT(val1, val2); val1 > val2
ASSERT_GE(val1, val2); EXPECT_GE(val1, val2); val1 >= val2
ASSERT_STREQ(expected_str, actual_str); EXPECT_STREQ(expected_str, actual_str); 2つの C 文字列の内容が等しい
ASSERT_STRNE(str1, str2); EXPECT_STRNE(str1, str2); 2つの C 文字列の内容が等しくない
ASSERT_STRCASEEQ(expected_str, actual_str); EXPECT_STRCASEEQ(expected_str, actual_str); 大文字小文字を無視した場合,2つの C 文字列の内容が等しい
ASSERT_STRCASENE(str1, str2); EXPECT_STRCASENE(str1, str2); 大文字小文字を無視した場合,2つの C 文字列の内容が等しくない
ASSERT_THROW(statement, exception_type); EXPECT_THROW(statement, exception_type); statement が与えられた型の例外を投げる
ASSERT_ANY_THROW(statement); EXPECT_ANY_THROW(statement); statement が任意の型の例外を投げる
ASSERT_NO_THROW(statement); EXPECT_NO_THROW(statement); statement が例外を投げない
ASSERT_FLOAT_EQ(expected, actual); EXPECT_FLOAT_EQ(expected, actual); 2つの float 値が,ほぼ等しい
ASSERT_DOUBLE_EQ(expected, actual); EXPECT_DOUBLE_EQ(expected, actual); 2つの double 値が,ほぼ等しい
ASSERT_NEAR(val1, val2, abs_error); EXPECT_NEAR(val1, val2, abs_error); val1 と val2 の差が,与えられた絶対誤差以内に収まる
ASSERT_DEATH(statement, regex); EXPECT_DEATH(statement, regex); 与えられたエラーが発生し,statement がクラッシュ
ASSERT_DEATH_IF_SUPPORTED(statement, regex); EXPECT_DEATH_IF_SUPPORTED(statement, regex); Death テストがサポートされていれば,statement が与えられたエラーでクラッシュすることを検証し,そうでなければ何もしない
ASSERT_EXIT(statement, predicate, regex); EXPECT_EXIT(statement, predicate, regex); statement が与えられたエラーで終了し,終了コードが predicate にマッチする
ASSERT_NO_FATAL_FAILURE(statement); EXPECT_NO_FATAL_FAILURE(statement); statement が, 現在のスレッドで新たな失敗を生成しない

参考

1分で実行できる?インストール不要、C言語向けGoogleTestサンプル for Linux - Qiita

上級ガイド — Google Test ドキュメント日本語訳

27
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?