2016-01-13 154 views
2

通常在測試系統中,當我們編寫一個新的測試用例時,我們需要在某處註冊測試用例,以便調用它。如何在測試系統中自動註冊測試用例?

例如,在一個測試系統: TESTCASE(a,b){...}可以映射到void testcase_a_b() {...}和測試系統可以從主調用每個這些void testcase_a_b()void testcase_c_d()等並且因此運行所有的測試用例。

在可執行文件中自動註冊測試用例的方法是什麼?例如,在Google Test中(就像其他幾個測試框架一樣),如果我們調用RUN_ALL_TESTS()它會自動執行在可執行文件中以TEST(a,b)等開頭的所有聲明。

Google測試如何知道exe文件中是否存在TEST(a,b)?我想從(從高層次的設計角度)理解什麼是在C++中實現類似系統的簡單方法。像TEST(a,b)這樣的宏自動附加到有效的測試用例列表中,以便它可以從main運行而不用擔心單獨註冊。

回答

2

通常這是通過創建全局對象來完成的,它們在構建時調用註冊方法。這在C++中通常被認爲是「良好實踐」(參見https://isocpp.org/wiki/faq/ctors#static-init-order),所以在嘗試這樣的實現之前,您應該非常精通這些問題。

無論如何,這是googletest使用方法 - 在TEST預處理宏最終歸結爲(GTEST-internal.h):

// Helper macro for defining tests. 
#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ 
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ 
public:\ 
    GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ 
private:\ 
    virtual void TestBody();\ 
    static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\ 
    GTEST_DISALLOW_COPY_AND_ASSIGN_(\ 
     GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ 
};\ 
\ 
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ 
    ::test_info_ =\ 
    ::testing::internal::MakeAndRegisterTestInfo(\ 
     #test_case_name, #test_name, NULL, NULL, \ 
     (parent_id), \ 
     parent_class::SetUpTestCase, \ 
     parent_class::TearDownTestCase, \ 
     new ::testing::internal::TestFactoryImpl<\ 
      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ 
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() 

所以,當你使用這個宏,的全局實例這個類調用了::testing::internal::MakeAndRegisterTestInfo,其參數對應於測試用例。

+0

感謝您的回覆。 那麼根據你的設計一個不使用靜態初始化就能達到相同結果的系統的好方法呢? 或者,沒有其他辦法嗎? –

+0

如果你想在'main'被調用之前發生一些事情,你將不得不依靠靜態初始化。顯然Google選擇這樣實現它 - 我只是警告必須非常小心才能正確實現 - 因爲如C++ FAQ中所述,創建不穩定的實現將非常容易。 – MuertoExcobito

+0

您的幫助非常感謝:) 非常感謝。 –

相關問題