入門ガイド

Google C++ Testing Frameworkをはじめよう

はじめに:なぜ Google C++ Testing Frameworkを使うのか

Google C++ Testing Framework を上手に活用すれば,より良い C++ のテストを書くことができます.

Linux,Windows,そして Mac,あなたが C++ のコードを書いているこれらの環境に関係なく Google Test を利用できます.

では,優れたテストを書くにはどうすればよいのでしょうか?Google C++ Testing Framework は,どのように役立つのでしょうか?我々は次のように考えています:

  1. テストには, 独立性再現性 が必要です.別のテストの結果に依存して成功したり失敗したりするテスト,をデバッグするのは非常に面倒な作業です.Google C++ Testing Framework は,各テストを異なるオブジェクト上で実行することによって,テストの独立性を保ちます.Google C++ Testing Framework は,これらを独立に実行するので,テストが失敗したときに迅速なデバッグが行えます.
  2. テストは,よく 整理され ,かつテストコードの構造を反映したものであるべきです.Google C++ Testing Framework は,関連するテスト同士を,データとサブルーチンを共有するテストケースとしてグループ化します.これにより,テストを理解しやすくなり,メンテナンスが簡単になります.このような一貫性は,プロジェクトが変わって新たなコードを扱い始める人にとっては,特に役立ちます.
  3. テストは, 移植性 があり再利用できるものであるべきです.オープンソースのコミュニティには,プラットフォームに依存しないコードが多くあり,それらのテストもプラットフォーム非依存であるべきです.Google C++ Testing Framework は,様々な OS やコンパイラ(gcc,MSVC など)上で,例外を使用するかしないかに関係なく動作します.よって,Google C++ Testing Framework のテストでは,様々な動作条件を簡単に試すことができます.(ただし,現在のリリースでは,Linux用のビルドスクリプトのみが付属します.ほかのプラットフォーム用のスクリプトも鋭意開発中です.)
  4. テストが失敗した場合,その問題に関する 情報 をできるだけ多く出力するべきです.Google C++ Testing Framework は,最初にテストが失敗した箇所では停止しません.代わりに,現在のテストを停止して,次のテストに移ります.また,致命的ではない失敗をレポートして,そのまま現在のテストを続けるように設定することもできます.したがって,1回の「実行-編集-コンパイル」サイクルで複数のバグを検出して修正することができます.
  5. Testing Framework は,テストを書くユーザがテスト内容に集中できるようにするものです.つまり,それ以外の雑多な作業をユーザにさせてはいけません.Google C++ Testing Framework は,定義されたすべてのテストを自動的に追跡するので,ユーザがそれらを実行順に並べたりする必要はありません.
  6. テストは 高速 に動作するべきです.Google C++ Testing Framework を使えば,共有リソースを再利用することができ,互いに依存しあうようなテストを作らずに,開始/終了のための処理は1度行うだけで済みます.

Google C++ Testing Framework は,有名な xUnit アーキテクチャに基づいているので,以前に JUnit や PyUnit を使ったことがあれば,すぐに馴染むことができるでしょう.もし使ったことがなくても,10分もあれば基本を学んで使い始めることができるようになります.さぁ,では始めましょう.

注意 : Google C++ Testing Framework を,Google Test と呼ぶ場合もあります.

新しいテストプロジェクトを開始する

Google Test を使ったテストプログラムを書くには,Google Test をライブラリとしてコンパイルし,それをテストにリンクする必要があります.有名なビルドシステム用のビルドファイルが用意されています:(Visual Studio 用の msvc/,Mac XCode 用の xcode/,GNU make 用の make/,Borland C++ Builder 用の codegear/,Scons 用の scons/,そして Google Test ルートディレクトリにある autotools スクリプト).あなたのビルドシステムがリストない場合,make/Makefile を見て,Google Test がどのようにコンパイルされるかを調べることができます. (通常,GTEST_ROOT および GTEST_ROOT/include をインクルードパスに入れて,src/gtest-all.cc をコンパイルします.ここで,GTEST_ROOT は Google Test のルートディレクトリです).

Google Test ライブラリをコンパイルできれば,後はプロジェクトを作成したり,テストプログラム用のターゲットをビルドしたりできるでしょう.コンパイル時にコンパイラが “gtest/gtest.h” を見つけられるように,GTEST_ROOT/include がインクルードパスに含まれていることを確認してください.また,Google Test ライブラリをリンクするようにプロジェクトを設定してください(例えば,Visual Studio の場合,gtest.vcproj への依存を追加することで実現できます).

