1. 程式人生 > >Google單元測試框架gtest之官方sample筆記4--事件監控之記憶體洩漏測試

Google單元測試框架gtest之官方sample筆記4--事件監控之記憶體洩漏測試

sample 10 使用event listener監控Water類的建立和銷燬。在Water類中,有一個靜態變數allocated建立一次值加一,銷燬一次值減一為了實現這個功能,過載了new和delete關鍵字,然後在new和delete函式中,做allocated的增減和記錄allocated變數的值。

class Water {
 public:
  // Normal Water declarations go here.
​
  // operator new and operator delete help us control water allocation.
  void* operator new(size_t allocation_size) {
    allocated_++;
    return malloc(allocation_size);
  }
​
  void operator delete(void* block, size_t /* allocation_size */) {
    allocated_--;
    free(block);
  }
​
  static int allocated() { return allocated_; }
​
 private:
  static int allocated_;
};
​
int Water::allocated_ = 0;

gtest的event listener能在TEST執行前和執行後呼叫,然後就可以判斷TEST執行完後是否發生洩漏。event listner是非入侵式檢測,不需要在TEST裡寫測試程式碼,而是在TEST之外執行特定的監控程式碼。

註冊event監聽的方法如下,在每個測試前執行OnTestStart,在測試後執行OnTestEnd。計算int difference = Water::allocated() - initially_allocated_;就可以得知是否發生記憶體洩漏,忘記了刪除new的物件。

class LeakChecker : public EmptyTestEventListener {
 private:
  // Called before a test starts.
  void OnTestStart(const TestInfo&  test_info ) override {
    initially_allocated_ = Water::allocated();
  }
​
  // Called after a test ends.
  void OnTestEnd(const TestInfo& /* test_info */) override {
    int difference = Water::allocated() - initially_allocated_;
​
    // You can generate a failure in any event handler except
    // OnTestPartResult. Just use an appropriate Google Test assertion to do
    // it.
    EXPECT_LE(difference, 0) << "Leaked " << difference << " unit(s) of Water!";
  }
​
  int initially_allocated_;
};
​
// 如果檢查洩漏,則註冊event listener監控
if (check_for_leaks) {
    TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
    listeners.Append(new LeakChecker);
}

測試程式碼如下,由於使用的是非入侵式檢測,所以TEST函式和普通的測試一樣。下面的DoesNotLeak測試無記憶體洩漏發生,而LeaksWater測試,會發生記憶體洩漏。

TEST(ListenersTest, DoesNotLeak) {
  Water* water = new Water;
  delete water;
}
​
// This should fail when the --check_for_leaks command line flag is specified.
TEST(ListenersTest, LeaksWater) {
  Water* water = new Water;
  EXPECT_TRUE(water != nullptr);
}

不啟用記憶體洩漏測試時的輸出結果:

使用記憶體洩漏測試時的輸出結果:

 

尊重技術文章,轉載請註明!

Google單元測試框架gtest之官方sample筆記4--事件監控之記憶體洩漏測試

https://www.cnblogs.com/pingwen/p/14482187.html