Блог разработчиков

тестирование Python-приложений: от unittest к nose

Макс Ищенко
Опубликовано 20.02.2006 в Python, Инструменты, Тестирование, статьи

С тех пор, как появилась первая библиотека для модульного тестирования - JUnit - появилась необходимость удобного выполнения тестов и представления результатов. В классическом JUnit были т.н. “runners”, один для консоли, другой для графического режима. Современные Java-IDE обычно интегрируют процесс исполнения тестов обычно прямо в оболочку, благо в JUnit есть для этих целей API.

Когда в Python 2.1 появился модуль unittest его дизайн был фактически содран с JUnit, включая интерфейс нахождения тестов и TextRunner для выполнения тестов в консоли. Наверное любой Python-программист знаком с unittest.main(), assertEquals и unitest.TestCase. По крайней мере, у меня в Vim даже макросы есть специальные для набора этих повторяющихся конструкций.

Как это часто бывает с заимствованиями, удобство использования инструмента с “чуждой” идеологией оставляли желать лучшего. Одним не нравилось необходимость наследоваться от unitest.TestCase, другим - необходимость писать self.assertEquals() вместо привычного assert, третьим - негибкость в поиске и исполнении тестов.

В конце концов “терпець урвався” и на свет появилась первая реальная альтернатива unittest - py.test, как часть амбициозного проекта py lib. На мой взгляд, чересчур амбициозного, с невысокими шансами попасть в mainstream. Компонент py.test был и остается, пожалуй, самой популярной частью проекта.

Девиз py.test: “лучший API - его отсутствие”. Как следствие, исчез класс TestCase от которого необходимо было наследоваться, вместе со своими assertEquals методами.
Наконец-то появилась возможность использовать обычный assert, а тесты определялись по наличию приставки test_ в именах функций и файлов.

Главных проблем с py.test было две: неудобство установки (требовался полный SVN checkout проекта py с последующими махинациями с PATH/PYTHONPATH) и “too much magic”. Как я говорил, проект py был весьма “продвинутым” и использовал очень уж сомнительные “трюкачества” над интерпретатором. В результате иногда тесты не выполнялись или падали с какой-нибудь экзотической ошибкой.

Обе эти проблемы были решены при помощи nose. Эта поистине замечательная программка-кроха (<1,5KLoC) выполнена в лучших Unix-традициях: “do one thing and do it well”. В двух словах это “py.test done right”.

Магии в ней самый минимум, а устанавливается она при помощи сверх-удобной setuptools. В результате установки получаем скрипт “nosetests” который найдет и выполнит все наши тесты.

Помимо описанных выше функций, перешедших из py.test есть в ней и другие приятные мелочи, как-то: code coverage report (если установлен coverage.py), интеграция с doctest, “правильный” nosetest.main (оригинальный unittest.main использует sys.exit() что делает затруднительной интеграцию), package-level fixtures (определяются в __init__.py), интеграция с уже упомянутыми setuptools.

Собственно использование nose я решил оставить за рамками статьи т.к. документация описывает все что нужно.

P.S.: По большому счету, тестировать можно не только приложения написанные на Пайтоне, но практически это имеет смысл если Python уже используется каким-то образом. Например, когда тесты пишутся на Python, приложение на Си, а взаимодейстуют они через HTTP/командный интерфейс/API. Я, например, использую nose для тестирования веб-приложения при помощи twill.

top of hotblogs.org.ua

1 звезда2 звезды3 звезды4 звезды5 звезд (2 голосов, средний: 2 из 5)
Загрузка ... Загрузка ...
Распределение голосов

Понравилась статья? Подпишись на обновления по RSS/E-mail

Подписаться, не оставляя комментарий

Все комментарии (5) к “тестирование Python-приложений: от unittest к nose”

  1. bialix говорит:

    использование assert для тестирования имеет один неприятный нюанс: при запуске интерпретатора с опцией -O все assert отключаются.

  2. Max говорит:

    Ну так не надо запускать интерпретатор с опцией -О. ;)

    Тем более для тестирования.

  3. bialix говорит:

    Это сильно сказано. А если нужно протестировать реальное поведение проги при этой опции? А еще есть гейзенбаги, я думаю вы о них знаете.

  4. Max говорит:

    Насколько я знаю, эта опция мало на что влияет (помимо отключения ассертов) и соотв очень редко используется (во всяком случае я об этом не знаю). А насчет гейзенбагов в модульных тестах - это сильно сказано. :)

  5. Andrew говорит:

    Обалденная штука. Раньше пользовал py.test, это - лучше. Кстати, никто не писал под него тесты для twisted? Может, есть уже для плагин, повторяющий функциональность twisted.trial?

Оставить комментарий

Указать свой сайт могут только зарегистрированные пользователи. Регистрация или вход.

Архив

Вакансии rss icon

Все вакансии

Комментарии