zoukankan      html  css  js  c++  java
  • 用gtest实现数据驱动的单元测试

    //使用gtest进行数据驱动的单元测试
    
    #include <gtest/gtest.h>  
    #include <iostream>
    #include <vector>
    #include <string>
    #include <fstream>
    #include "BuildAttrDesc.h"
    using namespace std;
    using namespace testing;
    //定义一个结构体,用于保存输入数据和期望结果的对比数据
    typedef struct
    {
       string myString;
       string productId;
       string standardAttr;
       string customAttr;
       string resultsExpect;
       string attrValueExpect;
    }datatype;
    //把vector返回给TEST_P,然后由TEST_P来处理相关的数据
    typedef ::std::vector<datatype> data;
    static data vec;
    //声明一个测试类,用来进行参数传递的类
    /*
    To write value-parameterized tests, first you should define a fixture class. 
    It must be derived from both ::testing::Test and ::testing::WithParamInterface<T> (the latter is a pure interface), 
    where T is the type of your parameter values. For convenience, you can just derive the fixture class from 
    ::testing::TestWithParam<T>, which itself is derived from both ::testing::Test and ::testing::WithParamInterface<T>. 
    T can be any copyable type. If it's a raw pointer, you are responsible for managing the lifespan of the pointed values.
    */
    class testBuildAttrDesc : public::testing::TestWithParam<datatype>{};
    
    /*
    The following class reads the envonrimental data from file "./dump_data/commodity_attribute_name_en","./dump_data/commodity_value_name_en", 
    every row consisted of the input and expected output from file "./dump_data/product_attribute/standard_custom_expect_attr.txt" and then push them into the vector
    */
    class Singleton
    { 
    public:
        CBuildAttrDesc* m_pBuildAttrDesc;
        static Singleton* getInstance()
        {
            if(_instance==NULL) _instance=new Singleton();
                return _instance;
        }
        ~Singleton()
        {
            delete m_pBuildAttrDesc;
            m_pBuildAttrDesc = NULL;
        }
    protected:
        Singleton()
        {
            datatype d;
            const string recordSeparator = "0103";
            const string fieldSeparator = "0102";
            string myString = "";
            string productId = "";
            string standardAttr = "";
            string customAttr = "";
            string resultsExpect = "";
            string attrValueExpect = "";
            vector<string> vStrArray;
            m_pBuildAttrDesc = new CBuildAttrDesc;
            m_pBuildAttrDesc->loadAttrNameValueMap("./dump_data/commodity_attribute_name_en","./dump_data/commodity_value_name_en", recordSeparator, fieldSeparator);
            if (!m_pBuildAttrDesc->initOk())
            {
                cout<<"CBuildAttrDesc init failed!"<<endl;
                exit(1);
            }else
                cout<<endl<<"sucess: Open files commodity_attribute_name_en.dump and commodity_value_name_en.dump"<<endl<<endl;
            ifstream inData("./dump_data/product_attribute/standard_custom_expect_attr.txt");//open the input files
            while(getline(inData, myString))
            {
                m_pBuildAttrDesc->splitStr(myString, "", vStrArray);
                if(5 != vStrArray.size())//total have five segments
                {
                cout<<"Format Error(the total record): "<<myString<<endl;
                continue;
                }
                d.productId = vStrArray[0];
                d.standardAttr = vStrArray[1];
                d.customAttr = vStrArray[2];
                d.resultsExpect = vStrArray[3];
                d.attrValueExpect = vStrArray[4];
                if(m_pBuildAttrDesc->isDigits(d.productId)==false)
                {
                 cout<<"Format Error(the product id): "<<d.productId<<endl;
                 continue;
                }
                cout<<endl<<"product id:     "<<d.productId<<endl;
                cout<<endl<<"standardAttr:   "<<d.standardAttr<<endl;
                cout<<endl<<"customAttr:     "<<d.customAttr<<endl;
                cout<<endl<<"resultsExpect:  "<<d.resultsExpect<<endl;
                cout<<endl<<"attrValueExpect:"<<d.attrValueExpect<<endl;
                vec.push_back(d);
             }
        }
    private:
            static Singleton *_instance;
    };
    Singleton* Singleton::_instance = NULL ;
    Singleton *single=Singleton::getInstance();
    
    
    /*
    Then, use the TEST_P macro to define as many test patterns using this fixture as you want. The _P suffix is for 
    "parameterized" or "pattern", whichever you prefer to think.
    */
    TEST_P(testBuildAttrDesc,HandleTrueReturn)
    {
        datatype n = GetParam();
        string results = "";
        string attrValue = "";
        // expected test
        single->m_pBuildAttrDesc->getAttrDesc(n.standardAttr,n.customAttr,results,attrValue);
        cout<<n.standardAttr<<endl<<n.customAttr<<endl<<results<<endl<<attrValue<<endl;
        EXPECT_STREQ(n.resultsExpect.c_str(),results.c_str());
        EXPECT_STREQ(n.attrValueExpect.c_str(),attrValue.c_str());
    }
    /*
    Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test case with any set of parameters you want. Google Test 
    defines a number of functions for generating test parameters. They return what we call (surprise!) parameter generators. 
    Here is a summary of them, which are all in the testing namespace:
    */
    INSTANTIATE_TEST_CASE_P(TrueReturn,testBuildAttrDesc,::testing::ValuesIn(vec));
    
    int main(int argc,char *argv[])
    {
        testing::InitGoogleTest(&argc,argv);
        RUN_ALL_TESTS();
        delete single;
        return 0;
    }
    

      

    gtest官方关于数据驱动单元测试的文档
    http://code.google.com/p/googletest/wiki/AdvancedGuide

  • 相关阅读:
    百奥谷
    3月13日火箭VS老鹰
    百度 hi 下载地址(内测版,正式版)
    中兴u980
    2008年清明节放假通知
    cyp740703 一个女人的自白
    黄唇鱼
    3月9日火箭vs黄蜂
    3月3日火箭vs掘金
    百度hi邀请码
  • 原文地址:https://www.cnblogs.com/laodageblog/p/3823822.html
Copyright © 2011-2022 走看看