zoukankan      html  css  js  c++  java
  • gtest框架使用

    gtest文档说明:

    由于公司单元测试的需要,自己花了大半天时间下载了一个gtest框架,使用了一些测试例子,总览了coderzh的玩转gtest测试框架,又看了几篇gtest博客,写下了以下内容,作为备忘。毕竟我需要的简单的东西,太复杂了我自己很难回顾起来。在此很感谢coderzh,他的玩转google开源框架gtest系列的文章真的不错,极力推荐。链接地址:http://www.cnblogs.com/coderzh/archive/2009/04/06/1426755.html,这篇文件就比较深入了一些,适合深入研究的人看。


    工程项目简介与基本配置:

    1,改造了一下gtest的目录结构,与我们平常使用的工程目录接口相匹配
    2,使用gtest库,需要头文件位于includegtest目录下,需要lib文件位于libgtestd.lib。
    3,注意工程配置需要配置成多线程调试模式,即MTd模式。vs20080->属性->配置属性->代码生成->运行时库->多线程调试(/MTd)
    4,工程需要包含头文件includegtestgtest.h,需要包含库目录libgtestd.lib。


    //-----------------------------------------------------------------------------

    比较测试:

    //基本代码框架
    TEST(TestSuitEqualTest, TestCase1)
    {
    EXPECT_EQ(1, min(1,2));//可以通过
    }

    1,数值型比较:

    EXPECT_EQ(1, min(1,2));//可以通过
    EXPECT_EQ(1, min(10,2));//不可以通过

    EXPECT_EQ传递的两个参数左边是期待的值,右边是自己的函数,即要测试的函数。
    比较还有有一系列的函数如下:
    //    * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual
    //    * {ASSERT|EXPECT}_NE(v1, v2):           Tests that v1 != v2
    //    * {ASSERT|EXPECT}_LT(v1, v2):           Tests that v1 < v2
    //    * {ASSERT|EXPECT}_LE(v1, v2):           Tests that v1 <= v2
    //    * {ASSERT|EXPECT}_GT(v1, v2):           Tests that v1 > v2
    //    * {ASSERT|EXPECT}_GE(v1, v2):           Tests that v1 >= v2
    断言assert与expect的区别是expect出现失败会在当前函数中继续运行下去,assert失败后退出当前函数,但是并不会退出整个程序。

    2,bool值比较

    //true false比较
    EXPECT_TRUE(true);//可以通过
    EXPECT_FALSE(true);//不可以通过
    对于这种true,false测试可以打印传入的参数。
    EXPECT_PRED2(MutuallyPrime, m, n);//yes

    3,字符串比较
    //字符串 不区分大小写比较
    EXPECT_STRCASEEQ("how", "how");//yes
    EXPECT_STRCASEEQ("how", "HOW");//yes
    EXPECT_STRCASEEQ("how", "how are");//no

    //字符串 区分大小写比较
    EXPECT_STREQ("how", "how");//yes
    EXPECT_STREQ("how", "HOW");//no
    EXPECT_STREQ("how", "how are");//no

    4,案例失败时候能够精确定位问题所在

    int n = -1;  
    bool actualResult = Foo::Dosometing(n);  
    ASSERT_TRUE(actualResult) << "Call Foo::Dosometing(n) when n = " << n;


    //-----------------------------------------------------------------------------

    事件机制:

    gtest提供了多种事件机制,以便在案例执行之前准备测试数据和测试之后释放相关资源。gtest的事件一共有3种:
    全局的,所有案例执行前后(继承testing::Environment类,实现里面的SetUp和TearDown方法 )
    TestSuite级别的,在某一批案例中第一个案例前,最后一个案例执行后(继承testing::Test类,实现里面的SetUpTestCase和TearDownTestCase静态方法
    TestCase级别的,每个TestCase前后(继承testing::Test类,实现里面的SetUp和TearDown方法 )
    全局级别的:
    //全局事件

    class FooEnvironment : public testing::Environment
    {
    public:
    	virtual void SetUp()
    	{
    		std::cout << "Foo FooEnvironment SetUP" << std::endl;
    	}
    	virtual void TearDown()
    	{
    		std::cout << "Foo FooEnvironment TearDown" << std::endl;
    	}
    };



    在main函数中添加:

    testing::AddGlobalTestEnvironment(new FooEnvironment());
    	
    class FooTest : public testing::Test
    {
    protected:
        static void SetUpTestCase(){ cout << "SetUpTestCase" << endl;}
        static void TearDownTestCase(){ cout << "TearDownTestCase" << endl;}
        static int m_nShareAllCaseInt;//此变量为一个testsuit的所有case公有
    protected:
        virtual void SetUp(){ cout << "SetUp" << endl;}
        virtual void TearDown(){ cout << "TearDown" << endl;}   
        int m_nCaseInt;//此变量为每一个case自己所有
    };
    int FooTest::m_nShareAllCaseInt=100;



    //仔细分析c++的静态成员变量和普通成员变量就明白了,m_nShareAllCaseInt为类的成员变量,为公有;m_nCaseInt为对象成员变量,每一个对象自己所有
    //TEST_F实际上是创建了一个类继承于FooTest,同时创建了此类的对象。因此下面两个TEST_F公有一个静态成员变量,各自私有m_nCaseInt

    TEST_F(FooTest, Test0){ cout << "Test0" << endl;}
    TEST_F(FooTest, Test1){ cout << "Test1" << endl;}


    //-----------------------------------------------------------------------------

    //批量参数测试

    class ParamTest : public::testing::TestWithParam<int>
    {
    };
    TEST_P(ParamTest, aLotTest)
    {
    	int n = GetParam();
    	int m = GetParam();
    	cout<<"m="<<m<<" n="<<n<<endl;
    	EXPECT_TRUE(m == n);
    }
    INSTANTIATE_TEST_CASE_P(EqualParamTest, ParamTest, testing::Values(1, 10, 100, 1000, 10000));//参数生成器


    //批量化测试:

    INSTANTIATE_TEST_CASE_P(PreName, myTest, testing::Values(1, 10, 100, 1000, 10000));

    第一个参数是测试结束时进行打印的一系列测试案例的前缀,无限制。 
    第二个参数是测试case的名称,需要和之前定义的参数化的类的名称相同,在这个例子里是myTest.
    第三个参数就是参数生成器。除了上面的例子所使用的test::Values,gtest还提供了一系列的参数生成的函数:
    Range(begin, end[, step]) 范围在begin~end之间,步长为step,不包括end
    Values(v1, v2, ..., vN) v1,v2到vN的值
    ValuesIn(container) and ValuesIn(begin, end) 从一个C类型的数组或是STL容器,或是迭代器中取值
    Bool() 取false 和 true 两个值 
    Combine(g1, g2, ..., gN) 这个比较强悍,它将g1,g2,...gN进行排列组合,g1,g2,...gN本身是一系列参数生成器,每次分别从g1,g2,..gN中各取出一个值,组合成一个元组(Tuple)作为一个参数。


    //-----------------------------------------------------------------------------

    //简单白盒测试例子

    class Foo//待测试类
    {public:
    	Foo(void): sum(0){}
    	void add(int num){ sum += num;}
    	void print(){ std::cout << sum << std::endl;}
    	friend class unittest_Foo;//声明友类
    private:
    	int sum;//私有变量
    };
    class unittest_Foo : public testing::Test		
    {public:
    	static void test_foo()	{//可以任意访问A的私有变量和私有函数
    		Foo a;	ASSERT_EQ(a.sum, 0);
    		a.add(0); ASSERT_EQ(a.sum, 0);
    		a.add(100); ASSERT_EQ(a.sum, 100);}
    };
    TEST_F(unittest_Foo, test_foo){	unittest_Foo::test_foo();}



    //-----------------------------------------------------------------------------

    //运行参数:

    gtest提供多种方式来设置运行参数。其中使用命令行参数最为常用。


    --gtest_filter :对执行的测试案例进行过滤,支持通配符
    ?    单个字符
    *    任意字符
    -    排除,如,-a 表示除了a
    :    取或,如,a:b 表示a或b
    比如下面的例子:
    ./foo_test 没有指定过滤条件,运行所有案例
    ./foo_test --gtest_filter=*   使用通配符,同样运行所有案例
    ./foo_test --gtest_filter=Foo.* 运行Foo案例集下所有案例
    ./foo_test --gtest_filter=Foo.test 运行案例Foo.test


    --gtest_repeat :执行若干次
    ./foo_test -- gtest_repeat=5 重复执行5次

  • 相关阅读:
    【转】NHibernate主键类型介绍
    【转】NHibernate 各种数据库配置
    NHibernate常见错误
    NHibernate 设置主键不自增长
    Oracle 同名字段的该行数据按照创建时间最新的隐藏其他
    不用第三个变量就能交换两个变量值的五个方法
    Java IO 要点总结
    Java API 各个包的内容解释
    Ways to 优化JAVA程序设计和编码,提高JAVA性能
    Java菜鸟入坑学习要点
  • 原文地址:https://www.cnblogs.com/riskyer/p/3228625.html
Copyright © 2011-2022 走看看