Отключение тестов носа Python - PullRequest
49 голосов
/ 13 июля 2009

При использовании тестов носа для Python можно отключить модульный тест, установив для атрибута __test__ функции теста значение false. Я реализовал это с помощью следующего декоратора:

def unit_test_disabled():
    def wrapper(func):
         func.__test__ = False
         return func

    return wrapper

@unit_test_disabled
def test_my_sample_test()
    #code here ...

Однако, это имеет побочный эффект вызова оболочки как модульного теста. Обертка всегда будет проходить, но она включена в вывод тестов носа. Есть ли другой способ структурировать декоратор так, чтобы тест не запускался и не появлялся в результатах тестирования носа.

Ответы [ 5 ]

145 голосов
/ 04 декабря 2009

Нос уже имеет встроенный декоратор для этого:

from nose.tools import nottest

@nottest
def test_my_sample_test()
    #code here ...

Также ознакомьтесь с другими вкусностями, которые предоставляет нос: https://nose.readthedocs.org/en/latest/testing_tools.html

64 голосов
/ 20 февраля 2015

Вы также можете использовать unittest.skip декоратор:

import unittest


@unittest.skip("temporarily disabled")
class MyTestCase(unittest.TestCase):
    ...
31 голосов
/ 07 октября 2011

Существует также плагин skiptest для проверки носа, который будет вызывать тестовое шоу в тестовом выводе при пропуске. Вот декоратор для этого:

def skipped(func):
    from nose.plugins.skip import SkipTest
    def _():
        raise SkipTest("Test %s is skipped" % func.__name__)
    _.__name__ = func.__name__
    return _

Пример вывода:

$ nosetests tests
..........................................................................
..................................S.............
----------------------------------------------------------------------
Ran 122 tests in 2.160s

OK (SKIP=1)
6 голосов
/ 13 мая 2016

Вы можете просто начать имя класса, метода или функции с подчеркивания, и нос будет игнорировать его.

@nottest имеет свое применение, но я считаю, что он не работает хорошо, когда классы наследуются друг от друга, и некоторые базовые классы должны игнорироваться носом. Это часто случается, когда у меня есть ряд похожих представлений Django для тестирования. Они часто разделяют характеристики, которые требуют тестирования. Например, они доступны только пользователям с определенными разрешениями. Вместо того чтобы писать одинаковую проверку разрешений для всех них, я помещаю такой общий тест в начальный класс, из которого происходят другие классы. Проблема, однако, в том, что базовый класс существует только для более поздних классов и не предназначен для самостоятельного запуска. Вот пример проблемы:

from unittest import TestCase

class Base(TestCase):

    def test_something(self):
        print "Testing something in " + self.__class__.__name__

class Derived(Base):

    def test_something_else(self):
        print "Testing something else in " + self.__class__.__name__

И вывод от насморка на него:

$ nosetests test.py -s
Testing something in Base
.Testing something in Derived
.Testing something else in Derived
.
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

Класс Base включен в тесты.

Я не могу просто ударить @nottest на Base, потому что это отметит всю иерархию. В самом деле, если вы просто добавите @nottest к приведенному выше коду перед class Base, то нос не будет запускать никаких тестов.

Я добавляю подчеркивание перед базовым классом:

from unittest import TestCase

class _Base(TestCase):

    def test_something(self):
        print "Testing something in " + self.__class__.__name__

class Derived(_Base):

    def test_something_else(self):
        print "Testing something else in " + self.__class__.__name__

А при запуске _Base игнорируется:

$ nosetests test3.py -s
Testing something in Derived
.Testing something else in Derived
.
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

Это поведение плохо документировано, но код, который выбирает тесты явно проверяет подчеркивание в начале имен классов .

Подобный тест выполняется носом для имен функций и методов, поэтому их можно исключить, добавив подчеркивание в начале имени.

0 голосов
/ 13 июля 2009

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

def unit_disabled(func):
    def wrapper(func):
         func.__test__ = False
         return func

    return wrapper

@unit_disabled
def test_my_sample_test():
    assert 1 <> 1

def test2_my_sample_test():
    assert 1 <> 1
...