【C++】Windowsでgoogleテストをやってみた（環境設定～実行まで）

# はじめに

本記事では、windows環境において、googleテストの環境設定から始まり、コードの書き方やテストの実行例まで記載していきます。

# googleテストって何？

googleが作成した、C++用のテストフレームワークです。


# 環境設定

１．googleテストをダウンロードします。
https://github.com/google/googletest/releases


２．Visual Studio をインストールします。
（ただし今回は元々使用していた2017を使用）
https://visualstudio.microsoft.com/ja/downloads/


３．ダウンロードしたzipファイルを解凍します。
（因みに今回ダウンロードしたのはバージョン1.8.1）


４．以下に格納されているgtest.slnをVisual Studioで開きます。
googletest-release-1.8.1\googletest\msvc\2010


５．セキュリティ警告が出てくるので、OKを押します。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271833/ccc5b223-8990-4c81-56bc-6f21d1671a8a.png)


６．プロジェクト再ターゲットのダイアログが出てくるので、OKを押します。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271833/81840dde-4af5-ac88-0e1e-62beb959ff9a.png)
※ わざわざこのためにgtest.slnを開くのは少々面倒ですが、
　 上記の再ターゲットを怠るとこの先で詰まってしまいます。


７．その後、ファイル->ソリューションを閉じるを選択します。


８．ファイル->新規作成->プロジェクトより、テスト用のプロジェクトを新たに作成します。
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271833/b483cb11-0793-abe4-8fc8-a10194c7c9ae.png)

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271833/6dfe5853-2c8c-70df-5efa-f81264398d92.png)


９．ソリューションを右クリックし、追加->既存の項目より googletest-release-1.8.1\googletest\msvc\2010\gtest.vcxproj を追加します。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271833/2908eb97-f024-2ce0-cc48-33784ab162cd.png)


１０．gtest.hをインクルードできるようにするため、まずは今回新たに作成したプロジェクトファイルを左クリックし、プロパティを選択します。
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271833/69c58d22-dfd0-7fd0-9f5f-8d24c6eaad32.png)


１１．構成プロパティ -> c/c++ -> 全般から、追加のインクルードディレクトリを選択し、gtest.hが格納されているgoogletest-release-1.8.1\googletest\includeを追加します。

![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271833/89b4c911-a114-bdc7-ff51-9132183a8a3f.png)

「新しい行」のアイコンから追加します。

![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271833/90fd543c-252b-9c20-28c7-0e7077793709.png)

※ gtest.hなどが格納されているのはincludeフォルダ直下のgtestフォルダであるため、上記のようなincludeまでのパスの代わりにgoogletest-release-1.8.1\googletest\include\gtest のパスを追加したくなりますが、そうすると実行時にエラーがでます。何故ならgoogletest-release-1.8.1\googletest\includeのパスが追加されたことを前提とするパスがgtest.h内に含まれているためです。
　例： #include "gtest/internal/gtest-internal.h" など


１２．新規作成したプロジェクトからgoogleテストのプロジェクトを参照できるようにするように、新規作成したプロジェクトの参照を左クリックし、参照の追加を選択してgtestにチェックを入れます。
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271833/f6eabc48-a3c2-afbe-06a0-a1560a9d761a.png)


![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271833/93e2dc2f-da40-9d72-9917-ace759e38eb4.png)

これで、新規作成したプロジェクト→gtestプロジェクトを参照する関係ができあがりました。


以上で環境設定が完了しました。


# テストコードの書き方

メインの雛型を下記とします。

```c:Project_for_gtest.cpp
#include "stdafx.h"
#include <gtest/gtest.h>

TEST() 
{
	// ここにテストコードを書く
}

int main(int argc, char **argv)
{
	::testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}
```

googleテストでテストをするには、アサーションマクロなる関数を呼び出します。アサーションマクロは大きく分けると、ASSERTとEXPECTの２種類があります。ASSERTの場合、テストが失敗した場合にその関数から戻ります。そのため、複数のテストを実行する場合、あるテストが失敗した場合にそれ以降はテストする必要がない場合など、ASSERTを使用します。ただし、失敗した場合、その後実行されるはずだった処理もスキップされてしまうことでメモリリークの原因になる可能性があるそうです。

一方、EXPECTの場合、テストに失敗してもその後の処理を続行します。

