C++单元测试(catch2)中SECTION是否同时运行?

问题描述 投票:0回答:1

我是 C++ 新手,正在学习使用 catch2 进行单元测试。我正在写一个这样的测试用例

TEST_CASE("Sandwich::AddTopping test", "[AddTopping]") {
  // your tests for Sandwich::AddTopping here
  Sandwich newsandwich;

  SECTION("adding two cheese") {
    newsandwich.AddTopping("cheese");
    REQUIRE(newsandwich.AddTopping("cheese") == false);
  }

  SECTION("adding more than 5 toppings") {
    newsandwich.AddTopping("cheese");
    newsandwich.AddTopping("lettuce");
    newsandwich.AddTopping("tomato");
    newsandwich.AddTopping("onions");
    newsandwich.AddTopping("pickles");
    REQUIRE(newsandwich.AddTopping("cheese") == false);
  }

  SECTION("adding 2 other toppings") {
    newsandwich.AddTopping("lettuce");
    REQUIRE(newsandwich.AddTopping("lettuce"));
  }

  SECTION("adding in range") { REQUIRE(newsandwich.AddTopping("lettuce")); }
}

但是,我的代码一开始只创建一个 Sandwich 对象,但其输出与我为每个 SECTION 单独创建对象时的输出相同。有人能告诉我为什么吗?谢谢你~

c++ unit-testing catch2
1个回答
0
投票

简短回答:
在顶部创建一个

Sandwich
与在每个部分中创建一个单独的实例相同,因为
SECTION
正是为了实现这一目标。
请参阅 catch2 文档中的 示例

更长的一个:
如果您有昂贵的测试设置,并且想要测试不同的东西,您可能希望统一创建,并且只关注测试本身。

这就是他们实现

SECTION
宏的原因 - 它将逐一测试每个部分,排除其他部分,但运行部分之外的所有内容与您拥有的部分一样多。

在您的示例中,当测试开始时:

  1. 它将通过运行
    Sandwich newsandwich;
    line
  2. 创建一个对象
  3. 然后运行第一部分
  4. 令人惊讶的是,它会从头开始“重新启动” - 再次在
    Sandwich newsandwich;
    行,因为它位于任何部分之外
  5. 它将跳过第一部分,只执行第二部分(“添加超过 5 个配料”)
  6. 再次“重新启动”使用
    Sandwich newsandwich;
  7. 创建一个新对象
  8. 跳过前面的所有部分,但执行第三部分
  9. 等等...

另外,我会检查我们是否可以至少添加一次奶酪

假设您的

Sandwich
类如下所示:

class Sandwich {
public:
    bool AddTopping(const std::string& type) {
        if(type == "cheese") {
            if(isCheesePresent)
                 return false;

            // add cheese
            isCheesePresent = true;
        }
        return true;
    };
private:
    bool isCheesePresent {false};
};

这将满足要求,即对于任何实例,只能添加一个

"cheese"
(说实话,它并没有做更多的事情)。

现在让我们看看你的测试用例 - 我修改了一点,请参阅评论

TEST_CASE("Sandwich::AddTopping test", "[AddTopping]") {
  // your tests for Sandwich::AddTopping here
  Sandwich newsandwich;

  SECTION("adding two cheese") {
    CHECK(newsandwich.AddTopping("cheese") == true);    // 1. added a check here
    REQUIRE(newsandwich.AddTopping("cheese") == false);
  }

  SECTION("adding more than 5 toppings") {
    CHECK(newsandwich.AddTopping("cheese") == true);    // 2. added a check here too
    newsandwich.AddTopping("lettuce");
    newsandwich.AddTopping("tomato");
    newsandwich.AddTopping("onions");
    newsandwich.AddTopping("pickles");
    REQUIRE(newsandwich.AddTopping("cheese") == false);
  }
  ...

让我们看看为什么这些很重要:

  1. 这个
    CHECK
    将确保我们至少可以添加一次
    "cheese"
    。没什么特别的,如果您在该部分内创建
    sandwich
    对象,效果是一样的。
  2. 这个更有趣!如果删除 SECTION(..) 文本,并运行上面的代码,在使用单个实例时它会失败。我们已经为
    newsandwich
    对象添加了奶酪(在 1. 检查时)。
    但是,如果您在该部分内创建对象,它就会通过。
© www.soinside.com 2019 - 2024. All rights reserved.