当前位置: 首页 > news >正文

做网站空深圳创业补贴2024

做网站空,深圳创业补贴2024,360网站提交收录入口,wordpress 标题关键词TDD#xff0c;测试驱动开发#xff0c;英文全称Test-Driven Development#xff0c;简称TDD#xff0c;是一种不同于传统软件开发流程的新型的开发方法。它要求在编写某个功能的代码之前先编写测试代码#xff0c;然后只编写使测试通过的功能代码#xff0c;通过测试来推…TDD测试驱动开发英文全称Test-Driven Development简称TDD是一种不同于传统软件开发流程的新型的开发方法。它要求在编写某个功能的代码之前先编写测试代码然后只编写使测试通过的功能代码通过测试来推动整个开发的进行。这有助于编写简洁可用和高质量的代码并加速开发过程。 简言之TDD是通过设计 Test 来完成软件设计的一种高效可行的软件开发模式。 为何更丰富地达成测试的目的googletes是绕不过去的本文备忘主要关注 googletest 主体的分析过程和结论即googleTest框架中是如何通过相关的测试宏的实现测试的目的。 TEST TEST_F TEST_P 等等 1googleTest 环境与简单示例 1.1 下载 googletest 并编译 下载 $ git clone https://github.com/google/googletest.git $ git checkout release-1.10.0 编译 $ mkdir build $ cd build/ $ export CXXFLAGS-Wno-errormaybe-uninitialized $ cmake .. $ make -j $ ls lib/ 默认为 release若debug版本则须 $ cmake .. -DCMAKE_BUILD_TYPEDebug 成果 1.2 示例1 验证函数 add 源码 #include iostream #include gtest/gtest.hint add_int_int(int a, int b){return ab; }TEST(SumFuncTest, twoNumbers){EXPECT_EQ(add_int_int(3,4),7);EXPECT_EQ(27, add_int_int(9, 18)); }GTEST_API_ int main(int argc, char** argv) {printf(Running main() from %s\n, __FILE__);testing::InitGoogleTest(argc, argv);return RUN_ALL_TESTS(); } 运行 1.3 示例 2 #include gtest/gtest.hint Foo(int a, int b) {if (a 0 || b 0){throw dont do that;}int c a % b;if (c 0)return b;return Foo(b, c); }TEST(FooTest, HandleNoneZeroInput) {EXPECT_EQ(2, Foo(4, 10));EXPECT_EQ(6, Foo(30, 18)); }g foo.cpp -I ../../googletest/googletest/include -L ../../googletest/build_dbg/lib -lgtest -lgtest_main 编译运行 1.4 示例3 源码 #include iostream #include gtest/gtest.h// add_util.ccfloat add_from_left(float a, float b, float c, float d, float e) {float sum 0.0;sum c;sum a;sum b;//sum c;sum d;sum e; /*sum a;sum b;sum c;sum d;sum e; */printf(add_from_left: sum %f\n, sum);return sum; }float add_from_right(float a, float b, float c, float d, float e) {float sum 0.0;sum e;sum d;sum c;sum b;sum a;printf(add_from_right: sum %f\n, sum);return sum; }int sum(int a, int b){return ab; }TEST(AddFuncTest, floatVSfloat) {printf(AddFuncTest: float sum %f\n, 1.238f 3.7f 0.000353265f 7898.3f 12.23209f);printf(AddFuncTest: double sum %f\n, 12.23209 7898.3 0.000353265 3.7 1.238);EXPECT_EQ(1.238f 3.7f 0.000353265f 7898.3f 12.23209f, add_from_left(1.238, 3.7, 0.000353265, 7898.3, 12.23209));EXPECT_EQ(1.238f 3.7f 0.000353265f 7898.3f 12.23209f, add_from_right(1.238, 3.7, 0.000353265, 7898.3, 12.23209)); // }TEST(AddFuncTest, doubleVSfloat) {printf(AddFuncTest: float sum %f\n, 1.238f 3.7f 0.000353265f 7898.3f 12.23209f);printf(AddFuncTest: double sum %f\n, 12.23209 7898.3 0.000353265 3.7 1.238);EXPECT_EQ(1.238f 3.7f 0.000353265f 7898.3f 12.23209f, add_from_left(1.238, 3.7, 0.000353265, 7898.3, 12.23209));EXPECT_EQ(1.238 3.7 0.000353265 7898.3 12.23209, add_from_right(1.238, 3.7, 0.000353265, 7898.3, 12.23209)); // }TEST(SumFuncTest, twoNumbers){EXPECT_EQ(sum(3,4),7);EXPECT_EQ(27, sum(9, 18)); }GTEST_API_ int main(int argc, char** argv) {printf(Running main() from %s\n, __FILE__);testing::InitGoogleTest(argc, argv);return RUN_ALL_TESTS(); } Makefile EXE : hello_gtest_ex hello_gtest_add_int_int all: $(EXE)%: %.cppg -O0 -fno-toplevel-reorder $ -o $ $(INC) $(LD_FLAGS)INC : -I../googletest/googletest/include/ LD_FLAGS : -L../googletest/build/lib/ -lgtest -lgtest_main.PHONY: clean clean:-rm -rf $(EXE) 2示例与源码分析 使用最简单的测试示例聚焦googletest本身的代码逻辑 观察点main 函数如何调用到 TEST(...){...} 这种结构中的代码 两种方式互相印证 方式1通过编译器的预编译指令 g -E ... 生成展开代码; 方式2通过跟踪源代码来份些TEST等的展开结果 2.1 TEST 示例代码如上 simple_gtest.cpp #include gtest/gtest.hint add_int_int(int a, int b){return ab; }TEST(SumFuncTest, twoNumbers){EXPECT_EQ(add_int_int(3,4),7); } 方式1: g -E simple_gtest.cpp -o simple_gtest.i 展开后simple_gtest.i文件有8W多行但是其中对我们理解有意义的也就最尾巴上的几行 int add_int_int(int a, int b){return ab; }static_assert(sizeof(SumFuncTest) 1, test_suite_name must not be empty); static_assert(sizeof(twoNumbers) 1, test_name must not be empty); class SumFuncTest_twoNumbers_Test : public ::testing::Test { public: SumFuncTest_twoNumbers_Test() {} private:virtual void TestBody(); static ::testing::TestInfo* const test_info_ __attribute__ ((unused)); SumFuncTest_twoNumbers_Test(SumFuncTest_twoNumbers_Test const ) delete; void operator(SumFuncTest_twoNumbers_Test const ) delete; }; ::testing::TestInfo* const SumFuncTest_twoNumbers_Test::test_info_ ::testing::internal::MakeAndRegisterTestInfo( SumFuncTest, twoNumbers, nullptr, nullptr, ::testing::internal::CodeLocation(simple_gtest.cpp, 8), (::testing::internal::GetTestTypeId()), ::testing::internal::SuiteApiResolver ::testing::Test::GetSetUpCaseOrSuite(simple_gtest.cpp, 8), ::testing::internal::SuiteApiResolver ::testing::Test::GetTearDownCaseOrSuite(simple_gtest.cpp, 8), new ::testing::internal::TestFactoryImplSumFuncTest_twoNumbers_Test); void SumFuncTest_twoNumbers_Test::TestBody() {switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar (::testing::internal::EqHelper::Compare(add_int_int(3,4), 7, add_int_int(3,4), 7))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure, simple_gtest.cpp, 9, gtest_ar.failure_message()) ::testing::Message(); } 分析这段代码会发现 TEST被展开成为了一个 class SumFuncTest_twoNumbers_Test 它有一个成员函数 TestBody(){....} 观察上述代码中最后一个函数体void SumFuncTest_twoNumbers_Test::TestBody() 其中出现了被测试的函数等。 这说明这个函数体中的代码才是是被测试内容而其外围都是框架。 框架部分只需要把这中类的一个实例添加到某个链表中然后依次迭代执行每个类的 TestBody成员函数既可以完成测试任务。 本例中的 class 如下 通过方法2.来验证一下展开的结果 第一部分class 宏 关联TEST宏我们可以找到如下内容 #define TEST(test_suite_name, test_name) GTEST_TEST(test_suite_name, test_name)#define GTEST_TEST(test_suite_name, test_name) \GTEST_TEST_(test_suite_name, test_name, ::testing::Test, \::testing::internal::GetTestTypeId())// Expands to the name of the class that implements the given test. #define GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \test_suite_name##_##test_name##_Test// Helper macro for defining tests. #define GTEST_TEST_(test_suite_name, test_name, parent_class, parent_id) \static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) 1, \test_suite_name must not be empty); \static_assert(sizeof(GTEST_STRINGIFY_(test_name)) 1, \test_name must not be empty); \class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \: public parent_class { \public: \GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() default; \~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override default; \GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \(const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) ) delete; \GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) operator( \const GTEST_TEST_CLASS_NAME_(test_suite_name, \test_name) ) delete; /* NOLINT */ \GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \(GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) ) noexcept delete; \GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) operator( \GTEST_TEST_CLASS_NAME_(test_suite_name, \test_name) ) noexcept delete; /* NOLINT */ \\private: \void TestBody() override; \static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \}; \\::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \test_name)::test_info_ \::testing::internal::MakeAndRegisterTestInfo( \#test_suite_name, #test_name, nullptr, nullptr, \::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id), \::testing::internal::SuiteApiResolver \parent_class::GetSetUpCaseOrSuite(__FILE__, __LINE__), \::testing::internal::SuiteApiResolver \parent_class::GetTearDownCaseOrSuite(__FILE__, __LINE__), \new ::testing::internal::TestFactoryImplGTEST_TEST_CLASS_NAME_( \test_suite_name, test_name)); \void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody() 其中的如下两行 class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ : public parent_class { \ TEST 的宏充分展开后会根据TEST(X,Y) 括号中的X、Y字串定义一个完整的类并且包含成员函数:   TestBody() 但是展开的内容中没有这个函数的函数体。 这个函数体正好就是TEST(X,Y){Z} 中{Z}的这个部分即     TestBody(){Z} 只需要在整个测试系统中讲上面展开生成的class的一个实例insert进一个链表中并依次迭代执行链表的每一对象的成员函数 TestBody(){Z}即可达到测试目的。 第二部分函数体中的宏 关于 EXPECT_EQ我们会发现如下定义 #define EXPECT_EQ(val1, val2) \EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2) 而其中的 EXPECT_PRED_FORMAT2 又被展开为如下 // Binary predicate assertion macros. #define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) 又 GTEST_PRED_FORMAT2_ 被定义为 #define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure) \GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure) 而且其中的 GTEST_ASSERT_  被展开为 #define GTEST_ASSERT_(expression, on_failure) \GTEST_AMBIGUOUS_ELSE_BLOCKER_ \if (const ::testing::AssertionResult gtest_ar (expression)) \; \else \on_failure(gtest_ar.failure_message()) 其中 GTEST_AMBIGUOUS_ELSE_BLOCKER_ 展开为 #define GTEST_AMBIGUOUS_ELSE_BLOCKER_ \switch (0) \case 0: \default: // NOLINT 于是得到函数体为 总之只需要调用这个 TestBody() 函数即可完成测试任务。 2.2 TEST_F 2.2.1 小示例编译与运行 保持关于 TEST 宏分析的记忆我们以一个简单的示例来分析 TEST_F 宏 #include gtest/gtest.hclass SampleTestWithFixture : public ::testing::Test { protected:void SetUp() override {a_ 1;b_ 2;}int a_;int b_; };TEST_F(SampleTestWithFixture, Case2) {a_ 3;EXPECT_EQ(a_ b_, 5); }Makefile: EXE : hello_gtest_f all: $(EXE)%: %.cppg -g -fno-toplevel-reorder $ -o $ $(INC) $(LD_FLAGS)# g -E hello_gtest_f.cpp -I ../googletest/googletest/include/ -o hello_gtest_f.i #g -g -fno-toplevel-reorder $ -o $ $(INC) $(LD_FLAGS)INC : -I../../googletest/googletest/include/ LD_FLAGS : -L../../googletest/build_dbg/lib/ -lgtest -lgtest_main.PHONY: clean clean:-rm -rf $(EXE) 编译确保能够正确运行 $ make $ ./hello_gtest_f 2.2.2 TEST_F 宏展开分析 $ g -E hello_gtest_f.cpp -I ../googletest/googletest/include/ -o hello_gtest_f.i 生成的预处理后的文件 hello_gtest_f.i 主要内容还是在文件的尾巴上摘录调整格式如下 class SampleTestWithFixture : public ::testing::Test { protected:void SetUp() override {a_ 1;b_ 2;}int a_;int b_; };static_assert(sizeof(SampleTestWithFixture) 1, test_suite_name must not be empty); static_assert(sizeof(Case2) 1, test_name must not be empty);class SampleTestWithFixture_Case2_Test : public SampleTestWithFixture{ public:SampleTestWithFixture_Case2_Test() default;~SampleTestWithFixture_Case2_Test() override default;SampleTestWithFixture_Case2_Test(const SampleTestWithFixture_Case2_Test) delete;SampleTestWithFixture_Case2_Test operator( const SampleTestWithFixture_Case2_Test) delete;SampleTestWithFixture_Case2_Test(SampleTestWithFixture_Case2_Test ) noexcept delete;SampleTestWithFixture_Case2_Test operator(SampleTestWithFixture_Case2_Test ) noexcept delete;private: void TestBody() override;static ::testing::TestInfo* const test_info_ __attribute__((unused)); };::testing::TestInfo* const SampleTestWithFixture_Case2_Test::test_info_::testing::internal::MakeAndRegisterTestInfo(SampleTestWithFixture,Case2,nullptr,nullptr,::testing::internal::CodeLocation(hello_gtest_f.cpp, 27),(::testing::internal::GetTypeIdSampleTestWithFixture()),::testing::internal::SuiteApiResolver SampleTestWithFixture::GetSetUpCaseOrSuite(hello_gtest_f.cpp, 27),::testing::internal::SuiteApiResolver SampleTestWithFixture::GetTearDownCaseOrSuite(hello_gtest_f.cpp, 27),new ::testing::internal::TestFactoryImplSampleTestWithFixture_Case2_Test);void SampleTestWithFixture_Case2_Test::TestBody() {a_ 3;switch (0)case 0:default:if (const ::testing::AssertionResult gtest_ar (::testing::internal::EqHelper::Compare( a_ b_ , 5 , a_ b_ , 5 )));else::testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure, hello_gtest_f.cpp, 29, gtest_ar.failure_message()) ::testing::Message(); } 跟 TEST 宏的展开类似组合 TEST_F(X,Y) 的两个参数构成一个新的类 class X_Y_Test :public SampleTestWithFixture{ ... ... TestBody() } 宏展开的新类中也有一个成员函数 TestBody() 其中 SampleTestWithFixture 是自己定义的类会被 X_Y_Test 类共有继承走。 而 TEST_F(...){body} 的类似函数体的部分 {body}也同样被安排成为了 TestBody函数的函数体。 接下来gtest框架会通过成员 X_Y_Test::test_info_ 的静态赋值过程将本测试用例挂进系统的代运行链表届时依次迭代 调用 X_Y_Test::TestBody(); 实现测试感兴趣代码的目的。 2.2.3 总结 TEST_F TEST_F的意图 TEST_F的目的是为了把关系密切的测试问题汇总到一个class中来进行测试可以共用同一个类的对象的上下文成员数据。 TEST_F 中成员函数的执行顺序 那么成员函数 Setup( ) 在什么时候执行呢 先说答案 1      X_Y_Test() 构造函数//c 语法 2      Setup();                      //数据预备资源申请 3      TestBody();                //测试部分 4      TearDown();               //资源释放 5      X_Y_Test() 析构函数//c 语法 改造刚才的示例 #include gtest/gtest.hclass SampleTestWithFixture : public ::testing::Test { public: SampleTestWithFixture(){std::coutconstruct_STWFstd::endl;} ~SampleTestWithFixture(){std::coutdestruct_STWFstd::endl;} protected:void SetUp() override {std::cout Hello setupupup()000std::endl;a_ 1;b_ 2;std::cout Hello setupupup()111std::endl;}void TearDown() override {std::cout Hello teardownnn()000std::endl;a_ 4;b_ 5;std::cout Hello teardownnn()111std::endl;}int a_;int b_; };TEST_F(SampleTestWithFixture, Case2) {std::cout test_f Casess222std::endl;a_ 3;EXPECT_EQ(a_ b_, 5); } 编译运行 TEST_F函数体中的部分的一些宏跟TEST中的一样展开成为一些比较语句。 2.3 TEST_P 2.3.1 可运行示例 #include gtest/gtest.hnamespace TTT { namespace testing { int g_env_switch 0;class BasicTestFixture : public ::testing::TestWithParamint { public:BasicTestFixture() {}void SetUp(){g_env_switch GetParam();std::coutBTF_SetUp() gesg_env_switchstd::endl;}void TearDown(){} };#define OK 0 #define FAIL 1int envCheckFunc(void) {if(g_env_switch 0) {return OK;}else {return FAIL;} }TEST_P(BasicTestFixture, BasicTest) {ASSERT_EQ(envCheckFunc(), OK); }INSTANTIATE_TEST_SUITE_P(configSwitch, BasicTestFixture, ::testing::Values(1, 0)); //INSTANTIATE_TEST_SUITE_P(failSwitch, BasicTestFixture, ::testing::Values(2, 3));} } Makefile EXE : hello_gtest_pall: $(EXE)%: %.cppg -g -fno-toplevel-reorder $ -o $ $(INC) $(LD_FLAGS)# g -E hello_gtest_p.cpp -I ../googletest/googletest/include/ -o hello_gtest_p.i #g -g -fno-toplevel-reorder $ -o $ $(INC) $(LD_FLAGS)INC : -I../../googletest/googletest/include/ LD_FLAGS : -L../../googletest/build_dbg/lib/ -lgtest -lgtest_main.PHONY: clean clean:-rm -rf $(EXE) 编译执行 因为故意藏了一个逻辑错误所以第二个参数时会测试失败 2.3.2 无实例化宏的预编译 注释掉程序中的所有 INSTANTIATE_TEST_SUITE_P 的行不厌其烦地再贴一次 #include gtest/gtest.hnamespace TTT { namespace testing { int g_env_switch 0;class BasicTestFixture : public ::testing::TestWithParamint { public:BasicTestFixture() {}void SetUp(){g_env_switch GetParam();std::coutBTF_SetUp() gesg_env_switchstd::endl;}void TearDown(){} };#define OK 0 #define FAIL 1int envCheckFunc(void) {if(g_env_switch 0) {return OK;}else {return FAIL;} }TEST_P(BasicTestFixture, BasicTest) {ASSERT_EQ(envCheckFunc(), OK); }//INSTANTIATE_TEST_SUITE_P(configSwitch, BasicTestFixture, ::testing::Values(1, 0)); //INSTANTIATE_TEST_SUITE_P(failSwitch, BasicTestFixture, ::testing::Values(2, 3));} }g -E hello_gtest_p.cpp -I ../googletest/googletest/include/ -o hello_gtest_p.i 这时候预编译后生成的代码如下 namespace TTT { namespace testing { int g_env_switch 0;class BasicTestFixture : public ::testing::TestWithParamint { public:BasicTestFixture() {}void SetUp(){g_env_switch GetParam();std::coutBTF_SetUp() gesg_env_switchstd::endl;}void TearDown(){} };int envCheckFunc(void) {if(g_env_switch 0) {return 0;}else {return 1;} }class BasicTestFixture_BasicTest_Test : public BasicTestFixture, private ::testing::internal::GTestNonCopyable { public:BasicTestFixture_BasicTest_Test() {}void TestBody() override; private:static int AddToRegistry(){::testing::UnitTest::GetInstance()-parameterized_test_registry().GetTestSuitePatternHolderBasicTestFixture( BasicTestFixture, ::testing::internal::CodeLocation(hello_gtest_p.cpp, 35))-AddTestPattern( BasicTestFixture,BasicTest,new ::testing::internal::TestMetaFactoryBasicTestFixture_BasicTest_Test(),::testing::internal::CodeLocation(hello_gtest_p.cpp, 35));return 0;}static int gtest_registering_dummy_ __attribute__((unused)); };int BasicTestFixture_BasicTest_Test::gtest_registering_dummy_ BasicTestFixture_BasicTest_Test::AddToRegistry();void BasicTestFixture_BasicTest_Test::TestBody() {switch (0)case 0:default:if (const ::testing::AssertionResult gtest_ar (::testing::internal::EqHelper::Compare(envCheckFunc(), 0, envCheckFunc(), 0)));elsereturn ::testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure, hello_gtest_p.cpp, 37, gtest_ar.failure_message()) ::testing::Message(); } 没有实例化宏 的代码展开到被测试类的 TestBody()函数后就停止了如上代码中最后一个函数的定义。 2.3.3 有实例化宏的预编译 多了这两句 INSTANTIATE_TEST_SUITE_P(configSwitch, BasicTestFixture, ::testing::Values(1, 0)); INSTANTIATE_TEST_SUITE_P(failSwitch, BasicTestFixture, ::testing::Values(2, 3)); namespace TTT { namespace testing { int g_env_switch 0;class BasicTestFixture : public ::testing::TestWithParamint { public:BasicTestFixture() {}void SetUp(){g_env_switch GetParam();std::coutBTF_SetUp() gesg_env_switchstd::endl;}void TearDown(){} };int envCheckFunc(void) {if(g_env_switch 0) {return 0;}else {return 1;} }class BasicTestFixture_BasicTest_Test : public BasicTestFixture, private ::testing::internal::GTestNonCopyable { public:BasicTestFixture_BasicTest_Test() {}void TestBody() override;private:static int AddToRegistry(){::testing::UnitTest::GetInstance()-parameterized_test_registry().GetTestSuitePatternHolderBasicTestFixture( BasicTestFixture, ::testing::internal::CodeLocation(hello_gtest_p.cpp, 35))-AddTestPattern( BasicTestFixture,BasicTest,new ::testing::internal::TestMetaFactoryBasicTestFixture_BasicTest_Test(),::testing::internal::CodeLocation(hello_gtest_p.cpp,35));return 0;}static int gtest_registering_dummy_ __attribute__((unused)); };int BasicTestFixture_BasicTest_Test::gtest_registering_dummy_ BasicTestFixture_BasicTest_Test::AddToRegistry(); void BasicTestFixture_BasicTest_Test::TestBody() {switch (0)case 0:default:if (const ::testing::AssertionResult gtest_ar (::testing::internal::EqHelper::Compare( envCheckFunc(), 0, envCheckFunc(), 0)));elsereturn ::testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure, hello_gtest_p.cpp, 37, gtest_ar.failure_message()) ::testing::Message(); } //TEST_P(X, Y, ...){} // 跟 TEST_F的展开比较接近同样是将 TEST_P(){...} 的{...} 部分作为TestBody的函数体 // 但一个重要不懂的地方在于TEST_P 展开为被测试模式或模版真正注册近被执行队列是INSTANTIATE_TEST_SUITE_P的工作。//INSTANTIATE_TEST_SUITE_P(X, Y, ...)的展开位三个函数 //参数容器函数gtest_XY_EvaluGenerator_ 测试参数值 //被测试类函数gtest_XY_EvalGenerateName_ 测试参数类型 //测试类压栈函数gtest_XY_dummy_ 将测试类实例化后 push进带测试队列中通过调用 AddTestSuiteInstantiation//展开INSTANTIATE_TEST_SUITE_P(configSwitch, BasicTestFixture, ::testing::Values(1, 0));static ::testing::internal::ParamGeneratorBasicTestFixture::ParamType gtest_configSwitchBasicTestFixture_EvalGenerator_() {return::testing::Values(1, 0); }static ::std::string gtest_configSwitchBasicTestFixture_EvalGenerateName_( const ::testing::TestParamInfoBasicTestFixture::ParamType info) {if (::testing::internal::AlwaysFalse()) {::testing::internal::TestNotEmpty(::testing::internal::DefaultParamNameBasicTestFixture::ParamType);auto t std::make_tuple(::testing::Values(1, 0));static_assert(std::tuple_sizedecltype(t)::value 2, Too Many Args!);}return ((::testing::internal::DefaultParamNameBasicTestFixture::ParamType))(info); }static int gtest_configSwitchBasicTestFixture_dummy_ __attribute__((unused)) ::testing::UnitTest::GetInstance()-parameterized_test_registry().GetTestSuitePatternHolderBasicTestFixture(BasicTestFixture, ::testing::internal::CodeLocation(hello_gtest_p.cpp, 40))-AddTestSuiteInstantiation(configSwitch,gtest_configSwitchBasicTestFixture_EvalGenerator_,gtest_configSwitchBasicTestFixture_EvalGenerateName_,hello_gtest_p.cpp,40);//展开INSTANTIATE_TEST_SUITE_P(failSwitch, BasicTestFixture, ::testing::Values(2, 3));static ::testing::internal::ParamGeneratorBasicTestFixture::ParamType gtest_failSwitchBasicTestFixture_EvalGenerator_() {return::testing::Values(2, 3); }static ::std::string gtest_failSwitchBasicTestFixture_EvalGenerateName_( const ::testing::TestParamInfoBasicTestFixture::ParamType info) {if (::testing::internal::AlwaysFalse()) {::testing::internal::TestNotEmpty(::testing::internal::DefaultParamNameBasicTestFixture::ParamType);auto t std::make_tuple(::testing::Values(2, 3));static_assert(std::tuple_sizedecltype(t)::value 2, Too Many Args!);}return ((::testing::internal::DefaultParamNameBasicTestFixture::ParamType))(info); }static int gtest_failSwitchBasicTestFixture_dummy_ __attribute__((unused)) ::testing::UnitTest::GetInstance()-parameterized_test_registry().GetTestSuitePatternHolderBasicTestFixture(BasicTestFixture, ::testing::internal::CodeLocation(hello_gtest_p.cpp, 41))-AddTestSuiteInstantiation(failSwitch,gtest_failSwitchBasicTestFixture_EvalGenerator_,gtest_failSwitchBasicTestFixture_EvalGenerateName_,hello_gtest_p.cpp,41);} }2.3.4 分析 TEST_P 和 TEST_P(X, Y, ...){...}的展开 跟 TEST_F的展开比较接近继承用户自定义类后定义一个新类含有成员函数 TestBody同样是将 TEST_P(){...} 的{...} 部分作为TestBody的函数体 但一个重要不同的地方在于TEST_P 展开为被测试模式或模版真正注册近被执行队列是INSTANTIATE_TEST_SUITE_P的工作。 INSTANTIATE_TEST_SUITE_P(X, Y, ...)的展开位三个函数 1参数容器函数gtest_XY_EvaluGenerator_ 测试参数值 2被测试类函数gtest_XY_EvalGenerateName_ 测试参数类型 3测试类压栈函数gtest_XY_dummy_ 将测试类实例化后 push进带测试队列中通过调用 AddTestSuiteInstantiation压栈入队等待main函数依次迭代调用各个类实例的 TestBody()成员函数完成测试任务。 而其中的SetUp(), TearDown()等成员函数的调用跟TEST_F的调用时机相同。 3. 总结 掌握 googletest的使用 首先需要理解TESTXXX(){...}结构中{...}会被展开为一个类的成员函数 TestBody(){...} 的函数体。 其次掌握Setup,TearDown的调用时机 然后对各种判别宏有一定掌握比如 EXPECT_EQ 最后掌握 TEST_P de 参数的各种形式的使用方式
http://www.hkea.cn/news/14360790/

