IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 跟我学c++中级篇工具应用——gtest的事件 -> 正文阅读

[开发测试]跟我学c++中级篇工具应用——gtest的事件

一、gtest的事件

gtest的事件机制其实是对单元测试的另外一种表现形式,它有两类基本的意义:
1、它可以在指定条件和场景前后处理相关数据
2、它可以提供指定条件和场景前后的结果通知
gtest中的事件分成基本的三个层次,即整个测试程序,相关测试的组或者说套件,最后是测试用例。因此,gtest中有三类基本的事件机制:
1、全局事件
在所有的Case执行前后动作,需要自定义一个测试类,继承testing::Environment类,实现使用的标记SetUp(),TearDown()两个虚函数,在所有测试开始前执行SetUp函数,测试结束后执行TearDown函数,这种事件是针对整个应用程序的,需要在main函数中调用testing::AddGlobalTestEnvironment(new MyEnvironment);。
2、组处理事件
在每组执行前后动作,需要定义一个类,继承testing::Test,实现应用标记TearDownTestCase()和SetUpTestCase()两个静态函数。它同样需要在组执行前执行这两个相关函数;它不需要像上面找全局事件需要注册,但是需要把TEST宏改为TEST_F宏。
3、Case事件
在每个案例Case执行前后动作,和组事件创建类似,它使用的标记是SetUp(),TearDown()两个函数,注意,非静态。需要在执行案例前调用这两个相关函数即可。
这个其实很好理解,无论是哪种工作,一定会有单个处理、批处理和所有处理这几大类别,它和现实是对应的。这样想,就明白了。

二、源码

看一下这些事件的源码:

class GTEST_API_ Test {
 public:
  friend class TestInfo;

  // The d'tor is virtual as we intend to inherit from Test.
  virtual ~Test();

  // Sets up the stuff shared by all tests in this test suite.
  //
  // Google Test will call Foo::SetUpTestSuite() before running the first
  // test in test suite Foo.  Hence a sub-class can define its own
  // SetUpTestSuite() method to shadow the one defined in the super
  // class.
  static void SetUpTestSuite() {}

  // Tears down the stuff shared by all tests in this test suite.
  //
  // Google Test will call Foo::TearDownTestSuite() after running the last
  // test in test suite Foo.  Hence a sub-class can define its own
  // TearDownTestSuite() method to shadow the one defined in the super
  // class.
  static void TearDownTestSuite() {}

  // Legacy API is deprecated but still available. Use SetUpTestSuite and
  // TearDownTestSuite instead.
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
  static void TearDownTestCase() {}
  static void SetUpTestCase() {}
#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_

  // Returns true if and only if the current test has a fatal failure.
  static bool HasFatalFailure();

  // Returns true if and only if the current test has a non-fatal failure.
  static bool HasNonfatalFailure();

  // Returns true if and only if the current test was skipped.
  static bool IsSkipped();

  // Returns true if and only if the current test has a (either fatal or
  // non-fatal) failure.
  static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }

  // Logs a property for the current test, test suite, or for the entire
  // invocation of the test program when used outside of the context of a
  // test suite.  Only the last value for a given key is remembered.  These
  // are public static so they can be called from utility functions that are
  // not members of the test fixture.  Calls to RecordProperty made during
  // lifespan of the test (from the moment its constructor starts to the
  // moment its destructor finishes) will be output in XML as attributes of
  // the <testcase> element.  Properties recorded from fixture's
  // SetUpTestSuite or TearDownTestSuite are logged as attributes of the
  // corresponding <testsuite> element.  Calls to RecordProperty made in the
  // global context (before or after invocation of RUN_ALL_TESTS and from
  // SetUp/TearDown method of Environment objects registered with Google
  // Test) will be output as attributes of the <testsuites> element.
  static void RecordProperty(const std::string& key, const std::string& value);
  static void RecordProperty(const std::string& key, int value);

 protected:
  // Creates a Test object.
  Test();

  // Sets up the test fixture.
  virtual void SetUp();

  // Tears down the test fixture.
  virtual void TearDown();

 private:
  // Returns true if and only if the current test has the same fixture class
  // as the first test in the current test suite.
  static bool HasSameFixtureClass();

  // Runs the test after the test fixture has been set up.
  //
  // A sub-class must implement this to define the test logic.
  //
  // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM.
  // Instead, use the TEST or TEST_F macro.
  virtual void TestBody() = 0;

  // Sets up, executes, and tears down the test.
  void Run();

  // Deletes self.  We deliberately pick an unusual name for this
  // internal method to avoid clashing with names used in user TESTs.
  void DeleteSelf_() { delete this; }

  const std::unique_ptr<GTEST_FLAG_SAVER_> gtest_flag_saver_;

  // Often a user misspells SetUp() as Setup() and spends a long time
  // wondering why it is never called by Google Test.  The declaration of
  // the following method is solely for catching such an error at
  // compile time:
  //
  //   - The return type is deliberately chosen to be not void, so it
  //   will be a conflict if void Setup() is declared in the user's
  //   test fixture.
  //
  //   - This method is private, so it will be another compiler error
  //   if the method is called from the user's test fixture.
  //
  // DO NOT OVERRIDE THIS FUNCTION.
  //
  // If you see an error about overriding the following function or
  // about it being private, you have mis-spelled SetUp() as Setup().
  struct Setup_should_be_spelled_SetUp {};
  virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; }

  // We disallow copying Tests.
  GTEST_DISALLOW_COPY_AND_ASSIGN_(Test);
};

