值参数不限定类型,也可以是类的引用,这就可以实现对类接口的测试,一个基类可以有多个继承类,那么可以测试不同的子类功能,但是只需要写一个测试用例,然后使用参数列表实现对每个子类的测试。
使用值参数测试法去测试多个实现了相同接口(类)的共同属性(又叫做接口测试)
using ::testing::TestWithParam; using ::testing::Values; typedef PrimeTable* CreatePrimeTableFunc(); PrimeTable* CreateOnTheFlyPrimeTable() {return new OnTheFlyPrimeTable(); } templatePrimeTable* 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 {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(1));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: #define INSTANTIATE_TEST_SUITE_P INSTANTIATE_TEST_CASE_P INSTANTIATE_TEST_SUITE_P(OnTheFlyAndPreCalculated, PrimeTableTestSmpl7,Values(&CreateOnTheFlyPrimeTable,&CreatePreCalculatedPrimeTable<1000>));
1.8sample8--值参数测试
有些时候,我们需要对代码实现的功能使用不同的参数进行测试,比如使用大量随机值来检验算法实现的正确性,或者比较同一个接口的不同实现之间的差别。gtest把“集中输入测试参数”的需求抽象出来提供支持,称为值参数化测试(Value Parameterized Test)。
参数值序列生成函数 | 含义 |
---|---|
Bool() | 生成序列 {false, true} |
Range(begin, end[, step]) | 生成序列 {begin, begin+step, begin+2*step, ...} (不含 end ), step 默认为1 |
Values(v1, v2, ..., vN) | 生成序列 {v1, v2, ..., vN} |
ValuesIn(container) , ValuesIn(iter1, iter2) | 枚举STL container ,或枚举迭代器范围 [iter1, iter2) |
Combine(g1, g2, ..., gN) | 生成 g1 , g2 , ..., gN 的笛卡尔积,其中g1 , g2 , ..., gN 均为参数值序列生成函数(要求C++0x的 |
代码实现
class HybridPrimeTable : public PrimeTable {public:HybridPrimeTable(bool force_on_the_fly, int max_precalculated): on_the_fly_impl_(new OnTheFlyPrimeTable),precalc_impl_(force_on_the_fly? nullptr: new PreCalculatedPrimeTable(max_precalculated)),max_precalculated_(max_precalculated) {}~HybridPrimeTable() override {delete on_the_fly_impl_;delete precalc_impl_;} bool IsPrime(int n) const override {if (precalc_impl_ != nullptr && n < max_precalculated_)return precalc_impl_->IsPrime(n);elsereturn on_the_fly_impl_->IsPrime(n);} int GetNextPrime(int p) const override {int next_prime = -1;if (precalc_impl_ != nullptr && p < max_precalculated_)next_prime = precalc_impl_->GetNextPrime(p); return next_prime != -1 ? next_prime : on_the_fly_impl_->GetNextPrime(p);} private:OnTheFlyPrimeTable* on_the_fly_impl_;PreCalculatedPrimeTable* precalc_impl_;int max_precalculated_; }; using ::testing::TestWithParam; using ::testing::Bool; using ::testing::Values; using ::testing::Combine; // To test all code paths for HybridPrimeTable we must test it with numbers // both within and outside PreCalculatedPrimeTable's capacity and also with // PreCalculatedPrimeTable disabled. We do this by defining fixture which will // accept different combinations of parameters for instantiating a // HybridPrimeTable instance. class PrimeTableTest : public TestWithParam< ::std::tuple> {protected:void SetUp() override {bool force_on_the_fly;int max_precalculated;std::tie(force_on_the_fly, max_precalculated) = GetParam();table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated);}void TearDown() override {delete table_;table_ = nullptr;}HybridPrimeTable* table_; };
PrimeTableTest类继承于TestWithParam,是测试固件类。接收参数tuple
测试编写:
TEST_P(PrimeTableTest, 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(PrimeTableTest, 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(PrimeTableTest, 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)); } #define INSTANTIATE_TEST_SUITE_P INSTANTIATE_TEST_CASE_P INSTANTIATE_TEST_SUITE_P(MeaningfulTestParameters, PrimeTableTest,Combine(Bool(), Values(1, 10)));
共计3个测试case,测试名为MeaningfulTestParameters,输入的参数是一个comine类,生成正交参数集合:
Combine(Bool(), Values(1, 10))); // Combine() allows the user to combine two or more sequences to produce // values of a Cartesian product of those sequences' elements. /*|--Bool--|--------- Value---------|| | 1 | 10 || true | (true,1) | (true,10) || false | (false,1) | (false,10) | */
本例有3个测试,参数正交后是4组参数,每组参数运行一次测试,所以输出12个测试结果。运行截图如下。
上一篇: 成熟低调有内涵的签名
下一篇: 女人最适合的微信名字大全