まだ分からないことがあれば,Google Test 自身のテストがどのようにビルドされ,どのように使われているかを調べてみてください.

基本コンセプト

Google Test を利用する場合,アサーション,つまり,ある条件が真かどうかを調べる文,を書くところから始まります.アサーションの結果には,成功,致命的ではない失敗,致命的な失敗,があります.致命的な失敗が起きた場合は,現在実行中の関数が中断され,それ以外の場合は,通常通りプログラムが続行されます.

テスト は,アサーションを利用してテスト対象コードの動作を検証します.テストがクラッシュしたり,アサーションが失敗したりした場合,テスト自体が 失敗 となります.それ以外の場合は,テスト成功となります.

1つの テストケース には,1つまたは複数のテストが含まれます.テスト対象コードの構造を反映するように,テストをテストケースとしてグループ化してください.1つのテストケースに複数のテストが含まれており,共通のオブジェクトやサブルーチンを共有する必要がある場合,それをテストフィクスチャクラスに書くことができます.

1つの テストプログラム は,複数のテストケースを含むことができます.

では,個々のアサーションレベルから始めて,テスト,テストケースと段階的に進むことで,テストプログラムの書き方を説明していきます.

アサーション

Google Test のアサーションはマクロであり,関数呼び出しと似たようなものです.クラスや関数のテストを行うには,それの動作を調べるアサーションを定義します.アサーションが失敗すると,Google Test は失敗を知らせるメッセージと共に,アサーションのソースファイルと失敗した箇所の行番号を出力します.また,Google Test のメッセージに追加する形で,ユーザ定義の失敗メッセージを出力することもできます.

現在実行中の関数で同じテストを行っても,その挙動が異なるアサーションが存在します.ASSERT_* バージョンが失敗した場合,致命的な失敗となり, 現在実行中の関数を中断します. EXPECT_* バージョンでは,致命的ではない失敗となり,関数を中断することはありません.1度のテストで複数の失敗を報告できるので,通常はEXPECT_* が好まれます.しかし,問題のアサーションが失敗した後にプログラムを続行しても意味がない場合は,ASSERT_* を利用してください.

ASSERT_*が失敗すると,その関数から直ちに戻るので,その後に実行されるはずだった後処理のコードをスキップしてしまう可能性があります.これは,メモリリークの原因になる可能性があります.これを修正する価値があるか否かは,リークの種類に依存します.アサーションエラーに加えてヒープエラーも調べる場合は,このことを覚えておいてください.

ユーザ定義の失敗メッセージを出力するには,単に<<演算子を用いて,そのメッセージをストリームに出力するだけです.以下に例を示します:

ASSERT_EQ(x.size(), y.size()) << "Vectors x and y are of unequal length";

for (int i = 0; i < x.size(); ++i) {
  EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i;
}

ostreamに出力できるものは,アサーションマクロにも出力できます.具体的には,Cの文字列やstringオブジェクトなどです.ワイド文字列(Windows環境のUNICODEのwchar_t*, TCHAR*,あるいはstd::wstring)をアサーション文字列として利用する場合,出力時にUTF-8に変換されます

基本的なアサーション

これらのアサーションは,基本的な true/false 条件のテストを行います.

致命的なアサーション 致命的ではないアサーション 検証内容
ASSERT_TRUE(condition); EXPECT_TRUE(condition); condition が true
ASSERT_FALSE(condition); EXPECT_FALSE(condition); condition が false

ASSERT_* が失敗した場合は,致命的な失敗となって現在の関数から戻ります.EXPECT_* の場合は,致命的ではない失敗となり,関数はそのまま実行されます.このことを忘れないでください.いずれにせよ,アサーションが失敗するということは,テストが失敗するということを意味します.

利用可能な環境: Linux,Windows,Mac.

2つの値の比較

ここでは,2つの値を比較するアサーションについて述べます.

致命的なアサーション 致命的ではないアサーション 検証内容
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

Google Test は失敗時に, val1 と val2 の両方を出力します.ASSERT_EQ* と EXPECT_EQ* (および,これ以降で紹介するすべての等号評価アサーション)では,テストしたい式を actual の位置に,期待する値を expected の位置に書きます.Google Test の失敗メッセージは,この順序を前提として出力されます.

