当前位置: 首页 > 工具软件 > OFTest > 使用案例 >

gtest 中Setup TearDown SetUpTestCase和TearDownTestCase 的区别

刘瑞
2023-12-01
前言
    在单元测试中,我们经常需要在某个测试套件、测试用例或者整个测试运行之前进行前置条件设置及检查,或者运行之后对运行结果进行校验等操作。在gtest中,称之为事件机制。gtest将事件按照作用的范围不同进行划分,从大到小总共分为3个层次:
    1)整个测试层面,即在测试工程开始前和结束后进行;
    2)测试套件层面,即在某个测试套件开始前和结束后进行;
    3)测试用例层面,即在某个测试用例开始前和结束后进行;

2、测试层面事件实现
    要实现测试层面的事件,我们需要继承testing::Environment类,首先我们来看一下这个类的定义:   
  1. class Environment {  
  2.  public:  
  3.   virtual ~Environment() {}  
  4.   
  5.   // Override this to define how to set up the environment.  
  6.   virtual void SetUp() {}  
  7.   
  8.   // Override this to define how to tear down the environment.  
  9.   virtual void TearDown() {}  
  10.  private:  
  11.   struct Setup_should_be_spelled_SetUp {};  
  12.   virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }  
  13. };  

    这个类中有两个虚函数:SetUp和TearDown。我们的子类只需要实现这个方法即可。其中在SetUp方法中实现所有测试启动之前需要完成的操作,而TearDown函数中实现所有测试运行结束后需要进行的操作。例如:
  1. class GlobalEvent2 :   
  2.  public testing::Environment  
  3. {  
  4. public:  
  5.   
  6.  virtual void SetUp()  
  7.  {  
  8.   cout << "Before any case, Global 2" << endl;  
  9.  }  
  10.   
  11.  virtual void TearDown()  
  12.  {  
  13.   cout << "After all cases done, Global 2" << endl;  
  14.  }  
  15. };  

    然后,在main函数中,在RUN_ALL_TESTS()之前,我们调用如下语句:
    testing::AddGlobalTestEnvironment(new GlobalEnvent);
    将这个测试层面的的事件添加到事件列表即可。这样,在测试执行之前,系统会先执行GlobalEvent2的SetUp方法;在所有测试用例执行完之后,系统会执行GlobalEvent2的TearDown方法。另外,我们可以定义任意多个继承自testing::Environment的子类,以实现不同的全局事件。所有的子类的SetUp按照我们调用testing::AddGlobalTestEnvironment添加它们的先后顺序执行,而TearDown的执行顺序则与添加顺序相反。

