如何对我的单元测试进行有效的代码覆盖率分析?

5 投票
5 回答
3300 浏览
提问于 2025-04-15 12:18

我负责一个非常大的金融定价系统的测试。最近,我们的总部坚持要求我们确认项目的每一个部分都有一个有意义的测试。至少,他们希望有一个系统,可以确保当我们修改某些内容时,能够发现其他子系统的意外变化。更理想的是,他们希望能验证我们系统中每个组件的正确性。

这显然会是一项非常庞大的工作!可能需要几年时间,但对于这种项目来说,这是值得的。

我需要找出我们代码中哪些部分没有被单元测试覆盖。如果我知道系统中哪些部分没有测试,我就可以开始开发新的测试,最终实现完全的测试覆盖。

那么,我该如何进行这种分析呢?我可以使用哪些工具呢?

我在Windows 32位XP上使用Python 2.4。

更新0:

为了澄清一下:我们有一个非常全面的单元测试套件(还有一个单独的、非常全面的回归测试套件,这不在本次讨论范围内)。我们还有一个非常稳定的持续集成平台(使用Hudson构建),旨在将标准的Python单元测试分开并在我们的测试设施中运行:大约20台按照公司规格构建的电脑。

这次工作的目标是填补我们Python单元测试套件中的任何空白,以确保每个组件都有一定程度的单元测试覆盖。其他开发人员将负责项目中非Python组件的部分(这些也不在讨论范围内)。

组件”这个词故意模糊:有时它指的是一个类,有时是一个完整的模块或多个模块的组合。它甚至可能指的是一个单一的金融概念(例如,一种特定类型的金融期权或多种期权使用的金融模型)。这个问题可以从很多角度来切入。

对我来说,“有意义”的测试是那些验证函数是否按照开发者最初的意图工作的测试。我们不想仅仅在纯Python中重现回归测试。开发者的意图往往不是立刻显而易见的,因此需要研究和澄清任何看起来模糊的地方,然后将这些知识固化在一个单元测试中,使原始意图变得非常明确。

5 个回答

4

这就是我们所做的事情。因为我不知道你的单元测试和回归测试是怎么设置的,所以你得自己判断这是否对你有帮助。

  • 每个Python包都有单元测试
  • 我们使用nose自动检测单元测试。nose可以自动识别标准的Python单元测试(基本上就是任何看起来像测试的东西)。这样我们就不会漏掉任何单元测试。nose还有插件功能,可以让你生成一些漂亮的输出。
  • 我们追求100%的单元测试覆盖率。为此,我们使用Coverage来检查,因为nose的一个插件提供了集成
  • 我们把Eclipse(我们的开发环境)设置成在文件更改时自动运行nose,这样单元测试总是会被执行,同时也能显示代码覆盖率作为附带结果。
4

第一步是写有意义的测试。如果你只是为了达到测试覆盖率而写测试,那就适得其反了;这可能意味着你会过于关注代码的具体实现,而不是关注它应该达到的效果。

顺便说一下,我会使用nose作为单元测试框架(http://somethingaboutorange.com/mrl/projects/nose/0.11.1/);它的插件系统非常好,可以让你选择覆盖率的选项(比如使用--with-coverage来查看Ned的覆盖率,使用--with-figleaf来查看Titus的覆盖率;支持coverage3的功能也应该会推出),而且你还可以为自己的构建系统编写插件。

6

如果你只是想查看代码覆盖率,可以使用coverage.py这个工具。

关于coverage.py和figleaf的比较:

figleaf和Python的标准覆盖工具(也就是'coverage.py')有几个不同之处。首先,figleaf在判断哪些代码行是“有趣”的时候,使用的是sys.settrace这个函数的标准,这样就简化了coverage.py的一些复杂性(但这也意味着你的“行数”统计会减少)。其次,figleaf不会记录在Python标准库中执行的代码,这样可以大大提高速度。最后,figleaf保存覆盖率的格式非常简单,容易处理。

如果你需要从多种测试中记录覆盖率,并且想以有趣的方式汇总这些覆盖率,或者控制何时记录覆盖率,figleaf可能是个不错的选择。而如果你是在命令行下执行,coverage.py会更好一些,它的报告也更漂亮。

我想这两个工具各有优缺点。

撰写回答