引数の値は,アサーションの比較演算子によって比較可能なものでなければいけません.そうでない場合は,コンパイルエラーになります.通常,ostream に出力するための << 演算子をサポートする引数が必要ですが,v1.6.0以降では必須ではなくなりました.(もし << がサポートされている場合は,アサーション失敗時の出力用にそれが呼ばれます.そうでない場合は,Google Test は,最適な方法で出力を行おうとします.これの詳細および引数の出力をカスタマイズする方法については,Google Mock レシピを参照してください).

これらのアサーションは,対応する比較演算子(例えば,==, <, など)を定義すれば,ユーザ定義型に対しても動作します.対応する演算子が定義されていれば,ASSERT_*() マクロを使う方が良いでしょう.比較結果に加えて2つのオペランドも表示するからです.

引数は,常に1回だけ評価されます.したがって,引数に副作用があっても問題ありません.しかし,通常の C/C++ 関数と同様に,引数の評価順序は未定義(つまり,コンパイラ依存)です.よって,引数の特定の評価順に依存するようなコードを書いてはいけません.

ASSERT_EQ() は,ポインタに対しては,ポインタが等しいか否かを評価します.2つの C 文字列に対しては,文字列の内容ではなくメモリのアドレスが等しいか否かをテストします.したがって,C 文字列(例えば,const char*)を,その値で比較したい場合は,後述の ASSERT_STREQ() を利用してください.特に,C文字列が NULL の場合は,ASSERT_STREQ(NULL, c_string) を利用します.しかし,2つの string オブジェクトを比較する場合は,ASSERT_EQ を利用する必要があります.

ここで説明したマクロは,通常の文字列およびワイド文字列(string と wstring)に対して動作します.

利用可能な環境: Linux,Windows,Mac.

文字列の比較

ここでは,2つの C 文字列 を比較するアサーションについて説明します.2つの string オブジェクトを比較したい場合は,EXPECT_EQ,EXPECT_NE,などを代わりに利用してください.

致命的なアサーション 致命的ではないアサーション 検証内容
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 文字列の内容が等しくない

名前に”CASE”と付いているアサーションは,引数の大文字小文字の区別をしないことに注意してください.

*STREQ* と *STRNE* も,C文字列(wchar_t*)を引数にとります.2つのワイド文字列の比較が失敗した場合,それらの値は UTF-8 の文字列として出力されます.

NULL ポインタと空文字は,別のものとして区別されます.

利用可能な環境: Linux,Windows,Mac.

参考:より詳細な文字列比較の方法(例えば,部分文字列,接頭語,接尾語,正規表現一致など)については, 上級ガイド を参照してください.

簡単なテスト

テストの作成方法:

  1. TEST() マクロを利用してテスト関数を定義し,名前を付けます.これらのテスト関数は,値を返さない通常の C++ 関数です.
  2. この関数内には,有効な C++ の文を自由に書けます.そして,ここで様々な Google Test アサーションを利用して値を検証します.
  3. アサーションによってテスト結果が決まります.テスト内のアサーションが1つでも失敗する(致命的である,ないにかかわらず),またはテストがクラッシュすると,そのテスト全体が失敗したことになります.それ以外の場合は,テスト成功となります.
TEST(test_case_name, test_name) {
 ... test body ...
}

TEST() の引数は,全体そして詳細,の順序に並んでいます.最初の引数は,テストケースの名前です.2番目の引数は,テストケースに含まれるテストの名前です.両者とも有効な C++ の識別子でなければならず,アンダースコア(_)を含んではいけません.テストケースと個々のテスト名を合わせたものが,テストの完全な名前となります.属するテストケースが別ならば,個々のテスト名として同じ名前を付けることもできます.

例として,整数を引数に取る単純な関数を見てみましょう:

int Factorial(int n); // nの階乗を返す

この関数のテストケースは,例えば次のようになります:

// 0 の階乗をテスト
TEST(FactorialTest, HandlesZeroInput) {
  EXPECT_EQ(1, Factorial(0));
}

// 正の数の階乗をテスト
TEST(FactorialTest, HandlesPositiveInput) {
  EXPECT_EQ(1, Factorial(1));
  EXPECT_EQ(2, Factorial(2));
  EXPECT_EQ(6, Factorial(3));
  EXPECT_EQ(40320, Factorial(8));
}

