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

Условный пропустить конструктор TestCase в носетках

Есть ли способ пропустить целое TestCase на основе пользовательского условия с помощью nosetests? Я имею в виду что-то в стиле unittest.skip*.

Я пробовал

import unittest

@unittest.skip("No reason")
class TestFoo(object):
    def test_foo(self):
        assert False

Я выяснил, что это работает, используя python <= 2.7.3 (по-видимому, случайно), но в python 2.7.6 нет.

Есть ли способ носетистов сделать это, или я должен создать свой собственный декоратор?

Примечания:

  • Мы пробовали все комбинации python 2.7.3, 2.7.6 и nosetests 1.1.2, 1.3.0.
  • Если класс наследуется от unittest.TestCase, он работает, но это не то, что мне нужно.
  • Кажется, что работает, когда setUpClass поднимает SkipTest, но выглядит неуклюже.
  • Я нашел nottest декоратор, но он не помечает тест как пропущенный.

Резюме

  • Обновление 20. 5. 2014: до этой даты я не нашел решения этой проблемы, поэтому кажется, что единственным вариантом является создание пользовательского декоратора.
  • Обновление 12. 6. 2014: Я обнаружил, что повышение SkipTest в setUpClass не является хорошей идеей в некоторых случаях, поскольку nosetests не teardownContext в этих случаях. Это может иметь неблагоприятные последствия, если задействованы плагины.
4b9b3361

Ответ 1

Я наблюдал такое же поведение, что unittest.skip, unittest.skipIf и т.д. декораторы не соблюдаются при использовании носа для выполнения моих тестов.

Предложение Bakuriu о написании декоратора, которое вызывает исключение SkipTest в методе setUpClass, устраняет проблему: тесты теперь должным образом пропускаются независимо от того, выполняется ли из unittest.main или из носа.

Вот код, в значительной степени основанный на исходном коде декодера unittest. Ключевыми строками являются те, которые используются при декорировании в классе TestCase:

from unittest import SkipTest, TestCase
import functools
import types

def _id(obj):
    return obj

def skip(reason):
    """Unconditionally skip a test."""
    def decorator(test_item):
        if not isinstance(test_item, (type, types.ClassType)):
            @functools.wraps(test_item)
            def skip_wrapper(*args, **kwargs):
                raise SkipTest(reason)
            test_item = skip_wrapper
        elif issubclass(test_item, TestCase):
            @classmethod
            @functools.wraps(test_item.setUpClass)
            def skip_wrapper(*args, **kwargs):
                raise SkipTest(reason)
            test_item.setUpClass = skip_wrapper
        test_item.__unittest_skip__ = True
        test_item.__unittest_skip_why__ = reason
        return test_item
    return decorator

def skipIf(condition, reason):
    """Skip a test if the condition is true."""
    if condition:
        return skip(reason)
    return _id

Ответ 2

Да.

from nose.plugins.skip import SkipTest

@SkipTest
def execute_main_test():
    model_small = os.path.join(utils.get_project_root(),
                               "models",
                               "small-baseline")
    view.main(True, model_small, False, 31, False, 'mysql_online')
    view.main(False, model_small, False, 31, False, 'mysql_online')
    view.main(False, model_small, True, 31, False, 'mysql_online')
    view.main(False, model_small, False, 31, True, 'mysql_online')