考虑这样的代码:

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;
}

我想测试一下,如果我用3个值填充向量,我的函数将按正确的顺序和数量调用。 例如,我的测试看起来像这样:

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()

你怎么建议测试这个? 有没有办法用CppUnit或GoogleTest框架做到这一点? 也许其他一些单元测试框架允许执行此类测试?

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

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

===============>>#1 票数:1

你可以看看mockpp

===============>>#2 票数:1

您应该能够使用任何良好的模拟框架来验证对协作对象的调用是否按特定顺序完成。

但是,您通常不会测试一个方法是否在同一个类上调用其他方法...为什么?

通常,当您测试一个类时,您只关心测试其公开可见的状态。 如果您测试其他任何内容,您的测试将阻止您稍后重构。

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

===============>>#3 票数:1

而不是试图弄清楚调用了多少函数,以及以什么顺序查找,如果以正确的顺序调用事物,则找到一组只能产生预期输出的输入。

===============>>#4 票数:1 已采纳

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

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

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

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

  1. 将它们移动到另一个类,称之为Collaborator
  2. 将此其他类的实例添加到ToBeTested类
  3. 使用模拟框架将ToBeTested上的实例变量设置为Collborator类的模拟
  4. 调用测试中的方法
  5. 使用您的模拟框架断言以正确的顺序在模拟上调用方法。

我不是本地cpp发言人所以我不能评论你应该使用哪个模拟框架,但我看到其他一些评论者在这方面添加了他们的建议。

===============>>#5 票数:0

一些模拟框架允许您设置有序期望,这可以让您确切地说出您按特定顺序调用的函数。 例如, RhinoMocks for C#允许这样做。

我不是C ++编码器,所以我不知道C ++可以使用什么,但这是一种可能允许你尝试做的工具。

===============>>#6 票数:0

http://msdn.microsoft.com/en-au/magazine/cc301356.aspx

这是一篇关于Context Bound Objects的好文章。 它包含一些非常先进的东西,但是如果你不是懒惰而且真的想要了解这类东西它将会非常有用。

最后,您将能够编写如下内容:[CallTracingAttribute()] public class TraceMe:ContextBoundObject {...}

===============>>#7 票数:0

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

  ask by cos translate from so

未解决问题?本站智能推荐:

1回复

在设计调用外部API的类时,测试实现是否正确?

我开始使用一些原型代码: 现在我想在非常简单的类中重构这个代码提取功能(现在不试图使通用非常通用... YAGNI)。 这是我想到的那种界面: 例如, SocketServer类封装了用于创建新套接字服务器的所有样板: 然后,由于这需要调用系统API,我需要模拟它:
3回复

什么是测试和测试驱动开发的在线介绍? [关闭]

我正在寻找有关单元测试和TDD的在线介绍。 我几乎没有TDD,单元测试或任何其他敏捷方法的经验。 我的开发环境是Linux上的C ++。 如果对使用C ++作为示例语言的单元测试和TDD进行质量介绍,那就太棒了。 如果没有,那么任何旧语言的一般介绍和使用C ++的更高级教程就足够了。
4回复

测试引发失败的功能

测试引发故障的功能的最佳方法是什么? 还是测试一个完全可以避免故障的功能? 例如; 我有一个I/O Completion Port类,如果它不能正确初始化端口,则会抛出该构造函数。 这将使用初始化列表中的CreateIoCompletionPort的Win32函数。 如果未正确设置
7回复

C ++中的单元测试

我已经阅读了很多有关单元测试和测试驱动开发的知识。 最近,我还阅读了Java单元测试代码。 但是,我更喜欢在Qt中进行开发。 因此,我搜索了“ C ++中的单元测试”,并找到了大量有关C ++可用的各种单元测试框架的信息。 但是,我找不到各种框架的可靠比较。 因此,我希
1回复

免费功能和单元测试

我对以下功能的测试感兴趣: 节点的类型为boost :: variant,其中此变量包含类型Foo1,Foo2,Bar1和Bar2等。 免费功能findFooNode使用访问者模式来定位Foo节点(类型为Foo1或Foo2) 自由函数getCacheIdentifier也使用
5回复

当要测试的类很复杂时,如何编写单元测试?

我正在尝试使用TDD使用VS 2010在C ++中编写步步高游戏。 我已经设置了CxxTest来编写测试用例。 第一堂课是 我想为函数IsSingleMoveValid()编写一个测试,我猜测试应该证明函数正常工作。 不幸的是,有很多情况要测试,即使我测试了几个案例,有些可
1回复

无需硬件即可测试此功能的简单/创意方式

我想知道是否有人会知道没有实际硬件的简单方法来测试此功能。 麻烦的是我设置了两个寄存器,我想读回它们,以便可以验证代码是否正确。 寄存器功能都具有形式 在读写功能中,我已经做到了。 我也尝试过使用std :: stack,但是由于在第一个setregister中推送值后
1回复

如何编译和链接单元测试?

我最近开始尝试在我的一个C ++项目中使用TDD。 我对此非常陌生,而且我对编译和使用单元测试的方式有一些非常基本的问题。 我在Linux上使用Boost.Test库。 为所有单元编译包含所有测试套件的单个大型测试程序是否常见? 如何将测试分成许多较小的独立测试程序? 如
1回复

在工厂方法中测试对象的创建

目前我正在编写一个测试驱动的项目,并且我坚持测试以下行为。 我有一个名为Menu的界面,可以通过addEntry动态添加条目。 还有另一个包含Menu对象的类。 我们称之为MenuPresenter 。 当someAction(string title)特定方法(例如someActi
2回复

C ++单元测试本机C ++

首先,有一点背景: 在工作中,我继承了一个大型C ++程序(这种语言已经12年没有广泛使用了)。 为了帮助自己更好地理解该应用程序以及它如何组合在一起,我想:“我喜欢TDD,为什么不编写一些单元测试!”。 从那以后,我花了两天时间来编译一个简单的单元测试。 我现在到达链接器的位置,但