Google Test は,テスト結果をテストケース毎にグループ化します.ですから,論理的に関連するテストは,同じテストケースに入れられるべきです.言い換えれば,TEST() の最初の引数が同じであるべきです.上述の例では,HandlesZeroInput と HandlesPositiveInput という2つのテストが,同じテストケース FactorialTest に属しています.

利用可能な環境: Linux,Windows,Mac.

テストフィクスチャ:複数のテストで同じデータ設定を使う

同じようなデータを扱うテストを複数書く場合は,テストフィクスチャを利用することができます.これを使うと,異なるテストに対して同じオブジェクト設定を再利用できます.

フィクスチャの作り方:

  1. ::testing::Test クラスからの派生クラスを作ります.フィクスチャの派生クラスからフィクスチャメンバにアクセスしたいので,ここでは protected: または public: でメンバを宣言します.
  2. 利用する予定のオブジェクトをすべて,クラス内で宣言します.
  3. 必要に応じて,デフォルトコンストラクタまたは SetUp() 関数を書きます.これは,テスト毎にオブジェクトの準備をするためのものです.よくある失敗は,SetUp() の代わりに,小文字の u- を使って Setup() と書いてしまい,実際には何も起こらない,というものです.
  4. 必要に応じて,デストラクタまたは TearDown() 関数を書きます.これは,SetUp() で確保されたりソースをすべて解放するためのものです.コンストラクタ/デストラクタ,そしてSetUp()/TearDown() をどのような場合に利用すればよいかについて知りたい場合は,この FAQ エントリ を参照してください.
  5. 必要ならば,複数のテストで共有するサブルーチンを書きます.

フィクスチャを利用する場合,TEST() の代わりに TEST_F() を使ってください.これによって,テストフィクスチャ内のオブジェクトやサブルーチンにアクセスできるようになります:

TEST_F(test_case_name, test_name) {
 ... test body ...
}

TEST() と同様に,最初の引数はテストケースの名前ですが,TEST_F() の場合は,これは必ずテストフィクスチャクラスの名前でなければいけません.ご想像の通り,_F はフィクスチャを表します.

残念ながら,C++ のマクロシステムでは1種類のマクロで両方のテストに対応することはできません.間違ったマクロを使うと,コンパイルエラーが起こります.

また,TEST_F() で利用するよりも前に,テストフィクスチャクラスを定義する必要があります.そうしない場合,”virtual outside class declaration” コンパイルエラーが発生します.

Google Test は, TEST_F() で定義される各テストに対して次の処理を行います:

  1. 実行時に新たなテストフィクスチャを作成します.
  2. 直後に,SetUp() による初期化を行います.
  3. テストを実行します.
  4. TearDown() による後処理を行います.
  5. テストフィクスチャを削除します.同じテストケース内の別のテストは,それぞれ異なるテストフィクスチャオブジェクトを持つことに注意してください.Google Test は,新たなテストフィクスチャオブジェクトを作成する前に,必ず以前のオブジェクトを削除します.Google Test は,同じテストフィクスチャを複数のテストで使いまわすことはしません.よって,あるテストがフィクスチャを変更しても,それが別のテストに影響することはありません.

例として,Queue という名前の FIFO キュークラスのテストを書いてみましょう.そのインタフェースは,次のようになります:

template <typename E> // E は要素の型
class Queue {
public:
  Queue();
  void Enqueue(const E& element);
  E* Dequeue(); // queue が空の場合は NULL を返します.
  size_t size() const;
...
};

まず最初に,フィクスチャクラスを定義します.慣例により,FooTest という名前にします.ここで,Foo はテストされるクラスの名前です.

class QueueTest : public ::testing::Test {
 protected:
  virtual void SetUp() {
    q1_.Enqueue(1);
    q2_.Enqueue(2);
    q2_.Enqueue(3);
  }

  // virtual void TearDown() {}

  Queue<int> q0_;
  Queue<int> q1_;
  Queue<int> q2_;
};

この場合,各テストにおいてデストラクタで行われる以上の後処理は不要なので, TearDown() は必要ありません.

では,このフィクスチャとTEST_F() を利用してテストを書いてみましょう.

TEST_F(QueueTest, IsEmptyInitially) {
  EXPECT_EQ(0, q0_.size());
}

TEST_F(QueueTest, DequeueWorks) {
  int* n = q0_.Dequeue();
  EXPECT_EQ(NULL, n);

  n = q1_.Dequeue();
  ASSERT_TRUE(n != NULL);
  EXPECT_EQ(1, *n);
  EXPECT_EQ(0, q1_.size());
  delete n;

  n = q2_.Dequeue();
  ASSERT_TRUE(n != NULL);
  EXPECT_EQ(2, *n);
  EXPECT_EQ(1, q2_.size());
  delete n;
}

