单元测试c ++ setup()和拆解()

时间:2014-09-25 04:45:17

标签: unit-testing googlemock

我目前正在使用google mock学习单元测试。谷歌模拟中virtual void SetUp()virtual void TearDown()的常用用法是什么?使用代码的示例场景将是好的。提前谢谢。

2 个答案:

答案 0 :(得分:10)

在每个测试的开始和结束时都要考虑您想要的代码,以避免重复它。

例如:

namespace {
  class FooTest : public ::testing::Test {

  protected:
    Foo * pFoo_;

    FooTest() {
    }

    virtual ~FooTest() {
    }

    virtual void SetUp() {
      pFoo_ = new Foo();
    }

    virtual void TearDown() {
      delete pFoo_;
    }

  };

  TEST_F(FooTest, CanDoBar) {
      // You can assume that the code in SetUp has been executed
      //         pFoo_->bar(...)
      // The code in TearDown will be run after the end of this test
  }

  TEST_F(FooTest, CanDoBaz) {
     // The code from SetUp will have been executed *again*
     // pFoo_->baz(...)
      // The code in TearDown will be run *again* after the end of this test

  }

} // Namespace

答案 1 :(得分:1)

测试代码趋向于充满代码重复:编写个别测试方法来测试某些被测代码的不同方面是一种好习惯。结果是,对于某些测试功能,可能有许多不同的测试方法。并且,所有这些方法必须(原则上)实现以下步骤:

  • 准备(设置)被测代码的执行。这样做的目的是确保在执行时,被测试代码的环境和输入完全受测试控制。
  • 执行(执行)被测代码。
  • 评估(验证)结果,即检查实际结果是否符合期望。
  • 如有必要,请进行清理(拆除),以使后续测试可以从定义的起点开始。通常在此步骤中释放分配的资源,删除创建的文件,等等。

由于这些活动对于所有测试方法都是通用的,并且由于每种测试功能都有几种测试方法,因此可能存在一定数量的代码重复,尤其是在不同的设置和拆卸阶段。为了克服这个问题,在使用Google Test SetUp和TearDown的情况下,测试框架提供了将通用的设置和拆卸代码放入特殊方法的可能性。

执行模型如下:首先,创建带有测试方法的类的新实例(gtest中的夹具),这意味着调用了构造函数。其次,在该实例上运行SetUp方法(如果有)。这使SetUp方法有机会执行不同测试方法之间共有的所有设置活动。第三,分别称为测试方法(只是其中之一!)。在这里,再次进行设置/练习/验证/拆卸,但是关于设置,只需要执行那些尚未被SetUp方法覆盖的活动。同样,仅在该测试方法内完成特定于该测试方法的拆卸活动。第四,调用TearDown方法执行常见的清理活动,最后实例被销毁(调用析构函数)。然后,对下一个测试方法执行这五个步骤,依此类推。

关于TearDown的SetUp的一般想法就这么多。但是,实施测试时需要牢记一些事情:当然,SetUp和TearDown可以帮助减少跨测试的代码重复。但是,它们的使用会导致各种问题:

  • 测试方法的代码可能变得晦涩难懂,因为SetUp方法中存在一些与了解测试工作原理相关的活动。当然,有经验的开发人员会知道,在尝试了解测试方法时,他们还应该研究SetUp和TearDown,但是测试代码的可读性受到负面影响。
  • SetUp方法倾向于在各种测试方法之间累积功能:如果您有三种测试方法,并且其中两个共享某些设置代码,则可以将其添加到SetUp方法中。对于以后的测试代码阅读者而言,了解SetUp的哪些部分实际上属于哪种测试方法变得更加困难。这也使得对SetUp进行修改变得更加困难,因为预测哪种测试方法会受到更改的影响变得更加困难。

因此,采用不同的方法来减少跨测试方法的代码重复可能是有益的。您可以执行以下操作,而不是将通用代码放入由测试框架隐式调用的SetUp和TearDown中:您可以创建自己的具有易于理解名称的助手方法,例如“ ensureTrafficLightIsGreen”,其中包含各自的通用设置和拆卸代码。当然,这些方法不会在每个测试方法之前隐式调用,而是您将显式调用它们。这留下了一些代码重复,但是带来的好处是,从测试方法本身可以清楚地知道哪些设置活动实际发生。您自己的辅助方法当然可以带有参数,例如“ ensureTrafficLightIs(Green)”。