Google單元測試框架gtest之官方sample筆記4–事件監控之內存泄漏測試
sample 10 使用event listener監控Water類的創建和銷毀。在Water類中,有一個靜態變量allocated,創建一次值加一,銷毀一次值減一。為了實現這個功能,重載了new和delete關鍵字,然後在new和delete函數中,
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–事件監控之內存泄漏測試