上述の例では,ASSERT_* と EXPECT_* の両方のアサーションを利用しています.簡単に言えば,アサーション失敗後のエラーも調べるために関数を続行したい場合は EXPECT_* を利用し,アサーション失敗後に続けても意味がない場合は ASSERT_* を利用します.例えば,Dequeue テストの2番目のアサーションは ASSERT_TRUE(n != NULL) となっています.これは,後でポインタ n の参照を外しますが,そこで n が NULL の場合はセグメンテーションフォルトが起こるので,テストを続ける意味がないためです.

これらのテストが実行されると,以下のようなことが起こります:

  1. Google Test は,QueueTest オブジェクトを作成します(これを t1 とします).
  2. t1.SetUp() が t1 を初期化します.
  3. t1 に対して最初のテスト(IsEmptyInitially)が実行されます.
  4. t1.TearDown() がテスト終了後の後処理をします.
  5. t1 が削除されます.
  6. 上述のステップが,別の QueueTest オブジェクトでも繰り返されます.今回の場合は,DequeueWorks テストが実行されます.

利用可能な環境: Linux,Windows,Mac.

注意 :Google Test は,テストオブジェクトが生成された時に自動的にすべての Google Test フラグを保存します.そして,オブジェクトが破棄された時にそれらを復元します.

テストの呼び出し

TEST() と TEST_F() によって定義されたテストは,暗黙のうちに Google Test に登録されます.したがって,他の多くの C++ testing framework とは異なり,定義したテストを実行順にリストアップする必要はありません.

テストを定義したら,RUN_ALL_TESTS() でテストを実行できます.すべてのテストが成功すれば 0 が返り,そうでなければ 1 が返ります.RUN_ALL_TESTS() は,リンクされたバイナリのすべてのテストを実行することに注意してください.これらのテストは,異なるテストケース,さらには異なるソースファイルから構成される場合もあります.

RUN_ALL_TESTS() マクロを呼び出した場合の動作は次のようになります:

  1. すべての Google Test フラグの状態を保存します.
  2. 最初のテストのために,テストフィクスチャオブジェクトを作成します.
  3. SetUp() によって初期化されます.
  4. フィクスチャオブジェクト上で,最初のテストが実行されます.
  5. TearDown() によってフィクスチャの後処理が実行されます.
  6. フィクスチャが削除されます.
  7. すべてのGoogle Test フラグの状態を復元します.
  8. 上述のステップを,すべてのテストが実行されるまで繰り返します.

また,ステップ2でテストフィクスチャのコンストラクタが失敗した場合,以降のステップ3-5は意味がないのでスキップされます.同様に,ステップ3で致命的な失敗が発生した場合,ステップ4はスキップされます.

重要 :RUN_ALL_TESTS() の戻り値を無視しないでください.無視すれば,gcc ではコンパイルエラーになります.何故このような仕組みなっているかといえば,テストが成功したか否かは自動的に判断されますが,この判断は stdout/stderr 出力ではなく終了コードに基づいているからです.よって,main() 関数は,必ず RUN_ALL_TESTS() の戻り値を返すようにしてください.

また,RUN_ALL_TESTS() を呼び出せるのは1度だけです.2回以上呼び出すと,Google Test の別の機能(例えば,thread-safe death テスト)と衝突します.したがって,そような呼び出しはサポートされていません.

利用可能な環境: Linux,Windows,Mac.

main() 関数を書く

まずは,お決まりの形からはじめましょう:

#include "this/package/foo.h"
#include "gtest/gtest.h"

namespace {

// テスト対象となるクラス Foo のためのフィクスチャ
class FooTest : public ::testing::Test {
 protected:
  // 以降の関数で中身のないものは自由に削除できます.
  //

  FooTest() {
    // テスト毎に実行される set-up をここに書きます.
  }

  virtual ~FooTest() {
    // テスト毎に実行される,例外を投げない clean-up をここに書きます.
  }

