2018-10-22心得

gtest

今天学习使用了gtest。gtest 主要使用方法就是在一个 TEST() / TEST_F () 里写测试用例,然后通过在main函数使用 RUN_ALL_TEST() 即可运行 gtest。
对于TEST_F 实际跟TEST 基本一样,但是它多了一个初始化功能,比如我们需要在进行这个测试用例前,需要构造一些临时的测试数据,那么就可以使用TEST_F。TEST_F 在gtest中也称为gtest的事件机制,所谓事件机制就是帮我们在测试列子的时候帮我们干些打杂的事情,比如帮我们生成一些测试数据,然后测试完了做一些清理工作

gtest 事件机制

gtest分为以下三个事件机制

  1. 全局事件
  2. test_case
  3. test
testcase 与 test

我们使用gtest的时候宏函数里面填的内容就是testcase,test。testcase 我的理解就相当于 我们要测那个案例,比如我们写了一个List想用gtest进行测试。testcase就是List,test就是List的具体功能比如插入、删除等等

TEST(testcase,test) 
全局事件

这个就是相当于一个全局初始化

// 全局事件
class GlobalTest : public testing::Environment {
public:
virtual void SetUp() {
std::cout << "SetUp" << std::endl;
}
virtual void TearDown() {
std::cout << "TearDown" << std::endl;
}
};
int main(int argc, char* argv[]) {
testing::InitGoogleTest(&argc, argv);
testing::Environment* env = new GlobalTest();
testing::AddGlobalTestEnvironment(env);
return RUN_ALL_TESTS();
}
test_case事件

test_case 的事件使用,TEST_F宏来实现具体测试。然后静态的实现 SetUpTestCase() 和 TearDownTestCase() 函数即可。使用TEST_F宏的时候其test_case必须是一个类名,并且这个类的基本结构如下所示。
它的初始函数(SetUpTestCase)在第一个test运行前执行, 清理函数(TearDownTestCase)在最后一个test运行后执行。

class test_case :: public testing::Test
{
   static void SetUpTestCase() {
    shared_resource_ = new ;
  }
   static void TearDownTestCase() {
    delete shared_resource_;
    shared_resource_ = NULL;
  }
TEST_F(test_case,test)
{
}
test事件

主要的主人公test事件级的测试,因为大多数我们都想每测一个功能,测试数据都不会收影响,所以每次测试的时候测试数据重新再次生成一遍是最好的了。它使用跟上面那个差不多,主要实现SetUp和TearDown即可。
主要使用起来,让我们感到舒服的是,我们可以把关于这个test_case的所有功能都以成员函数的方式写到自己实现的Test类里,然后在TEST_F宏里面直接调用这些成员函数即可,这样就可以一边测试一边开发,帮助减少bug,这也就是传说中的测试驱动开发(Test Driver Development)

class Data {
    void init()
    {
       构造测试数据
    }
    void Destroy()
    {
        释放测试数据
    }
};
class Test:: public testing::Test 
{
    public :
      virtual void SetUp()
      {
          data.init();
      }
      virtual void TearDown()
      {
          data.Destroy();
      }
      void Fun()
      {
         使用data初始的测试数据然后执行一些关于被测对象的逻辑
      }
      int TestFun()
      {
          Fun();
          if(A.success)
           return 1;
          else
           return 0;
      }
    private:
       Data data;
       A  a; //被测数据
 }
 TEST_F(Test,test1)
 {
     ASSERT_EQ(1,TestFun());
 }
test_F
#include<gtest/gtest.h>
class Foo::public testing::test {
  protected :
  void Fun()
  {}  
};

TEST_F(Foo,Foo_test1)
{
  Foo::Fun();
}

class Foo::public testing::test {
  protected :
  void Fun() 
  {}
};

class Foo_Foo_test1_Test : public Foo { 
public: 
Foo_Foo_test1_Test() {} 
private: 
virtual void TestBody(); 
static ::testing::TestInfo* const test_info_ __attribute__ ((unused)); 
Foo_Foo_test1_Test(Foo_Foo_test1_Test const &); 
void operator=(Foo_Foo_test1_Test const &);
};

::testing::TestInfo* const Foo_Foo_test1_Test ::test_info_ = 
::testing::internal::MakeAndRegisterTestInfo( "Foo", "Foo_test1", __null, __null,
(::testing::internal::GetTypeId<Foo>()), Foo::SetUpTestCase, Foo::TearDownTestCase, new
::testing::internal::TestFactoryImpl< Foo_Foo_test1_Test>);

void Foo_Foo_test1_Test::TestBody()
{
  Foo::Fun();
}

今天发现为什么TEST_F宏里面可以访问 我们自定义的test类的protected成员。凭直觉我想到能这样处理要么gtest把TEST_F宏的宏函数变成一个实际的函数,然后这个函数是我们自定义test类的友元函数,要么gtest 自定义了一个类,宏函数是这个类的成员函数,然后gtest自定义类继承了我们定义的test类。经过编译宏展开发现,确实gtest自己搞了一个类public继承了我们定义的test类,所以它可以访问test类的protect成员在宏函数中,但是它并没有自己定义一个类似TEST_F宏函数的成员函数,只是把所有TEST_F宏内的内容搬移到了一个TestBody里的函数中,然后转掉这个TestBody而已。

Base64

项目中使用到了很多base64编码,期初我以为这个玩意是用来序列化和反序列化的,但是我发现项目中的数据已经使用了 protobuf序列化后再进行的base64编码,所以我想到可能base64不是用来序列化的,所以一查才发现它是用来处理二进制数据的不可见数据的,因为可能二进制数据在网络传输中因为某些不可见数据或者 CRCF这种导致数据传输错误,所以使用 base64 把二进制数据转换为 纯文本数据方便传输防止出错

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值