2016-01-13 93 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

您的帮助非常感谢:) 非常感谢。 –

相关问题