Подтвердить что ты не робот

Как пропустить весь модуль Unittest Python во время выполнения?

Я хотел бы, чтобы мой модуль unittest Python рассказывал тестировщику пропустить его в некоторых ситуациях (например, не удалось импортировать модуль или найти критический ресурс).

Я могу использовать @unittest.skipIf(...), чтобы пропустить класс unittest.TestCase, но как пропустить весь модуль? Применение скипов к каждому классу недостаточно, поскольку сами определения классов могут вызывать исключения, если модуль не может импортировать.

4b9b3361

Ответ 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.