Здравствуйте.
Модуль doctest, входящий в стандартную библиотеку Python, удобен при решении следующих задач:
– создание и прогон регрессионных unit-тестов
– документирование программного кода
Рассмотрим небольшой пример. В модуле transformation.py определена функция is_palindrome, которая находит слова-палиндромы в заданной строке. Ожидаем, что слова разделены пробелами, а пустая строка недопустима:
def is_palindrome (s): if len(s) < 1: raise ValueError ("Empty String!") words = s.split(" ") for word in words: wlist = list(word) wlist.reverse() drow = ''.join(wlist) if word == drow: print word
Обратимся к is_palindrome из оболочки Python:
>>> from transformation import is_palindrome >>> is_palindrome("level hello racecar") level racecar >>> is_palindrome("") Traceback (most recent call last): File "<stdin>", line 1, in ? File "transformation.py", line 12, in is_palindrome raise ValueError ("Empty String!") ValueError: Empty String! >>>
Функция выводит найденные палиндромы, а в случае пустой строки инициирует исключение. Полученные результаты могут одновременно служить unit-тестами и комментариями к is_palindrome. Видоизменим текст функции, добавив в нее результаты прогона и вызов unit-тестов:
def is_palindrome (s): """ Print palindromes >>> is_palindrome("level hello racecar") level racecar >>> is_palindrome("") Traceback (most recent call last): ... ValueError: Empty String! """ if len(s) < 1: raise ValueError ("Empty String!") words = s.split(" ") for word in words: wlist = list(word) wlist.reverse() drow = ''.join(wlist) if word == drow: print word def simple_test(): import doctest doctest.testmod() if __name__ == "__main__": simple_test()
Результат запуска transformation.py из командной строки будет более чем скромным:
[capt@rh Work]# python transformation.py [capt@rh Work]#
Такой результат означает, что все тесты, представленные в модуле, выполнены успешно. Подробные сведения можно получить с помощью ключа -v:
[capt@rh Work]# python transformation.py -v Running __main__.__doc__ 0 of 0 examples failed in __main__.__doc__ Running __main__.is_palindrome.__doc__ Trying: is_palindrome("level hello racecar") Expecting: level racecar ok Trying: is_palindrome("") Expecting: Traceback (most recent call last): ... ValueError: Empty String! ok 0 of 2 examples failed in __main__.is_palindrome.__doc__ Running __main__.simple_test.__doc__ 0 of 0 examples failed in __main__.simple_test.__doc__ 2 items had no tests: __main__ __main__.simple_test 1 items passed all tests: 2 tests in __main__.is_palindrome 2 tests in 3 items. 2 passed and 0 failed. Test passed.
Успешно пройдены два теста. Убедимся в том, что при изменении алгоритма прогон тестов закончится неудачей. Для этого в функции is_palindrome закомментируем одну строку:
wlist = list(word) # wlist.reverse() drow = ''.join(wlist)
Запуск transformation.py:
[capt@rh Work]# python transformation.py ******************************************************** Failure in example: is_palindrome("level hello racecar") from line #1 of __main__.is_palindrome Expected: level racecar Got: level hello racecar ******************************************************** 1 items had failures: 1 of 2 in __main__.is_palindrome ***Test Failed*** 1 failures.
Результат соответствует ожидаемому.
Дополнительную информацию о модуле doctest можно почерпнуть в документации Python.
Отметим плюсы и минусы doctest:
+ входит в стандартную библиотеку
+ простота использования
+ unit-тесты одновременно служат комментариями к коду
– необходимость жесткого соблюдения формата вывода (что не всегда приемлемо)
+ возможность интеграции с unittest (еще одним встроенным механизмом организации unit-тестов)
Разговор о unit-тестах в Python будет продолжен в одной из следующих статей. Оставайтесь с нами.
Что такое качество программного обеспечения и как его улучшить: теория и практика, задачи и решения, подводные камни и обходные пути.
Pingback : OpenQuality.ru | Python unittest: базовые возможности | February 2, 2009
[…] Приложение, достойное модульного тестирования, как правило содержит больше одного модуля. Соответственно, unittest предоставляет возможности для централизованного управления всеми тестами. Создадим агрегатор, который будет запускать тесты из класса TestBankAccount и тесты нахождения палиндромов. […]
Pingback : OpenQuality.ru | Python: модульное тестирование с MiniMock | June 2, 2009
[…] впечатлением от модуля python-mock. Будучи приверженцем doctest, Ian решил задействовать его возможности для […]