- 这个问题与单元测试框架无关。
- 这个问题与编写单元测试无关。
- 这个问题是关于在哪里放置UT代码以及如何/何时/在哪里编译和运行它。
在有效地使用旧版代码中,迈克尔·费瑟斯断言
良好的单元测试...运行速度快
然后
运行1/10秒的单元测试是缓慢的单元测试。
我认为这些定义确实有意义。我还认为,这意味着您必须分别保留一组单元测试和一组代码测试,这些测试需要更长的时间,但是我想这就是您仅在运行(非常快)时才调用单元测试的价格。
显然,问题在C ++中是“跑”单元测试(小号),你必须:
- 编辑代码(生产或单元测试,具体取决于您所在的“周期”)
- 编译
- 链接
- 启动单元测试可执行文件(小号)
编辑(经过奇怪的近距离表决):在进入细节之前,我将尝试在此处总结要点:
如何有效地组织C ++单元测试代码,这样既可以有效地编辑(测试)代码又可以运行测试代码?
然后,第一个问题是确定将单元测试代码放在哪里,以便:
- 结合相关的生产代码进行编辑和查看是“自然的”。
- 轻松/快速地为您当前更改的单元开始编译周期
在第二个的话,相关的,问题是什么来编译,这样的反馈是瞬时的。
极端的选择:
- 每个单元测试-测试单元都位于一个单独的cpp文件中,并且此cpp文件被单独编译+链接(连同它测试的源代码单元文件)到单个可执行文件,然后该可执行文件运行此一个单元测试。
- (+)这样可以最小化单个测试单元的启动(编译+链接!)时间。
- (+)测试运行非常快,因为它仅测试一个单元。
- (-)执行整个套件将需要启动大量流程。可能是一个管理难题。
- (-)流程启动的开销将变得可见
- 另一面将是-仍然-每个测试一个cpp文件,但是所有测试cpp文件(以及它们测试的代码!)都链接到一个可执行文件中(每个模块/每个项目/选择您的选择)。
- (+)编译时间仍然可以,因为只有更改的代码才能编译。
- (+)执行整个套件很容易,因为只有一个exe可以运行。
- (-)套件将花费很多时间进行链接,因为任何对象的每次重新编译都会触发重新链接。
- (-)(?)套装将花费更长的时间运行,尽管如果所有单元测试都很快,则时间应该可以。
那么,现实世界中的C ++ 单元测试如何处理?如果我只是每晚/每小时运行一次,那么第二部分并不重要,但是第一部分,即如何将UT代码“耦合”到生产代码,这样对于开发人员来说,将两者保持一致是“自然的”我认为专注始终很重要。(如果开发人员将UT代码作为重点,他们将要运行它,这将使我们回到第二部分。)
欣赏真实世界的故事和经验!
笔记:
- 该问题有意离开了未指定的平台和品牌/项目系统。
- 问题带有标记的UT&C ++是一个很好的起点,但是不幸的是,太多的问题(尤其是答案)过于注重细节或特定框架。
- 前一阵子,我回答了关于升压单元测试的结构的类似问题。我发现这种结构对于“真实的”快速单元测试是缺少的。我发现另一个问题过于狭窄,因此提出了这个新问题。
Pipeline<A,B>.connect(Pipeline<B,C>)
应该编译而不Pipeline<A,B>.connect(Pipeline<C,D>)
应该编译:第一级的输出类型与第二级的输入类型不兼容。