GTEST使用二
接上篇GTEST使用,https://developer.ibm.com/articles/au-googletestingframework/,这个地址介绍的更为简介易懂。
为什么要用GTEST
一些bad内存问题只有在某些运行的时候才会出现。gtest 对此提供了很好的支持。你可以重复很简单的就重复测试100次。当第一次出现的时候,会自动的开启调试调用。只需要命令行中添加这两个选项:–gtest_repeat=1000 --gtest_break_on_failure
gtest内置了assertion
运行case简单,你需要使用使用预定义的宏 RUN_ALL_TESTS。这个是CPPUNIT完全不同的地方,他需要创建一个单独的运行类来进行测试
可以简单的产生一个XML结果 ,只需要增加 --gtest_output=“xml:”
基础测试
1.一个函数如下:
double square?root (const double);
你可以进行正负数测试
所以有如下case
2.单元测试
#include "gtest/gtest.h"
TEST (SquareRootTest, PositiveNos) {
EXPECT_EQ (18.0, square?root (324.0));
EXPECT_EQ (25.4, square?root (645.16));
EXPECT_EQ (50.3321, square?root (2533.310224));
}
TEST (SquareRootTest, ZeroAndNegativeNos) {
ASSERT_EQ (0.0, square?root (0.0));
ASSERT_EQ (?1, square?root (?22.0));
}
这个例子创建了一个SquareRootTest的测试,包含了PositiveNos和ZeroAndNegativeNos这两个测试 TEST是gtest.h中预定义的宏。EXPECT_EQ和ASSERT_EQ 同样也是,他俩的区别上篇介绍过,不再赘述。
3.运行 testcase
#include "gtest/gtest.h"
TEST(SquareRootTest, PositiveNos) {
EXPECT_EQ (18.0, square?root (324.0));
EXPECT_EQ (25.4, square?root (645.16));
EXPECT_EQ (50.3321, square?root (2533.310224));
}
TEST (SquareRootTest, ZeroAndNegativeNos) {
ASSERT_EQ (0.0, square?root (0.0));
ASSERT_EQ (?1, square?root (?22.0));
}
int main(int argc, char ??argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
::testing::InitGoogleTest 正如名字一样是初始化框架的,必须在RUN_ALL_TESTS前调用 RUN_ALL_TESTS必须只能调用一次,否则会有冲突。RUN_ALL_TESTS会自动的检测所有的TEST的宏。默认情况下,结果打印到标准输出。
4.输出如下:
Running main() from user_main.cpp
[==========] Running 2 tests from 1 test case.
[??????????] Global test environment set?up.
[??????????] 2 tests from SquareRootTest
[ RUN ] SquareRootTest.PositiveNos
..\user_sqrt.cpp(6862): error: Value of: sqrt (2533.310224)
Actual: 50.332
Expected: 50.3321
[ FAILED ] SquareRootTest.PositiveNos (9 ms)
[ RUN ] SquareRootTest.ZeroAndNegativeNos
[ OK ] SquareRootTest.ZeroAndNegativeNos (0 ms)
[??????????] 2 tests from SquareRootTest (0 ms total)
[??????????] Global test environment tear?down
[==========] 2 tests from 1 test case ran. (10 ms total)
[ PASSED ] 1 test.
[ FAILED ] 1 test, listed below:
[ FAILED ] SquareRootTest.PositiveNos
1 FAILED TEST
gtest的选项
你可以将输出结果 转存到XML中,方式是命令行使用–gtest_output=“xml:report.xml” 函数在某些情况成功某些情况失败,这是内存溢出的典型问题。这种情况在多运行几次的情况下就会出现。 --gtest_repeat=2 --gtest_break_on_failure 如果在命令行中加上这个运行,同样的test会运行2次,并且失败的时候,debugger自动被调用
不是所有的test每次都需要全部运行,如果你执行运行其中的某几个函数,可以使用模糊匹配来做这个。-gtest_filter=* 运行所有的test,–gtest_filter=SquareRoot* 仅运行SquareRootTest 的测试。如果你回想运行SquareRootTest 下的positive的测试,gtest_filter=SquareRootTest.-SquareRootTest.Zero。其中-SquareRootTest.Zero* 表示不运行SquareRootTest下以Zero开头的case
5.一个例子:
[arpan@tintin] ./test_executable ??gtest_output="xml:report.xml" ??gtest_repeat=2 ??
gtest_filter=SquareRootTest.??SquareRootTest.Zero?
Repeating all tests (iteration 1) . . .
Note: Google Test filter = SquareRootTest.??SquareRootTest.Z?
[==========] Running 1 test from 1 test case.
[??????????] Global test environment set?up.
[??????????] 1 test from SquareRootTest
[ RUN ] SquareRootTest.PositiveNos
..\user_sqrt.cpp (6854): error: Value of: sqrt (2533.310224)
Actual: 50.332
Expected: 50.3321
[ FAILED ] SquareRootTest.PositiveNos (2 ms)
[??????????] 1 test from SquareRootTest (2 ms total)
[??????????] Global test environment tear?down
[==========] 1 test from 1 test case ran. (20 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] SquareRootTest.PositiveNos
1 FAILED TEST
Repeating all tests (iteration 2) . . .
Note: Google Test filter = SquareRootTest.??SquareRootTest.Z?
[==========] Running 1 test from 1 test case.
[??????????] Global test environment set?up.
[??????????] 1 test from SquareRootTest
[ RUN ] SquareRootTest.PositiveNos
..\user_sqrt.cpp (6854): error: Value of: sqrt (2533.310224)
Actual: 50.332
Expected: 50.3321
[ FAILED ] SquareRootTest.PositiveNos (2 ms)
[??????????] 1 test from SquareRootTest (2 ms total)
[??????????] Global test environment tear?down
[==========] 1 test from 1 test case ran. (20 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] SquareRootTest.PositiveNos
1 FAILED TEST
暂时停用某些tests
6.用DISABLE_后缀暂时停用一个case
#include "gtest/gtest.h"
TEST (DISABLED_SquareRootTest, PositiveNos) {
EXPECT_EQ (18.0, square?root (324.0));
EXPECT_EQ (25.4, square?root (645.16));
EXPECT_EQ (50.3321, square?root (2533.310224));
}
OR
TEST (SquareRootTest, DISABLED_PositiveNos) {
EXPECT_EQ (18.0, square?root (324.0));
EXPECT_EQ (25.4, square?root (645.16));
EXPECT_EQ (50.3321, square?root (2533.310224));
}
7.包含DISABLE的示例输出如下
1 FAILED TEST
YOU HAVE 1 DISABLED TEST
用在命令行输入:gtest_also_run_disabled_tests 选项可以执行DISABLE的case,输出如下:
8.输出
[??????????] 1 test from DISABLED_SquareRootTest
[ RUN ] DISABLED_SquareRootTest.PositiveNos
..\user_sqrt.cpp(6854): error: Value of: square?root (2533.310224)
Actual: 50.332
Expected: 50.3321
[ FAILED ] DISABLED_SquareRootTest.PositiveNos (2 ms)
[??????????] 1 test from DISABLED_SquareRootTest (2 ms total)
[ FAILED ] 1 tests, listed below:
[ FAILED ] SquareRootTest. PositiveNos
浮点型数据比较
9.用于比较浮点数的宏
ASSERT_FLOAT_EQ (expected, actual)
ASSERT_DOUBLE_EQ (expected, actual)
ASSERT_NEAR (expected, actual, absolute_range)
EXPECT_FLOAT_EQ (expected, actual)
EXPECT_DOUBLE_EQ (expected, actual)
EXPECT_NEAR (expected, actual, absolute_range)
通常由于浮点数的在各不同CPU下和操作系统下,一个简单的的相等无法生效。比如ASSERT_FLOAT_EQ (2.00001, 2.000011) 可以通过。如果想要高精度的,需要ASSERT_NEAR (2.00001, 2.000011, 0.0000001) ,输出如下:
ASSERT_NEAR的输出
Math.cc(68): error: The difference between 2.00001 and 2.000011 is 1e?006, which exceeds
0.0000001, where
2.00001 evaluates to 2.00001,
2.000011 evaluates to 2.00001, and
0.0000001 evaluates to 1e?007.
death test
ASSERT_DEATH, ASSERT_EXIT等等
10.death test示例
#include "gtest/gtest.h"
double square?root (double num) {
if (num < 0.0) {
std::cerr << "Error: Negative Input\n";
exit(?1);
}
}
TEST (SquareRootTest, ZeroAndNegativeNos) {
ASSERT_EQ (0.0, square?root (0.0));
ASSERT_EXIT (square?root (?22.0), ::testing::ExitedWithCode(?1), "Error:
Negative Input");
}
int main(int argc, char ??argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
12.death test的原型
ASSERT_DEATH(statement, expected_message)
ASSERT_EXIT(statement, predicate, expected_message)
test fixtures
13.一个fixture示例
典型场景,在单元测试前,做一些个性化的初始化。比如你做一些时间和内存的占用测试,你就需要一些特定的代码来做这些测试
class myTestFixture1: public ::testing::Test {
public:
myTestFixture1( ) {
}
void SetUp( ) {
}
void TearDown( ) {
}
~myTestFixture1( ) {
}
};
text fixture的场景要使用TEST_F代替TEST,下面是一个简单的例子
14.一个简单的fixture用例
TEST_F (myTestFixture1, UnitTest1) {
.
}
TEST_F (myTestFixture1, UnitTest2) {
.
}
下面有几点需要注意:
- 初始化可以放在构造,也可以放在SetUp,取决于用户。
- 析构资源放在析构函数,还是TearDown也都可以。但是如果释放资源的的时候,需要处理异常的情况,你必须放在TearDwon,因为析构中throw Exception是未定义行为
- assertion的宏也可能会throw 异常,所以为了更好的维护性,assertion的宏也可以放在TearDwon中
- 通安一个的test fixture不会在多个case中使用,每一次测试会创建一个新的test fixture。比如14中的测试,SetUp会被调用两次,因为myFixture1 对象会被创建两次
总结
这是一个简介,如果需要更多了解,可以看google的网站 更高级的开发,推荐你学习一些其他的回归测试框架,比如BoostUnit 和CppUnit
|