跟我学c++中级篇工具应用——gtest的动态参数

一、测试的场景

无论是在编程还是在测试的场景下,都会有重复代码的出现,有些重复代码可能具体到某种场景是需要的,但大多数情况下,重复的代码有着“腐化”的味道,需要把它们去除。需要注意的是,有的所谓重复代码,指的并不一定是完全重复的代码,可能是逻辑或者流程重复,这也需要同学们务必引起重视。
如果在测试中遇到一种场景,这种场景类似于泛型编程或者说c++中的模板编程的应用场景,只是参数类型,甚至参数类型都相同,只是具体的数值不同,如果因为这个让程序员们不断的重复写着EXPECT_TRUE这些类似的代码,程序员们心里会怎么样,用屁股都可以想到啊。
在gtest中,解决这种问题,就是用动态参数,或者说参数化。其实挺好理解,

二、动态参数的实现方式

正如上面所说,在gtest也是支持动态参数的两种形式:
1、普通的参数化,即不同的数值引起的参数动态变化。
2、数据类型的参数化,即不同的数据类型引起的参数动态变化。
前者好理解,后者类似于模板编程(泛型编程)。

三、例程

1、普通动态参数

class MyTest : public::testing::TestWithParam<int>
{

};
bool GetEven(int n)
{
    if (n == 0) return false;

    if (n % 2 == 0)
    {
        return true;
    }
    else
    {
        return false;
    }

    return true;
}
TEST(GetEvenTest, HandleTest)
{
    EXPECT_TRUE(GetEven(2));
    EXPECT_TRUE(GetEven(7));
    EXPECT_TRUE(GetEven(1));
    EXPECT_TRUE(GetEven(20));
    EXPECT_TRUE(GetEven(19));
}
TEST_P(MyTest, HandleTest)
{
    int n = GetParam();
    EXPECT_TRUE(GetEven(n));
}

// 定义参数
//INSTANTIATE_TEST_CASE_P();已经过时,使用下面这个替代
INSTANTIATE_TEST_SUITE_P(TestEven, MyTest, testing::Values(2,7, 1, 20, 19));
int main(int argc, char** argv)
{
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

看上面的例程可以明白文档中的说明了:
1、先创建自定义类继承testing::TestWithParam
2、将宏TEST转换为TEST_P。在此宏内使用GetParam()获取动态参数的实际值
3、利用INSTANTIATE_TEST_SUITE_P来输入动态参数,第一个参数自定义,第二个是自定义的类,第三个为动态参数值。
在gtest中设置动态参数的方法有以下几种:
1、Range(begin, end[, step]) begin至end间的数值,步长为step,不含end。
2、Values(v1, v2, …, vN) 上面实际应用的例子,表示括号内的数据集合。
3、ValuesIn(container) and ValuesIn(begin, end) 从数组、容器或迭代器中设置动态参数
4、Bool() 设置动态参数为true 和false.
5、Combine(g1, g2, …, gN) c++11后的参数生成器,利用tuple来生成动态参数。

2、数据类型动态参数

template <typename T>
class MyTempTest : public testing::Test {
public:

    typedef std::list<T> List;
    static T shared_ ;
    T value_;
};
template <typename T> T MyTempTest<T>::shared_;
typedef testing::Types<char, int, unsigned int> MyTem;
TYPED_TEST_SUITE(MyTempTest, MyTem);
TYPED_TEST(MyTempTest, doowner) {

    TypeParam num = this->value_;

    num += TestFixture::shared_;

    typename TestFixture::List v;
    v.push_back(num);

}

int main(int argc, char** argv)
{
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

数据类型的参数化使用方式:
1、写一个模板类,继承public testing::Test,并实现相关内容
2、定义具体的类型。
3、使用TYPED_TEST_SUITE来实现测试,第一个参数是自定义的模板类,第二个是数据类型
4、在TYPED_TEST中使用TypeParam获取具体的参数并编写测试功能
在gtest还有一种更灵活的方式,使用TYPED_TEST_P和REGISTER_TYPED_TEST_SUITE_P以及INSTANTIATE_TYPED_TEST_SUITE_P几个宏来实现,有兴趣可以看看,这里不再赘述。

四、总结

测试和开发的侧重点是不同的,测试强调的不是技术能力和对技术把握的多深(当然,把握的深肯定是没有坏处),更多的考查的测试人员对程序认知的角度,要想到一些异常,一些和开发人员不同的思维方式。前一阵一个国外的小姑娘乱点键盘能解开一个Linux操作系统的Bug,就是一种测试的Case,它其实代表着一种思想,一种边界案例测试的想法。
在国内整体环境上测试不太重视的情况下,开发人员自己多增加一些测试的思想,其实对以后升级到架构师,也有不小的裨益。思想变了,虽然上帝会发笑,但有可能就升华了。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值