【问题标题】:Testing about deletion of a node in list [closed]测试删除列表中的节点[关闭]
【发布时间】:2018-07-03 10:46:54
【问题描述】:

我已经实现了一个双向循环列表,我确实想编写测试。

所以在这个列表中,有一个删除操作符,我想检查它是否正常工作。我持有一个节点的迭代器,然后我删除了这个节点,现在我想验证这个迭代器是否指向不再存在的东西。 我如何编写测试来验证这一点? 当我在网上搜索时,我发现了一些关于 boost 库和测试库的东西。 下面是我所说的一个最小示例。

#include<iostream>
struct Node{
    Node* back;
    Node* front;
    int data;
}Node;

int main(int argc, char* argv[])
{
    Node* a = new Node;
    Node* b = a;
    delete a;

    //HOW TO CHECK IF THE NODE THAT I ALLOCATED, HAVE BEEN DELETED?
}

【问题讨论】:

  • 听起来你可以继续使用你提到的网络搜索:) 另见here
  • 请展示实现,以便我们轻松创建与您的代码匹配的测试示例。否则这将只是一般性建议 - 没有真正的帮助,也不适合 SO。
  • @chaviarasmichalis 您不必提供实际代码,事实上,您不应该提供。您应该提供MCVE。就目前而言,这个问题是题外话,不管你认为它有多明显。
  • @chaviarasmichalis 另外,如果你编写“科学代码”,不管是什么,使用 C++ 中已经可用的列表的标准实现,并专注于域逻辑 - 你在浪费时间重新发明轮子。
  • @chaviarasmichalis 对,抱歉,我错过了列表必须是双向链接的。 boost.org/doc/libs/1_67_0/doc/html/intrusive/list.html 呢?如果我没记错的话,它只是标题。

标签: c++ unit-testing automated-tests


【解决方案1】:

通常访问无效的迭代器是未定义的行为,或者至少在使用标准库容器时是这样。

除非您的容器具有一些特定的附加功能来跟踪迭代器是否仍然有效,否则我建议使用不同的方法来确保节点已被删除,例如通过测试节点在删除之前和之后的原始情况节点现在相互指向而不是指向已删除的节点。

如果你想实际测试节点是否已被释放,并且包含它的内存没有泄漏,那么我个人会通过在 Valgrind 下运行整个测试套件来做到这一点。这将跟踪内存分配,并在您尝试越界访问内存、泄漏内存、尝试双重释放等时发出警告。

Valgrind 可以配置为生成 XML 输出,因此您可以让测试运行器在 Valgrind 下运行测试并自动解析输出以确保没有发生泄漏或其他违规行为。即使您找到了在没有 Valgrind 的情况下测试此特定案例的方法,始终确保您的测试套件在 Valgrind 下运行时不会产生错误,以捕捉您可能犯的任何其他错误.

【讨论】:

  • 如果我按照你建议的方法通过查看删除节点前后的方式进行测试,如何查看“删除”节点的内存是否泄露?
  • 我个人会通过在 Valgrind 下运行测试套件来测试它,它会告诉你是否发生了任何内存泄漏。
  • 我确实知道 valgrind,但我想要更自动化的东西来将它添加到我已经实现的单元测试中。
  • @chaviarasmichalis 为了避免内存泄漏,只需使用自动指针(unique_ptr 等)并停止关注低级细节。正如 Sean 所建议的那样,使用 Valgrind 来验证您没有内存泄漏,否则专注于您需要的域逻辑。
  • 非常感谢@BartoszKP 提供的所有信息。您对我很有帮助,我将阅读有关自动指针的信息。
【解决方案2】:

单元测试主要由三部分组成;安排、行动和断言。

  • 排列部分,您可以创建您的列表。
  • Act 部分使用删除运算符
  • Assert 部分,您将结果与预期值进行比较。

我最喜欢的 C++ 单元测试框架是Google Test,你可以找到一个非常好的框架教程here

【讨论】:

  • 我在断言阶段,这个问题提到了这个阶段。
【解决方案3】:

您可以在删除对象之前故意将其丢弃或标记,以便继续使用它们会很快出错。这并不是一个真正的测试工具,而是用于快速发现错误,而不是等待损坏最终导致崩溃。例如,您可以将对象归零。因此,在双向链表中,您不恰当地保留了引用的已删除对象中的前向/后向链接应该被丢弃。 (如果使用指针,则它可能为空。如果使用索引,您可能希望用 0xFF 填充对象)如果您真正释放了已删除的项目,那么它可能已被重用。但我想你可以在任何进一步的分配发生之前运行这个测试。对于调试,您可以选择是否将垃圾留在发布版本中。除非您的动态列表构建受到性能限制,否则我会将其保留。因此,它也可以用于测试。虽然我不确定我是否会一直推荐这种类型的测试。对我来说,创建一个项目列表并删除一个并检查它是否被删除就足够了。我也会添加泄漏测试,我会重复多次删除等任务,并希望内存不会泄漏。

【讨论】:

  • “对我来说,创建一个项目列表并删除一个并检查它是否被删除就足够了。”那你建议怎么做呢?
猜你喜欢
  • 1970-01-01
  • 2016-06-26
  • 2022-01-07
  • 2016-03-31
  • 1970-01-01
  • 2019-06-29
  • 1970-01-01
  • 2021-07-01
  • 1970-01-01
相关资源
最近更新 更多