C++ 如何测试函数调用顺序

C++ 如何测试函数调用顺序,c++,unit-testing,tdd,C++,Unit Testing,Tdd,考虑到这些守则: class ToBeTested { public: void doForEach() { for (vector<Contained>::iterator it = m_contained.begin(); it != m_contained.end(); it++) { doOnce(*it); doTwice(*it); doTwice(*it); } } void doOnce(Conta

考虑到这些守则:

class ToBeTested {
public:
  void doForEach() {
    for (vector<Contained>::iterator it = m_contained.begin(); it != m_contained.end(); it++) {
       doOnce(*it);
       doTwice(*it);
       doTwice(*it);
    }
  }
  void doOnce(Contained & c) {
    // do something
  }
  void doTwice(Contained & c) {
    // do something
  }

  // other methods
private:
  vector<Contained> m_contained;
}
您建议如何测试这一点?有什么方法可以用CppUnit或GoogleTest框架实现这一点吗?也许其他的单元测试框架允许执行这样的测试

我理解,如果不从这些函数调用任何调试函数,这可能是不可能的,但至少可以在某些测试框架中自动完成。我不喜欢扫描跟踪日志并检查它们的正确性


UPD:我不仅要检查对象的状态,还要检查执行顺序,以避免在尽可能早的阶段出现性能问题(通常我想知道我的代码完全按照我的预期执行)。

一些模拟框架允许您设置有序的预期,这可以让你准确地说出你期望的函数调用顺序。例如,对于C#允许这样做


我不是C++程序员,所以我不知道C++有什么用,但这是一种工具,可以允许你尝试做什么。

< p>你可以检查一下。

你应该能够使用任何好的模拟框架来验证对协作对象的调用是按特定顺序完成的。 但是,您通常不会测试一个方法是否对同一类上的其他方法进行调用。。。你为什么要这么做

通常,当您测试一个类时,您只关心测试它的公共可见状态。如果你测试 除此之外,您的测试将阻止您以后重构

我可以提供更多帮助,但我认为您的示例并不一致(AddContained方法的实现在哪里?。

这是一篇关于上下文绑定对象的好文章。它包含了一些非常高级的东西,但是如果你不懒惰并且真的想了解这类东西,它将非常有用

最后,您将能够编写如下内容: [CallTracingAttribute()] 公共类TraceMe:ContextBoundObject
{…}

不要试图找出调用了多少函数,以及调用的顺序,而是找到一组输入,如果您按正确的顺序调用,这些输入只能生成预期的输出。

您可以使用ACE(或类似的)调试框架,在测试中,将调试对象配置为流到文件。然后您只需要检查文件。

如果您对性能感兴趣,我建议您编写一个测试来衡量性能

检查当前时间,运行您关心的方法,然后再次检查时间。断言所花费的总时间小于某个值

检查方法是否按特定顺序调用的问题在于,您的代码必须更改,并且您不希望在这种情况下必须更新测试。您应该专注于测试实际需求,而不是测试满足该需求的实现细节

也就是说,如果您真的想测试您的方法是否按特定顺序被调用,则需要执行以下操作:

  • 将它们移动到另一个类,称之为Collaborator
  • 将另一个类的实例添加到ToBeTested类
  • 使用模拟框架将ToBeTested上的实例变量设置为Collaborator类的模拟
  • 调用被测试的方法
  • 使用您的模拟框架断言方法是按照正确的顺序在模拟上调用的

  • 我不是母语为cpp的人,所以我无法评论您应该使用哪种模拟框架,但我看到其他一些评论者在这方面添加了他们的建议。

    “示例是一致的”-AddContained()属于“//other方法”:“公共可见状态”-不必要的调用可能不会影响对象的状态,但他们可以减慢执行速度。“…为什么?”-您的意思是测试函数的调用方吗?这也太好了。调用的顺序和数量可能不会影响内部状态,但只会导致将来执行缓慢。当然,这可以在以后的性能测试中进行测试,但这可能太晚而且很困难。我看不出将函数中的trace()调用到stdout或stderr,然后检查这些日志有什么主要区别。我想在每次构建之后自动执行这样的测试,例如与其他单元测试一起。谢谢你的回答。我觉得带反射的.NET可以提供帮助,但我使用普通cpp(有时甚至没有RTTI)感谢您提供了有用的答案。现在我知道我的方法是模仿框架。关于时间:首先,我不知道目标时间比较。第二:在早期阶段意外的执行顺序,可能会导致以后不正确的结果,并且会向模型中添加其他类,所以我为什么要等待?
    tobeTested.AddContained(one);
    tobeTested.AddContained(two);
    tobeTested.AddContained(three);
    
    BEGIN_PROC_TEST()
    SHOULD_BE_CALLED(doOnce, 1)
    SHOULD_BE_CALLED(doTwice, 2)
    SHOULD_BE_CALLED(doOnce, 1)
    SHOULD_BE_CALLED(doTwice, 2)
    SHOULD_BE_CALLED(doOnce, 1)
    SHOULD_BE_CALLED(doTwice, 2)
    
    tobeTested.doForEach()
    END_PROC_TEST()