我想我的Python单元测试模块告诉测试运行器在某些情况下(如无法导入模块或找到关键资源)跳过其全部内容。如何在运行时跳过整个Python unittest模块?
我可以使用@unittest.skipIf(...)
跳过unittest.TestCase类,但是如何跳过整个模块?对每个类应用跳过是不够的,因为如果模块导入失败,类定义本身可能会导致异常。
我想我的Python单元测试模块告诉测试运行器在某些情况下(如无法导入模块或找到关键资源)跳过其全部内容。如何在运行时跳过整个Python unittest模块?
我可以使用@unittest.skipIf(...)
跳过unittest.TestCase类,但是如何跳过整个模块?对每个类应用跳过是不够的,因为如果模块导入失败,类定义本身可能会导致异常。
看其他answe后在这里,这是我想到的最好的答案。这很丑陋,将整个测试套件嵌入到异常处理中,但它似乎按照你的意愿去做。特别是在进口不起作用时跳过测试。
假设你正在讨论使用nosetests -x来运行测试,它应该继续跳过测试,至少它在我尝试时会出现。
import unittest
try:
import PyQt4
# the rest of the imports
# actual tests go here.
class TestDataEntryMixin(unittest.TestCase):
def test_somefeature(self):
# ....
except ImportError, e:
if e.message.find('PyQt4') >= 0:
class TestMissingDependency(unittest.TestCase):
@unittest.skip('Missing dependency - ' + e.message)
def test_fail():
pass
else:
raise
if __name__ == '__main__':
unittest.main()
如果导入失败,它将用单个跳过的单个测试代替测试运行。我也试图确保它不会无意中吞噬任何异常。这个解决方案对这个问题的所有其他答案和评论都有很大的帮助。
如果您在详细模式下运行它,你会看到这个的时候它会跳过,
test_fail (test_openihm_gui_interface_mixins.TestMissingDependency) ... skipped 'Missing dependency - No module named PyQt4'
我认为这是最好的答案,但你是对的,这很丑。 :-) –
获取'DeprecationWarning:BaseException.message从Python 2.6'已被弃用?你需要这样做:http://stackoverflow.com/questions/1272138/baseexception-message-deprecated-in-python-2-6 – crazysim
这可能是脏把所有的unittest.TestCase
子类定义的try...except
块,但它的工作:
eggs
导入失败和所有那些
import unittest
try:
import eggs
class Spam(unittest.TestCase):
pass
class Ham(unittest.TestCase):
pass
# ...
except ImportError:
# print 'could not import eggs'
pass
无子类将被定义类()被跳过。不会反映在输出中(取决于你想要的是好还是坏)。
对于一个人为的问题,一个肮脏的解决方案并不是那么糟糕;) –
@Mu Mind,真的是人为的吗?我的用例是在多个平台上运行测试套件(其中有些可能无法'导入蛋')。 –
我主要是给你一个难过的时光。我认为关于类定义失败的一点听起来有点奇怪,但禁用“这个模块”确实比禁用“本模块中的所有类”更清洁。 –
如果您看一下unittest.skipIf
和unittest.skip
的定义,您可以看到执行测试时密钥正在执行raise unittest.SkipTest(reason)
。如果您能够接受有它显示为一个中的TestRunner跳过测试而不是几个,你可以简单地提高自己的unittest.SkipTest
进口:
import unittest
try:
# do thing
except SomeException:
raise unittest.SkipTest("Such-and-such failed. Skipping all tests in foo.py")
与nosetests -v
运行提供了:
Failure: SkipTest (Such-and-such failed. Skipping all tests in foo.py) ... SKIP:
Such-and-such failed. Skipping all tests in foo.py
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK (SKIP=1)
试试你的模块中定义自定义load_tests
功能:
import unittest
try:
(testcases)
except ImportError as e:
def load_tests(*args, **kwargs):
print("Failed to load tests: skipping")
return unittest.TestSuite() # no tests
我喜欢这种方法。如果它使用SkipTest机制而不仅仅是一个'print',它可能会更好,因为输出可能会在一堆其他测试输出/结果中被淹没。 –
这是可能的。只要'TestSuite'包含一个虚拟测试用例,说明它被跳过了。 ('unittest'模块的'loader'做类似的事情,如果导入失败就会产生保证失败的测试用例)。 – nneonneo
我发现,在安装使用skipTest运作良好。如果您需要导入模块,则使用try块来设置module_failed = True,并在setUp中调用skipTest(如果已设置)。该报告检验跳过正确数量只需要很短的try块:
import unittest
try:
import my_module
module_failed = False
except ImportError:
module_failed = True
class MyTests(unittest.TestCase):
def setUp(self):
if module_failed:
self.skipTest('module not tested')
def test_something(self):
#...
的solution提出的OTU的作品,比在我看来,接受的解决方案更容易。但至少有一个缺点。如果你在一个装饰查询my_module
跳过一个单一的测试,如
@unittest.skipIf(my_module.support_foo, 'foo not supported')
def test_foo(self):
...
你会得到一个NameError: name 'my_module' is not defined
。将溶液放跳过内部函数定义:
def test_foo(self):
if not my_module.support_foo:
self.skipTest('foo not supported')
结合所提到的答案,并使用this answer:
import unittest
def module_exists(module_name):
try:
__import__(module_name)
except ImportError:
return False
else:
return True
class TestClass(unittest.TestCase):
@unittest.skipUnless(module_exists("moduleA"), 'ModuleA not installed')
def test_something(self):
# test something with moduleA
用于Python 2.7+(或使用unittest2反向移植):
...
import unittest
def setUpModule():
try:
import something
except ImportError as err:
raise unittest.SkipTest(str(err))
class Tests(unittest.TestCase):
@classmethod
def setUpClass(cls):
try:
import something
except ImportError as err:
raise unittest.SkipTest(str(err))
...
仅供参考,在http://colinnewell.wordpress.com/2012/08/31/skippng-python-unit-tests-if-a-dependency-is-missing/上有一篇关于此确切内容的博客文章 –
@Mu心灵,这个作品,除了我告诉'鼻子“,”失败快“。调用'unittest.SkipTest()'似乎算作失败并暂停执行。 –