time

Nose: тестирование в Python

Давно пользуюсь встроенными unittest'ами и по большому счету они всем устраивают. Но иногда их ругают, например тут.

Как утверждают в статье на ibm.com, существует три явных лидера для unit-тестирования на python: nose, py.test и zope.testing.

Nose представляет собой расширение над стандартными unittest и облегчает написание тестов.

Но перед началом, стоит упомянуть о хорошей вводной статье про TDD и модульное тестирование - Модульные тесты: pros, cons, et cetera. Интересная подборка python-модулей для тестирования есть в wiki - Python Testing Tools Taxonomy.

Установим nose и coverage

pip install nose coverage

Напишем простой пример, в котором будем проверять функционал класса Foo на равенство значению, не равенство значению и возможность генерации исключения. Для этого создадим класс TestFoo, у которого все методы начинаются с test_ - это метка (testMatch regular expression) для nose, что надо вызвать этот метод. Результат работы этих методов попадет в конечный отчет о запущенных тестах. В TestFoo есть два дополнительных метода: setUp - выполняется каждый раз, когда вызывается какой-то из тестовых методов (в моем случаи: test_exist, test_get, test_calc.), teardown - выполняется по окончанию тестового метода.

from nose.tools import assert_raises

class Foo:
    def exist(self):
        return True
    def get(self):
        raise IOError('access denied')
    def calc(self, v):
        return 2*v

class TestFoo:
    def setUp(self):
        self.multiplier = 2
    def teardown(self):
        pass
    def test_exist(self):
        f = Foo()
        assert f.exist() == True
    def test_get(self):
        f = Foo()
        assert_raises(IOError, f.get)
    def test_calc(self):
        f = Foo()
        assert f.calc(self.multiplier) != 5

Запускаем и смотрим результат

nosetests -v ntst.py
ntst.TestFoo.test_calc ... ok
ntst.TestFoo.test_exist ... ok
ntst.TestFoo.test_get ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.001s
OK

Что-бы оценить насколько хорошо класс Foo обложен тестами понадобится модуль coverage, который должен был установится через выше приведенную команду pip.

nosetests -v --with-coverage ntst.py
ntst.TestFoo.test_calc ... ok
ntst.TestFoo.test_exist ... ok
ntst.TestFoo.test_get ... ok

Name    Stmts   Miss  Cover   Missing
-------------------------------------
ntst       24      0   100%   
----------------------------------------------------------------------
Ran 3 tests in 0.002s

OK

Что-бы отобразить прогресс бар во время процесса тестирования можно прикрутить nose-progressive.

У nose есть разные конфигурационные параметры и расширения.

Дополнительные модули

  • disable-docstring - отключение запуска тестов в docstring
  • rudolf - раскрашивание вывода nose

Полезные ссылки с тестированием в django

Для интеграции nose с django существует модуль django-nose.

Модули для реализации mock-объектов

Web testing

Selenium

Дополнительное чтиво

blog comments powered by Disqus