以下表に、アサーションマクロの例を示します。
下の例はASSERTですが、ASSERTと記述している部分は、全て"EXPECT"に置き換えて使用できます。

テストが失敗しても途中で止まらないこともあり、基本的にはEXPECTの方が好まれます。

|式|成功条件|
|---|---|
|ASSERT_TRUE(式)|式が真|
|ASSERT_FALSE(式)|式が偽|
|ASSERT_EQ(a, b)|a == b|
|ASSERT_NE(a, b)|a != b|
|ASSERT_LT(a, b)|a < b|
|ASSERT_LE(a, b)|a <= b|
|ASSERT_GT(a, b)|a > b|
|ASSERT_GE(a, b)|a >= b|
|ASSERT_STREQ(a, b)|a == b（引数は文字列）|
|ASSERT_STRNE(a, b)|a != b（引数は文字列）|

詳しくは以下を参照

入門ガイド ― Google Test ドキュメント日本語訳
http://opencv.jp/googletestdocs/primer.html

# 実際に使ってみた

## 例１
では、上記に記載した雛形内のTEST関数を以下のように記述し、テストを実行します。

```c
TEST()
{
	int a = 10;
	int b = 10;
	EXPECT_TRUE(a, b);
}
```

結果は以下のように出力されます。
![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271833/fccea3e7-4baa-036f-26ac-a697b9e208ec.png)




## 例２

次はtestcode.cppに記載したテストコードに従い、
target.cppをテストしてみます。

尚、今回のTEST関数には第１引数テストケース名、第２引数テストケース中のテスト名を
記載しています。１つのテストケースの中に、１つ以上のテストが含まれるという構造に
なっており、テストケース名及びテスト名は任意で決定できます。

```c:target.cpp
// テスト対象を記載
#include "stdafx.h"
#include "target.h"

int TestTarget::add(int a, int b) 
{
	return a + b;
}
int TestTarget::subtract(int a, int b) 
{
	return a - b;
}
```


```c:target.h
// テスト対象を記載
class TestTarget
{
public:
	int add(int a, int b);
	int subtract(int a, int b);
private:

};
```


```c:testcode.cpp
// テストコードを記載
#include "stdafx.h"
#include <gtest/gtest.h>
#include "target.h"

TEST(TestTarget, calc_add) {

	TestTarget obj;
	
	EXPECT_EQ(14, obj.add(4, 10)); //テスト成功
}

TEST(TestTarget, calc_subtract) {

	TestTarget obj;
	
	EXPECT_NE(17, obj.subtract(21, 4)); //テスト失敗
}
```

```c:Project_for_gtest.cpp
#include "stdafx.h"
#include <gtest/gtest.h>

int main(int argc, char **argv)
{
	::testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}
```

出力結果は、以下です。
![19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271833/24bf61a7-0365-5cf5-144f-ba812eca9da8.png)


## 例３

例３も例２と同様に、テストコードはtestcode.cppに、
テスト対象はtarget.cppに記載します。


```c:target.cpp
// テスト対象を記載
#include "stdafx.h"
#include "target.h"

namespace TestTarget
{

	int TestTarget::multiply(int a, int b) {
		return a * b;
	}
	int TestTarget::divide(int a, int b) {
		return a / b;
	}
}
```

```c:target.h
// テスト対象を記載
namespace TestTarget
{
	int multiply(int a, int b);
	int divide(int a, int b);
};
```


```c:testcode.cpp
// テストコードを記載
#include "stdafx.h"
#include <gtest/gtest.h>
#include "target.h"

TEST(TestTarget, calc_mutiply) {

	EXPECT_EQ(24, TestTarget::multiply(4, 6)); //テスト成功
}

TEST(TestTarget, calc_divide) {

	EXPECT_NE(7, TestTarget::divide(56, 8)); //テスト失敗
}
```

```c:Project_for_gtest.cpp
#include "stdafx.h"
#include <gtest/gtest.h>

int main(int argc, char **argv)
{
	::testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}
```

出力結果は、以下です。
![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271833/a0906095-dbb2-ebfe-8c40-3e7719ea18b9.png)

以上です。

ここ間違っているぞ！ここはこうしたほうがいいぞ！等ありましたら
気軽にご指摘いただけますと幸いです。