3、测试套件层面事件
    要在测试套件层面上定义事件,我们需要继承testing::Test类,并覆盖它的静态方法:SetUpTestCase和TearDownTestCase.在继续之前我们首先看看testing::Test类的定义:
  1. class GTEST_API_ Test {  
  2.  public:  
  3.   friend class TestInfo;  
  4.   
  5.   // Defines types for pointers to functions that set up and tear down  
  6.   // a test case.  
  7.   typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc;  
  8.   typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc;  
  9.   
  10.   // The d'tor is virtual as we intend to inherit from Test.  
  11.   virtual ~Test();  
  12.   
  13.   // Sets up the stuff shared by all tests in this test case.  
  14.   //  
  15.   // Google Test will call Foo::SetUpTestCase() before running the first  
  16.   // test in test case Foo.  Hence a sub-class can define its own  
  17.   // SetUpTestCase() method to shadow the one defined in the super  
  18.   // class.  
  19.   static void SetUpTestCase() {}  
  20.   
  21.   // Tears down the stuff shared by all tests in this test case.  
  22.   //  
  23.   // Google Test will call Foo::TearDownTestCase() after running the last  
  24.   // test in test case Foo.  Hence a sub-class can define its own  
  25.   // TearDownTestCase() method to shadow the one defined in the super  
  26.   // class.  
  27.   static void TearDownTestCase() {}  
  28.   
  29.   // Returns true iff the current test has a fatal failure.  
  30.   static bool HasFatalFailure();  
  31.   
  32.   // Returns true iff the current test has a non-fatal failure.  
  33.   static bool HasNonfatalFailure();  
  34.   
  35.   // Returns true iff the current test has a (either fatal or  
  36.   // non-fatal) failure.  
  37.   static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }  
  38.   
  39.   // Logs a property for the current test, test case, or for the entire  
  40.   // invocation of the test program when used outside of the context of a  
  41.   // test case.  Only the last value for a given key is remembered.  These  
  42.   // are public static so they can be called from utility functions that are  
  43.   // not members of the test fixture.  Calls to RecordProperty made during  
  44.   // lifespan of the test (from the moment its constructor starts to the  
  45.   // moment its destructor finishes) will be output in XML as attributes of  
  46.   // the <testcase> element.  Properties recorded from fixture's  
  47.   // SetUpTestCase or TearDownTestCase are logged as attributes of the  
  48.   // corresponding <testsuite> element.  Calls to RecordProperty made in the  
  49.   // global context (before or after invocation of RUN_ALL_TESTS and from  
  50.   // SetUp/TearDown method of Environment objects registered with Google  
  51.   // Test) will be output as attributes of the <testsuites> element.  
  52.   static void RecordProperty(const std::string& key, const std::string& value);  
  53.   static void RecordProperty(const std::string& key, int value);  
  54.   
  55.  protected:  
  56.   // Creates a Test object.  
  57.   Test();  
  58.   
  59.   // Sets up the test fixture.  
  60.   virtual void SetUp();  
  61.   
  62.   // Tears down the test fixture.  
  63.   virtual void TearDown();  
  64.   
  65.  private:  
  66.   // Returns true iff the current test has the same fixture class as  
  67.   // the first test in the current test case.  
  68.   static bool HasSameFixtureClass();  
  69.   
  70.   // Runs the test after the test fixture has been set up.  
  71.   //  
  72.   // A sub-class must implement this to define the test logic.  
  73.   //  
  74.   // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM.  
  75.   // Instead, use the TEST or TEST_F macro.  
  76.   virtual void TestBody() = 0;  
  77.   
  78.   // Sets up, executes, and tears down the test.  
  79.   void Run();  
  80.   
  81.   // Deletes self.  We deliberately pick an unusual name for this  
  82.   // internal method to avoid clashing with names used in user TESTs.  
  83.   void DeleteSelf_() { delete this; }  
  84.   
  85.   // Uses a GTestFlagSaver to save and restore all Google Test flags.  
  86.   const internal::GTestFlagSaver* const gtest_flag_saver_;  
  87.   
  88.   // Often a user mis-spells SetUp() as Setup() and spends a long time  
  89.   // wondering why it is never called by Google Test.  The declaration of  
  90.   // the following method is solely for catching such an error at  
  91.   // compile time:  
  92.   //  
  93.   //   - The return type is deliberately chosen to be not void, so it  
  94.   //   will be a conflict if a user declares void Setup() in his test  
  95.   //   fixture.  
  96.   //  
  97.   //   - This method is private, so it will be another compiler error  
  98.   //   if a user calls it from his test fixture.  
  99.   //  
  100.   // DO NOT OVERRIDE THIS FUNCTION.  
  101.   //  
  102.   // If you see an error about overriding the following function or  
  103.   // about it being private, you have mis-spelled SetUp() as Setup().  
  104.   struct Setup_should_be_spelled_SetUp {};  
  105.   virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }  
  106.   
  107.   // We disallow copying Tests.  
  108.   GTEST_DISALLOW_COPY_AND_ASSIGN_(Test);  
  109. };  

    从testing::Test类的声明可以看到,SetUpTestCase和TearDownTestCase为静态方法,并且它们的注释也很详细。在测试套件的第一个测试用例开始前,SetUpTestCase函数会被调用,而在测试套件中的最后一个测试用例运行结束后,TearDownTestCase函数会被调用。

4、测试用例层面的事件
    要实现单个测试用例的事件,我们需要同样需要继承testing::Test类,并实现它的protected virtual方法SetUp和TearDown。gtest在运行这个测试用例之前,会首先调用SetUp方法,然后在测试用例结束之后,调用TearDown方法。

5、总结
    通过gtest事件机制,我们可以让gtest在运行测试、测试套件、测试用例的前后分别运行指定的代码段。这一点很有用,比如在单元测试中,我们可以将初始化操作放入SetUp函数中,而资源回收等操作方在TearDown函数中实现,这样可以使得我们在测试用例中只需专注于测试即可。
 类似资料: