Announce

PukiWiki contents have been moved into SONOTS Plugin (20070703)

GoogleTest

GoogleTestの使い方

Table of Contents

インストール(cygwin)

Cygwin起動。

mkdir -p ~/opt
cd ~/opt
wget http://googletest.googlecode.com/files/gtest-1.6.0.zip
unzip gtest-1.6.0.zip
ln -s ~/opt/gtest-1.6.0 ~/opt/gtest
cd gtest
./configure
make all
make check

参考

テストコード

PID制御クラスのなんちゃってテストを書いてみた。

Pid.h

#ifndef PID_H_
#define PID_H_

#define MAX_BUF_SIZE 10
/**
 * PID 制御クラス
 */
class Pid
{
public:
	float mKp; // 比例係数
	float mKi; // 積分係数
	float mKd; // 微分係数
	int index; // リングバッファの現在インデックス
	float buf[MAX_BUF_SIZE]; // リングバッファのバッファ
public:
	Pid(float kp, float ki, float kd);
	virtual ~Pid();
public:
	float control(float P);
};
#endif

Pid.cpp

#include"Pid.h"
/**
 * コンストラクタ
 *
 * @param[in] kp 比例係数
 * @param[in] ki 積分係数
 * @param[in] kd 微分係数
 */
Pid::Pid(float kp, float ki, float kd) : 
    mKp(kp), mKi(ki), mKd(kd)
{
	index = 0;
	for(int i = 0; i < MAX_BUF_SIZE; i++)
	{
		buf[i] = 0;
	}
}
/**
 * デストラクタ
 */
Pid::~Pid()
{
}
/**
 * PID制御による操作量の計算
 *
 * @param[in] P 比例成分
 * @return 操作量
 */
float Pid::control(float P)
{
	// Ring Buffer
	float pP = buf[index]; //oldest value
	buf[index] = P;  // newest value
	index = (index + 1) % MAX_BUF_SIZE;
	// Integral
	// I += P;
	float I = 0;
	for(int i = 0; i < MAX_BUF_SIZE; i++)
	{
		I += buf[i];
	}
	// Derivative
	float D = P - pP;
	// PID
	float Y = (mKp * P) + (mKi * I) + (mKd * D);	
	return Y;
}

TestPid.cpp

#include "Pid.h"
#include <gtest/gtest.h>

TEST(Pid, DefaultContructor)
{
	Pid pid(10, 0, 0);
	EXPECT_EQ(10, pid.mKp);
	EXPECT_EQ(0 , pid.mKi);
	EXPECT_EQ(0 , pid.mKd);
}

TEST(Pid, control)
{
	Pid pid(10, 0, 0);
	float Y = pid.control(10);
	EXPECT_DOUBLE_EQ(100, Y);
}

int main(int argc, char **argv)
{
  ::testing::GTEST_FLAG(color) = "yes";
  ::testing::InitGoogleTest(&argc, argv);

  return RUN_ALL_TESTS();
}

コンパイルと実行

   g++ -I$HOME/opt/gtest/include -g -Wall -Wextra Pid.cpp TestPid.cpp -L$HOME/opt/gtest/lib/.libs/ -lgtest -lgtest_main

実行

   ./a.exe

本当は色も付くけど。

[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from Pid
[ RUN      ] Pid.DefaultContructor
[       OK ] Pid.DefaultContructor (0 ms)
[ RUN      ] Pid.control
[       OK ] Pid.control (0 ms)
[----------] 2 tests from Pid (5 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (14 ms total)
[  PASSED  ] 2 tests.

private メンバのテスト

やっぱりさすがの goolgetest といえど、private メンバに直接アクセスしてテストできるようにはならないようだ。

というわけで、なにかないか探したところ次のような方法が見つかった。

Pid.h

#ifndef PID_H_
#define PID_H_
 
#ifdef UNITTEST
#define private public
#endif
....
   g++ -I$HOME/opt/gtest/include -g -Wall -Wextra Pid.cpp TestPid.cpp -L$HOME/opt/gtest/lib/.libs/ -lgtest -lgtest_main -DUNITTEST

UNITTESTが定義されているときは、private を public に置き換えるという荒業。テストコードのビルド時に -DUNITTEST として、定義する。