相关文章:

  • 海南省建设网站的公司电话号码网站建设论文的前言
  • 南山做网站行业成都兴光华城市建设公司网站
  • 风云榜小说排行榜网站代码优化调整
  • 雅联网站建设公众号开发费用
  • 论文收录网站wordpress文章类模板下载
  • 网站界面切片做程序六安城市网地址在哪里
  • cc域名的网站火车头采集器 wordpress论坛发布
  • 做编程的网站有哪些内容wordpress 建站教程 下载
  • 建设网站的相关技术平台网站建设费用
  • 幸福人寿保险公司官方网站电子保单打印博客seo怎么做
  • 网站建设销售技巧舵落口网站建设
  • 做网站的公司苏州有哪些网站免费做推广
  • ppt做的好的网站有哪些内容phpcms 安装官网的教程更换域名后网站图片还是无法显示
  • 深圳市龙岗区做网站的公司网站绑定别名好吗
  • 备案号 查询 网站老公做网站网站推广
  • 备案博客域名做视频网站会怎么样wap网站开发
  • 广州网站建设开发公司爱空间家装怎么样?两点告诉你
  • 怎样用西瓜影音做网站phpcms网站打开空白
  • 东莞建设工程交易中心网站wordpress登录密码忘记了
  • 什么是网站可信认证桂林做网站
  • 做网赌网站得多少钱首次登录 e账户客户登录
  • 做外贸外文网站怎么做好网站开发四点注意事项
  • 静态网站html成都新站软件快速排名
  • 网络营销企业网站中国购物平台排名
  • 怎么通过微博做网站外链医院网站建设联系方式
  • 大连网站建设制作公司wordpress 数据库
  • 网站空间带宽廊坊seo排名公司
  • 知道抖音视频是怎么做的网站嘛网站死链怎么产生的
  • 外卖网站的建设与推广网站设计开发软件网页美化工具
  • 灰蓝 网站模板做网站是怎么赚钱吗