Как пропустить весь модуль Unittest Python во время выполнения?
Я хотел бы, чтобы мой модуль unittest Python рассказывал тестировщику пропустить его в некоторых ситуациях (например, не удалось импортировать модуль или найти критический ресурс).
Я могу использовать @unittest.skipIf(...)
, чтобы пропустить класс unittest.TestCase, но как пропустить весь модуль? Применение скипов к каждому классу недостаточно, поскольку сами определения классов могут вызывать исключения, если модуль не может импортировать.
Ответы
Ответ 1
Посмотрев на другие ответы здесь, это лучший ответ, который я придумал. Это уродливо, внедряя весь набор тестов в обработку исключений, но, похоже, делает то, что вы хотите. В частности, пропустить тесты, когда импорт не работает.
Предполагая, что вы говорите об использовании 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'
Ответ 2
Если вы посмотрите на определение 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)
Ответ 3
Я обнаружил, что использование skipTest в setUp хорошо работает. Если вам нужен импортированный модуль, вы используете блок 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):
#...
Ответ 4
решение, предлагаемое otus, и, на мой взгляд, проще, чем принятое решение. Но есть хотя бы один недостаток. Если вы запросите 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')
Ответ 5
Возможно, было бы грязно помещать все определения подкласса unittest.TestCase
в блок try...except
, но это сработало бы:
import unittest
try:
import eggs
class Spam(unittest.TestCase):
pass
class Ham(unittest.TestCase):
pass
# ...
except ImportError:
# print 'could not import eggs'
pass
Ни один из подклассов не будет определен, если сбой импорта eggs
и все эти классы (Spam, Ham, etc.
) будут пропущены. Не отразилось бы на выходе (хорошее или плохое в зависимости от того, что вы хотите).
Ответ 6
Попробуйте определить пользовательскую функцию 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
Ответ 7
Объединяя указанные ответы и используя этот ответ:
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
Ответ 8
Для python 2.7+ (или с помощью backport):
...
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))
...
Ответ 9
@unittest.skip('comments_for_skipping_unit_tests')
class MyTests(unittest.TestCase):
def setUp(self):
pass
def test_something(self):
вы можете пропустить весь класс модульного теста, используя @unittest.skip decorator.