注意区分全局和个例,名字相同的函数的性质不同。

三、事件例程

把gtest中的断言基本描述了一遍,下面看几个例子

#include <iostream>
#include <gtest/gtest.h>
#include <string>
#include <vector>
#include <iostream>

//注意看运行结果就明白了
//全局
class MyGlobalTest :public testing::Environment
{
public:
    virtual void SetUp()
    {
        std::cout << "Global test SetUp" << std::endl;
    }

    virtual void TearDown()
    {
        std::cout << "Global test TearDown" << std::endl;
    }

    std::vector<std::string> vec;
};

//组:SetUpTestCase()和TearDownTestCase()
class MyTestSuite :public testing::Test
{
public:
    static void SetUpTestCase()
    {
        std::cout << "Suite test SetUpTestCase()" << std::endl;
    }

    static void TearDownTestCase()
    {
        std::cout << "Suite test TearDownTestCase()" << std::endl;
    }

    void SetUp()
    {
        std::cout << "Suite test SetUp()" << std::endl;
        vec.emplace_back("aaa");
        vec.emplace_back("bbb");
        vec.emplace_back("ccc");
        vec.emplace_back("ddd");
    }

    void TearDown()
    {
        vec.clear();
        std::cout << "Suite test TearDown()" << std::endl;
    }

    std::vector<std::string> vec;
};

class MyTestCase :public testing::Test
{
public:
    void SetUp()
    {
        std::cout << "Case SetUp" << std::endl;
    }
    void TearDown()
    {
        std::cout << "Case TearDown" << std::endl;
    }
};

TEST_F(MyTestSuite, Find)
{
    std::vector<std::string>::iterator it = vec.begin()+1;
    ASSERT_NE(it, vec.end());
}

TEST_F(MyTestSuite, Size)
{
    ASSERT_EQ(6, vec.size());
}

TEST(MyGlobalTest, test0)
{
    EXPECT_EQ(6, 3);
}

TEST_F(MyTestCase, ZeroEqual)
{
    EXPECT_EQ(0, 0);
}

int main(int argc, char** argv)
{
    testing::InitGoogleTest(&argc, argv);
    testing::Environment* env = new MyGlobalTest();
    testing::AddGlobalTestEnvironment(env);
    return RUN_ALL_TESTS();
}

运行结果是:

[==========] Running 4 tests from 3 test suites.
[----------] Global test environment set-up.
Global test SetUp
[----------] 2 tests from MyTestSuite
Suite test SetUpTestCase()
[ RUN      ] MyTestSuite.Find
Suite test SetUp()
Suite test TearDown()
[       OK ] MyTestSuite.Find (0 ms)
[ RUN      ] MyTestSuite.Size
Suite test SetUp()
D:\vs2019_project\gtestSamples\gtestSamples.cpp(81): error: Expected equality of these values:
  6
  vec.size()
    Which is: 4
Suite test TearDown()
[  FAILED  ] MyTestSuite.Size (1 ms)
Suite test TearDownTestCase()
[----------] 2 tests from MyTestSuite (2 ms total)

[----------] 1 test from MyGlobalTest
[ RUN      ] MyGlobalTest.test0
D:\vs2019_project\gtestSamples\gtestSamples.cpp(86): error: Expected equality of these values:
  6
  3
[  FAILED  ] MyGlobalTest.test0 (0 ms)
[----------] 1 test from MyGlobalTest (0 ms total)

[----------] 1 test from MyTestCase
[ RUN      ] MyTestCase.ZeroEqual
Case SetUp
Case TearDown
[       OK ] MyTestCase.ZeroEqual (0 ms)
[----------] 1 test from MyTestCase (1 ms total)

[----------] Global test environment tear-down
Global test TearDown
[==========] 4 tests from 3 test suites ran. (6 ms total)
[  PASSED  ] 2 tests.
[  FAILED  ] 2 tests, listed below:
[  FAILED  ] MyTestSuite.Size
[  FAILED  ] MyGlobalTest.test0

 2 FAILED TESTS

对比着结果就可以很清楚的看到使用的效果。

三、总结

gtest的事件应用还有很多的情况,在实践中需要不断的总结和应用相关的技巧,只要不断的学习,就会有量变到质变的过程,坚持不懈,深入底层才能不断的把技术锤炼到更高的境界。
在这里插入图片描述

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-12-06 15:33:46  更:2021-12-06 15:33:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 4:33:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码