Давно пользуюсь встроенными 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 есть разные конфигурационные параметры и расширения.
Дополнительные модули
Полезные ссылки с тестированием в django
Для интеграции nose с django существует модуль django-nose.
Модули для реализации mock-объектов
Web testing
Selenium
Дополнительное чтиво