我正在为一个大型Python项目策划大量的单元测试。我们使用nose来进行测试发现和执行。我有一些测试文件在某些情况下确实不应该运行。例如,也许我有一个测试模块,它永远不应该在Windows上运行(只在Mac和Linux上运行)。
以下是我使用过的一些解决方案:
- 使用Nose出色的attrib插件标记测试方法或类的条件
- 对测试方法或类使用unittest.skipIf()
- 例如,使用nose的模式排除可以跳过名称中包含
windows
的文件
我对1&2是这些迫使我导入模块,这至少是浪费时间,如果存在依赖于平台的导入,可能会导致错误。我不喜欢#3,因为我觉得它很脆,在阅读测试用例时不容易发现它会被跳过。这三者似乎都过于依赖于测试和测试运行者之间的交互,我想要一些测试中的东西。
我想在测试模块的顶部做以下事情:
"""This module should not be run on Windows"""
import platform
if platform.system() == 'Windows':
<stop reading this module. nothing to see here>
# do the tests.
我如何告诉Python或Nose停止读取模块,但没有错误?我想我在找一个相当于提前退货的进口货。
以前曾提出过从模块执行中提前返回的功能,但它得到了一些反对票,并且该功能没有添加到语言中。
您可以阅读邮件列表线程,但通常不会认为必须将模块的大部分缩进一个额外级别的问题不是添加此"返回"功能的充分理由。有些人说,模块中几乎所有的代码都应该在函数和类中,几乎没有留下任何模块级的代码会受到这个问题的影响。
在Nose和unittest下,SkipTest异常被特殊处理-它不是失败。因此,以下代码将停止执行,并且不会向单元测试运行程序报告任何错误:
import unittest
import platform
if platform.system() == 'Windows':
raise unittest.case.SkipTest("The rest of this code will not be run on Windows.")
您可以使用该消息在那里引发ImportError
。调用程序可能会退出,并显示一个未捕获的异常,解释显示该错误,但如果需要,它可以捕获ImportError
。