  // コンストラクタとデストラクタでは不十分な場合.
  // 以下のメソッドを定義することができます:

virtual void SetUp() {
  // このコードは,コンストラクタの直後(各テストの直前)
  // に呼び出されます.
}

virtual void TearDown() {
  // このコードは,各テストの直後(デストラクタの直前)
  // に呼び出されます.
}

// ここで宣言されるオブジェクトは,テストケース内の全てのテストで利用できます.
};

// Abc を行う Foo::Bar() メソッドをテストします.
TEST_F(FooTest, MethodBarDoesAbc) {
  const string input_filepath = "this/package/testdata/myinputfile.dat";
  const string output_filepath = "this/package/testdata/myoutputfile.dat";
  Foo f;
  EXPECT_EQ(0, f.Bar(input_filepath, output_filepath));
}

// Xyz を行う Foo をテストします.
TEST_F(FooTest, DoesXyz) {
  // Foo の Xyz を検査
}

}  // namespace

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

::testing::InitGoogleTest() 関数は,コマンドラインの Google Test フラグを解析して,認識されたフラグを削除します.これによって,ユーザは様々なフラグを介してテストプログラムの挙動を制御することができます.これについては, 上級ガイド で述べます. この関数は,RUN_ALL_TESTS() よりも前に呼び出す必要があります.そうしない場合,フラグが適切に初期化されません.

Windows 環境では,InitGoogleTest() はワイド文字列に対しても動作するので,UNICODE モードでコンパイルされたプログラムでも利用できます.

しかし,このような main() 関数を書くのは大変すぎると思うかもしれません.確かにその通りなので,Google Test では基本的な main() 関数の実装を用意してあります.これで十分な場合は,テストに gtest_main ライブラリをリンクするだけで利用できます.

Visual C++ ユーザのための重大な注意

ライブラリ内部にテストを書いる場合, main() 関数が別のライブラリまたは別の .exe ファイルにあると,これらのテストは実行されません.これは,Visual C++ の バグ によるものです.テストを定義する際, Google Test は静的なオブジェクトを生成して,それを登録します.これらのオブジェクトはどこからも参照されませんが,オブジェクトのコンストラクタは,本来ならば実行されるはずです.しかし,Visual C++ のリンカは,外部参照されないライブラリであると判断して,リンクを行いません.リンカが無視しないように,メインプログラムから,テストの書かれたライブラリを参照する必要があります. ここでは,その方法について説明します.ライブラリ内のどこかで,次のように関数を宣言します:

__declspec(dllexport) int PullInMyLibrary() { return 0; }

テストを書いたのが(DLLではなく)スタティックライブラリならば, __declspec(dllexport) は不要です.そして,メインプログラムには,この関数を呼び出すコードを書きます:

int PullInMyLibrary();
static int dummy = PullInMyLibrary();

これにより,外部からの参照が保たれ,テストはスタートアップに登録されます.

さらに,テストをスタティックライブラリに書いた場合,メインプログラムのリンカオプションに /OPT:NOREF を追加してください.MSVC++ IDE を利用する場合,.exeプロジェクトのプロパティ/構成プロパティ/リンカ/最適化にある参照の設定を,参照されないデータを保持する (/OPT:NOREF) に変更してください.このようにすることで,Visual C++ のリンカは,最終的な実行ファイルを作る際に,テストによって生成される個々のシンボルを破棄しなくなります.

しかし,落とし穴がもう1つあります.Google Test をスタティックライブラリとして利用する場合(これは,gtest.vcproj内で使われてる方法です),あなたのテストコードもまたスタティックライブラリ内に存在し続けることになります.テストをDLL内部に持つ必要があるならば,必ず Google Test も DLL としてビルドしなおさなければいけません.そうしなければ,テストは正常に動作しないか,もしくはまったく動作しないでしょう.ここで得られる結論はこうです.こういう事で悩みたくないならば,テストをライブラリ内に書かないようにしてください!

次のステップ

おめでとうございます!あなたは,Google Test の基本を学び終えました.これで,Google Test でテストを書いて実行できます. サンプル を読んだり,Google Test のさらに役立つ機能について書かれた 上級ガイド に進むこともできます.

既知の制限事項

Google Test はスレッドセーフであるように設計されています.この実装では,pthreads ライブラリが使えるシステムにおいてスレッドセーフとなります.それ以外のシステム(例えば,Windows)で,2つのスレッドから同時に Google Test のアサーションを利用するのは,現在のところスレッドセーフではありません.普通,アサーションはメインスレッドで実行されるので,ほとんどのテストではこれは問題にはなりません.この問題の対処に協力したい場合,あなたのプラットフォームで必要な同期プリミティブを gtest-port.h に実装して提供することができます.