googletest:sample7分析
目录
googletest:sample1
googletest:sample2
googletest:sample3
googletest:sample4
googletest:sample5
googletest:sample6
googletest:sample7
googletest:sample8
googletest:sample9
待测文件
同sample6,都是prime_tables.h
文件
PrimeTable
类声明了素数表的一系列接口,包括
1)IsPrime
:判断当前输入数n是否为素数;
2)GetNextPrime
:找比输入数n大的下一个素数.
文件内容略.
测试文件
sample6的测试,类型参数化测试,利用"typed test" "type-parameterized tests" 2种方法复用test,对不同类型的派生类进行测试.
sample7的测试,接口测试,利用"value-parameterized tests" 复用test,测试接口的多个实现的公共属性.
步骤:
1)利用工厂方法CreateOnTheFlyPrimeTable, CreatePreCalculatedPrimeTable
创建待测对象;
2)利用夹具类的Setup(),TearDown()
负责待测对象的创建、销毁;
3)利用TEST_P()
定义test;
4)利用INSTANTIATE_TEST_SUITE_P
初始化作为测试参数的值列表.
tips: TEST_P(test_suite_name, test_name)
定义一个test,test_suite_name
必须匹配测试夹具名,test_name
是自定义test名称.
// This sample shows how to test common properties of multiple
// implementations of an interface (aka interface tests) using
// value-parameterized tests. Each test in the test case has
// a parameter that is an interface pointer to an implementation
// tested.
// The interface and its implementations are in this header.
#include "prime_tables.h"
#include "gtest/gtest.h"
namespace {
using ::testing::TestWithParam;
using ::testing::Values;
// As a general rule, to prevent a test from affecting the tests that come
// after it, you should create and destroy the tested objects for each test
// instead of reusing them. In this sample we will define a simple factory
// function for PrimeTable objects. We will instantiate objects in test's
// SetUp() method and delete them in TearDown() method.
typedef PrimeTable* CreatePrimeTableFunc();
PrimeTable* CreateOnTheFlyPrimeTable() { return new OnTheFlyPrimeTable(); }
template <size_t max_precalculated>
PrimeTable* CreatePreCalculatedPrimeTable() {
return new PreCalculatedPrimeTable(max_precalculated);
}
// Inside the test body, fixture constructor, SetUp(), and TearDown() you
// can refer to the test parameter by GetParam(). In this case, the test
// parameter is a factory function which we call in fixture's SetUp() to
// create and store an instance of PrimeTable.
class PrimeTableTestSmpl7 : public TestWithParam<CreatePrimeTableFunc*> {
public:
~PrimeTableTestSmpl7() override { delete table_; }
void SetUp() override { table_ = (*GetParam())(); }
void TearDown() override {
delete table_;
table_ = nullptr;
}
protected:
PrimeTable* table_;
};
TEST_P(PrimeTableTestSmpl7, ReturnsFalseForNonPrimes) {
EXPECT_FALSE(table_->IsPrime(-5));
EXPECT_FALSE(table_->IsPrime(0));
EXPECT_FALSE(table_->IsPrime(1));
EXPECT_FALSE(table_->IsPrime(4));
EXPECT_FALSE(table_->IsPrime(6));
EXPECT_FALSE(table_->IsPrime(100));
}
TEST_P(PrimeTableTestSmpl7, ReturnsTrueForPrimes) {
EXPECT_TRUE(table_->IsPrime(2));
EXPECT_TRUE(table_->IsPrime(3));
EXPECT_TRUE(table_->IsPrime(5));
EXPECT_TRUE(table_->IsPrime(7));
EXPECT_TRUE(table_->IsPrime(11));
EXPECT_TRUE(table_->IsPrime(131));
}
TEST_P(PrimeTableTestSmpl7, CanGetNextPrime) {
EXPECT_EQ(2, table_->GetNextPrime(0));
EXPECT_EQ(3, table_->GetNextPrime(2));
EXPECT_EQ(5, table_->GetNextPrime(3));
EXPECT_EQ(7, table_->GetNextPrime(5));
EXPECT_EQ(11, table_->GetNextPrime(7));
EXPECT_EQ(131, table_->GetNextPrime(128));
}
// In order to run value-parameterized tests, you need to instantiate them,
// or bind them to a list of values which will be used as test parameters.
// You can instantiate them in a different translation module, or even
// instantiate them several times.
//
// Here, we instantiate our tests with a list of two PrimeTable object
// factory functions:
INSTANTIATE_TEST_SUITE_P(OnTheFlyAndPreCalculated, PrimeTableTestSmpl7,
Values(&CreateOnTheFlyPrimeTable,
&CreatePreCalculatedPrimeTable<1000>));
} // namespace
用宏INSTANTIATE_TEST_SUITE_P
+ Values
实例化包含一个包含2个PrimeTable对象工厂方法的列表,GTest就会进行value-parameterized tests,为每个参数实例化test;
INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...)
实例化一个test suite,"prefix"是test_suite_name的前缀名,"test_suite_name"是组件名,"..."包含了要用作test parameters的值列表.
而在Test, Test Fixture的ctor, Setup(), TearDown()中,可通过GetParam()
获取列表中的参数.
小结
3个宏TEST, TEST_F, TEST_P, TYPED_TEST区别:
- TEST
用于创建最简单的test,定义一个测试函数,在其中可定义任何C++代码并用gtest提供的断言进行检查. 不需要继承任何类.
语法:
TEST(test_suite_name, test_name)
其中,test_suite_name
测试组件名,test_name
测试名.
- TEST_F
用于创建需要共享测试对象的test,需要搭配自定义test fixture(测试夹具,继承自testing::Test)类使用,用virtual Setup(), TearDown()管理测试对象执行test前的初始化、执行后的清理工作.
TEST_F(test_fixture, test_name)
其中,test_fixture
测试夹具名,test_name
测试名.
- TEST_P
用于参数化test. 允许开发者为同一个test提供多个参数,自动为每个参数生成一个单独的test. 通过INSTANTIATE_TEST_SUITE_P
指定数据集,GTest自动为每个数据在运行时生成相应的test并执行.
TEST_P(test_suite_name, test_name)
其中,test_suite_name
测试组件名,需匹配测试夹具名,test_name
测试名.
示例:sample7
- TYPED_TEST
用于类型化test,针对多种类型需要复用同一test的情形. 基于C++模板实现.
TYPED_TEST(CaseName, TestName)
其中,CaseName
用例名,需要匹配测试夹具名,TestName
测试名.
示例:sample6