gtest的一个简单扩展
看了gtest的一个simple,其中有测试运行时间的方法,但使用起来稍微负责,因此做了一个简单的扩展。
扩展内容:
1. TEST_T(test_case_name, test_name),用于定义运行时间测试用例。
2. TEST_T_SHOWTIME(),打开打印测试用例运行时间打印开关。
3. EXCEPT_TIME(second)和ASSERT_TIME(second),断言,second为double类型,测试运行时间是否小于second。
使用说明:
向正常使用一样,只是在需要时间测试时include “gtest_e.h”即可,当然也得把相应的库链接到执行文件中。
具体实现:
源文件gtest_e.h----
/**//**
* gtest_e.h
*/
#ifndef GTEST_E_H_
#define GTEST_E_H_
#include "gtest_time.h"
#define TEST_T(test_case_name, test_name)\
GTEST_TEST(TIME_##test_case_name, test_name, ::TimeTest)
#define TEST_T_SHOWTIME() TimeTest_setShowFlag(1)
#define ASSERT_TIME(time) if(TimeTest_setTimePoint() - time > 0) \
FAIL() << "Time: running " << TimeTest_getTime() << "(s) > " << time << "(s)"
#define EXCEPT_TIME(time) if(TimeTest_setTimePoint() - time > 0) \
ADD_FAILURE() << "Time: running " << TimeTest_getTime() << "(s) > " << time << "(s)"
#endif /* GTEST_E_H_ */
源文件gtest_time.h----
/**//**
* gtest_time.h
*/
#ifndef GTEST_TIME_H_
#define GTEST_TIME_H_
#include <gtest/gtest.h>
class TimeTest: public testing::Test
{
public:
inline void TimeTest_setShowFlag(int flag)
{
show_time_ = flag;
}
inline double TimeTest_getTime()
{
return end_time_ - start_time_;
}
double TimeTest_setTimePoint();
protected:
double start_time_;
double end_time_;
int show_time_;
virtual void SetUp();
virtual void TearDown();
};
#endif /* GTEST_TIME_H_ */
源文件gtest_time.cpp----
/**//**
* gtest_time.cpp
*/
#include <iostream>
#include "gtest_time.h"
using namespace std;
#if defined(WIN32)
#include <sys/timeb.h>
double now()
{
struct _timeb current;
_ftime(¤t);
return (((double) current.time) + (1.0 * current.millitm) * 0.000001);
}
#else
double now()
{
struct timeval current;
gettimeofday(¤t, NULL);
return (((double) current.tv_sec) + 1.0e-6 * ((double) current.tv_usec));
}
#endif
void TimeTest::SetUp()
{
start_time_ = now();
end_time_ = 0;
TimeTest_setShowFlag(0);
}
void TimeTest::TearDown()
{
if (show_time_)
{
double used_time = TimeTest_setTimePoint();
cout << "[ TIME ] used time: " << used_time << "(s)"
<< endl;
}
}
double TimeTest::TimeTest_setTimePoint()
{
end_time_ = now();
return TimeTest_getTime();
}
以上内容只是一个简单的实现,没有过多的测试,且时间精度不够,误差较大。
上面对gtest进行了一个简单的扩展,本文通过实例测试并介绍这个扩展的用法。
首先实现两个Fibonacci函数,然后对这两个函数进行测试:
Fibonacci_1,使用循环实现:
unsigned int Fibonacci_1(unsigned int n)
{
unsigned int i;
unsigned int f0 = 1, f1 = 1, f2;
for (i = 1; i < n; i++)
{
f2 = f0 + f1;
f0 = f1;
f1 = f2;
}
return f1;
}
Fibonacci_2,使用递归实现:
unsigned int Fibonacci_2(unsigned int n)
{
switch (n)
{
case 0:
return 1;
case 1:
return 1;
default:
return Fibonacci_2(n - 1) + Fibonacci_2(n - 2);
}
}
测试用例:
TEST_T(Fibonacci_Recursive, 30)
{
Fibonacci_2(30);
ASSERT_TIME(0.1);
}
TEST_T(Fibonacci_Loop, 30)
{
Fibonacci_1(30);
ASSERT_TIME(0.1);
}
TEST_T(Fibonacci_Recursive, 40)
{
TEST_T_SHOWTIME();
Fibonacci_2(40);
EXCEPT_TIME(0.1);
ASSERT_TIME(1) << "\nUsed too long time!";
}
TEST_T(Fibonacci_Loop, 40)
{
TEST_T_SHOWTIME();
Fibonacci_1(40);
EXCEPT_TIME(0.1);
ASSERT_TIME(1) << "\nUsed too long time!";
}
测试结果:
[==========] Running 4 tests from 2 test cases.
[----------] Global test environment set-up.
[----------] 2 tests from TIME_Fibonacci_Recursive
[ RUN ] TIME_Fibonacci_Recursive.30
[ OK ] TIME_Fibonacci_Recursive.30
[ RUN ] TIME_Fibonacci_Recursive.40
FibonacciTest.cpp:47: Failure
Failed
Time: running 2.9995(s) > 0.1(s)
FibonacciTest.cpp:48: Failure
Failed
Time: running 2.9995(s) > 1(s)
Used too long time!
[ TIME ] used time: 2.9995(s)
[ FAILED ] TIME_Fibonacci_Recursive.40
[----------] 2 tests from TIME_Fibonacci_Loop
[ RUN ] TIME_Fibonacci_Loop.30
[ OK ] TIME_Fibonacci_Loop.30
[ RUN ] TIME_Fibonacci_Loop.40
[ TIME ] used time: 0(s)
[ OK ] TIME_Fibonacci_Loop.40
[----------] Global test environment tear-down
[==========] 4 tests from 2 test cases ran.
[ PASSED ] 3 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] TIME_Fibonacci_Recursive.40
实例中测试了四个测试用例,分别测试了两个函数分别计算Fibonacci(30)和Fibonacci(40)所花费的时间。测试用例1、2比较简单,仅有一个ASSERT_TIME断言用于测试运行到此该测试用例花费的时间。测试用例3、4,增加了两条语句:TEST_T_SHOWTIME(),测试用例结束后打印执行时间;EXCEPT_TIME断言,这里只是测试以下EXCEPT_TIME和ASSERT_TIME的区别,前者继续执行后续语句,后者则结束当前的测试用例。