Как написать декоратор, чтобы пропустить определенные тесты, когда модуль не импортируется? - PullRequest
3 голосов
/ 26 марта 2012

Я использую нос для тестирования.Я знаю, как пропустить тестирование, но мне было интересно, есть ли простое решение написать декоратор для пропуска тестов, когда какой-то модуль не импортирован.

Сейчас я пытаюсь импортировать mock и поймать ImportError, если он не установлен и установить mock = None.В начале тестов, требующих макета, я использую if not mock: raise SkipTest() в качестве 1-й строки.

Это работает хорошо.Мне просто интересно, возможно ли это и с декоратором?

Обновление

Я уже давно пользуюсь ответом kindall , просто чтобы сегодня заметить, что это все еще не работает правильно (по крайней мере, не в всех случаях!

Кажется, что работает, когда я использую тестовую функцию, то есть негенератор (не содержит оператора yield). Всякий раз, когда я использую декоратор в тестовой функции, которая использует yield, тест проходит независимо от того, произойдет ли сбой assert в полученной функции.

Есть идеи, почему это происходит и как предотвратить такое поведение?

Ответы [ 3 ]

6 голосов
/ 26 марта 2012

Разве не нравится эта работа?

import functools

def requires_mock(test):

    @functools.wraps(test)
    def wrapper():
        if mock:
            return test()
        raise SkipTest

    return wrapper
0 голосов
/ 29 марта 2012

Вдохновленный ответом kindall (который работает) Я попытался заставить его работать без functools снова:

def requires_mock(test):

    def wrapper(*args, **kwargs):
      if mock_not_available:
        raise SkipTest()
      else:
        return test(*args, **kwargs)

    wrapper.__name__ = test.__name__
    return wrapper

Кажется, тоже работает. Значение __name__ важно, чтобы nose распознало функцию и пометило ее при подробном тестировании.

Надеюсь, я ничего не пропустил? Потерять веру в свой тест - печальная вещь: (

0 голосов
/ 26 марта 2012

Декоратор должен выглядеть так:

def needsMock(fn):
    def wrapped():
        if mock is None: return

        fn()

    return wrapped

Это делает тестовый проход, когда mock равен None.Вы также можете попытаться поднять SkipTest(), но это может помешать декораторам.

...