zoukankan      html  css  js  c++  java
  • Google C++单元测试框架(Gtest)系列教程之六——FAQ节选

    这一节,我们来看Gtest的FAQ(Frequently-Asked Questions)。


    为什么测试用例和测试实例命名中不应包含下划线

    在C++中,对于以下情况,相应的标识可能会被编译器或标准库使用:

    1. 以下划线开始并紧接一个大写字母的标识
    2. 包含连续两个下划线的标识

    为避免标识符冲突,用户代码中不应自定义以上两种情况的标识。使用TEST()或TEST_F()时,滥用下划线,将有可能产生标志符命名冲突。

    当我们定义以下测试实例并执行测试程序时,Gtest会为我们生成一个名为TestCaseName_TestName_Test的类。

    TEST(TestCaseName, TestName)

    如果TestCaseName或TestName中包含下划线,情况会怎样呢?

    • TestCaseName以"_"开头(例如_Foo),我们得到_Foo_TestName_Test
    • TestCaseName以"_"结尾(例如Foo_),我们得到Foo__TestName_Test
    • TestName以"_"开头(例如_bar),我们得到TestCaseName__bar_Test
    • TestName以"_"结尾(例如bar_),我们得到TestCaseName_bar__Test

    以上命名方式都有可能产生命名冲突,因而TestCaseName和TestName以“_"开头或结尾均不可取。

    如果TestCaseName或TestName命名中包含下划线,情况又会怎样呢?

    TEST(Time, Flies_Like_An_Arrow) { ... }
    TEST(Time_Flies, Like_An_Arrow) { ... }

    假设我们同时定义了两个测试实例,Oops! 这时Gtest将产生同一个类:Time_Flies_Like_An_Arrow。

    因而为避免命名冲突的情况发生(不管是与系统标志冲突或自定义的标志间冲突),我们的测试用例或测试实例的命名最好不包含下划线。当然,这是建议而不是必须的。

    在测试固件类中,为什么要用set-up/tear-down函数,而不使用构造函数/析构函数

    还记得测试固件的作用吗?通过测试固件,Gtest为每一个测试实例生成一个测试固件对象,该对象为每个测试实例提供独立的数据配置,通过编写SetUp()/TearDown()函数,我们可以对数据进行初始化和销毁操作。

    对于一个类而言,构造函数和析构函数不是同样有初始化数据/销毁数据的作用吗?Gtest提供SetUp()和TearDown()岂不是多此一举?No,no,no, 对于以下情况,还非得用SetUp()/TearDown()不可:

    对于销毁操作中包含异常抛出调用的,由于在C++的析构函数中不能抛出异常,这时候需使用TearDown()调用(关于C++析构函数抛出异常的介绍,请看这里)。

    为什么当我调用RUN_ALL_TESTS()函数时,编译器抛出"ignoring return value"警告

    一些Gtest使用者忽略了RUN_ALL_TESTS()的返回值,理应这样调用:

    return RUN_ALL_TESTS();

    而不是这样:

    RUN_ALL_TESTS();

    测试程序根据RUN_ALL_TESTS()的返回值判断其所包含的测试实例是否通过。如果在main()函数中忽略其返回值,即使是某个测试实例检测失败,整个测试程序也会被认为是无检测失败地成功执行。

    为避免误用RUN_ALL_TESTS(),对于不作为main()返回值的调用,gcc将对此抛出警告,为消除该警告,将RUN_ALL_TESTS()作为main()函数的返回值即可。

    如何为一个测试固件定义多个测试用例

    我想编写多个测试实例,它们对应于同一个测试固件,对此,是否要为每一个测试实例编写新的测试固件类?就像这样:

    class FooTest : public BaseTest {};

    TEST_F(FooTest, Abc) { ... }
    TEST_F(FooTest, Def) { ... }

    class BarTest : public BaseTest {};

    TEST_F(BarTest, Abc) { ... }
    TEST_F(BarTest, Def) { ... }

    这里类FooTest和类BarTest什么都不做,我们这样定义只是为了产生两个不同的测试用例名。

    其实使用typedef能更便捷地达到目的:

    typedef BaseTest FooTest;

    TEST_F(FooTest, Abc) { ... }
    TEST_F(FooTest, Def) { ... }

    typedef BaseTest BarTest;

    TEST_F(BarTest, Abc) { ... }
    TEST_F(BarTest, Def) { ... }


    关于Gtest的更多FAQ,请参看这里

  • 相关阅读:
    扫面线模板
    (动态规划、栈)leetcode 84. Largest Rectangle in Histogram, 85. Maximal Rectangle
    tmux 常见命令汇总
    leetcode 221
    leetcode 319 29
    (贪心)leetcode 392. Is Subsequence, 771. Jewels and Stones, 463. Island Perimeter
    leetcode 982 668
    Python import 同文件夹下的py文件的函数,pycharm报错
    Windows里Anaconda-Navigator无法打开的解决方案
    Windows下 gpu版 Tensorflow 安装
  • 原文地址:https://www.cnblogs.com/bangerlee/p/2218392.html
Copyright © 2011-2022 走看看