Я пытаюсь начать работу с модульным тестированием на Python, и мне было интересно, сможет ли кто-нибудь объяснить преимущества и недостатки doctest и unittest.
Какие условия вы бы использовали для каждого из них?
Я пытаюсь начать работу с модульным тестированием на Python, и мне было интересно, сможет ли кто-нибудь объяснить преимущества и недостатки doctest и unittest.
Какие условия вы бы использовали для каждого из них?
Оба ценны. Я использую как doctest, так и nose, заменяя unittest. Я использую doctest для случаев, когда тест дает пример использования, который действительно полезен в качестве документации. Как правило, я не делаю эти тесты исчерпывающими, ориентируясь исключительно на информативность. Я эффективно использую doctest в обратном порядке: не проверять мой код на основе моего доктрины, но проверить правильность моей документации на основе кода.
Причина в том, что я нахожу, что всеобъемлющие доктрины слишком сильно загромождают вашу документацию, поэтому вы либо закончите с непригодными докстерами, либо неполным тестированием.
Для фактического тестирования кода цель состоит в том, чтобы тщательно протестировать каждый случай, а не проиллюстрировать то, что происходит на примере, что является другой целью, которая, как мне кажется, лучше встречается другими фреймворками.
Я использую unittest почти исключительно.
Время от времени я помещаю некоторые вещи в docstring, которые можно использовать с помощью doctest.
95% тестовых случаев являются unittest.
Почему? Мне нравится держать docstrings несколько короче и более точно. Иногда тестовые примеры помогают уточнить документную строку. В большинстве случаев тестовые примеры приложений слишком длинны для docstring.
Еще одно преимущество учения - это то, что вы убедитесь, что ваш код делает то, что говорит ваша документация. Через некоторое время изменения программного обеспечения могут сделать вашу документацию и код разными.: -)
Я работаю биоинформатиком, и большая часть кода, который я пишу, - это сценарии "один раз, одна задача", код, который будет запускаться только один или два раза и который выполняет одну конкретную задачу.
В этой ситуации писать большие unittests могут быть чрезмерными, а доктрины - полезный компромисс. Они быстрее записываются, и поскольку они обычно включаются в код, они позволяют всегда следить за тем, как должен себя вести код, без необходимости открывать другой файл. Это полезно при написании небольших script.
Кроме того, доктрины полезны, когда вам нужно передать ваш script исследователю, который не является экспертом в программировании. Некоторым людям очень сложно понять, как структурированы унитаты; С другой стороны, доктрины - это простые примеры использования, поэтому люди могут просто скопировать и вставить их, чтобы посмотреть, как их использовать.
Итак, чтобы возобновить мой ответ: доктрины полезны, когда вам приходится писать небольшие скрипты, и когда вам нужно передать их или показать их исследователям, которые не являются компьютерными учеными.
Если вы только начинаете с идеи модульного тестирования, я бы начал с doctest
, потому что он настолько прост в использовании. Это также естественно обеспечивает некоторый уровень документации. И для более всестороннего тестирования с помощью doctest
вы можете поместить тесты во внешний файл, чтобы он не загромождал вашу документацию.
Я бы предложил unittest
, если вы исходите из того, что использовали JUnit или что-то подобное, где вы хотите писать модульные тесты в целом так же, как и в других местах.
Использование обоих вариантов является допустимым и довольно простым. Модуль doctest
предоставляет методы DoctTestSuite
и DocFileSuite
, которые создают совместимый с unittest testuite из модуля или файла соответственно.
Поэтому я использую оба варианта и обычно использую doctest для простых тестов с функциями, которые требуют небольшой или никакой настройки (простые типы для аргументов). Я на самом деле думаю, что несколько тестов на доктрины помогают документировать функцию, а не отвлекать ее.
Но для более сложных случаев и для более полного набора тестовых примеров я использую unittest, который обеспечивает больший контроль и гибкость.
Я использую unittest исключительно; Я думаю, что учение слишком сильно мешает основному модулю. Это, вероятно, связано с написанием тщательных тестов.
Я не использую doctest в качестве замены для unittest. Хотя они перекрывают бит, два модуля не имеют одинаковой функции:
Я использую unittest
как единый модуль тестирования, то есть он помогает мне быстро определить влияние любых изменений на остальную часть кода.
Я использую doctest
как гарантию того, что комментарии (а именно, docstrings) по-прежнему актуальны для текущей версии кода.
Широко документированные преимущества разработки, основанной на тестах, я получаю от unittest
. doctest
решает гораздо более тонкую опасность того, что устаревшие комментарии вводят в заблуждение содержание кода.
Я почти никогда не использую доктрины. Я хочу, чтобы мой код сам документировался, а docstrings предоставляют документацию пользователю. ИМО, добавляющая сотни строк тестов к модулю, делает докстрипы гораздо менее удобочитаемыми. Я также обнаружил, что модульные тесты легче модифицировать при необходимости.
Doctest
может несколько раз привести к неправильному результату. Особенно, когда вывод содержит escape-последовательности. Например
def convert():
"""
>>> convert()
'\xe0\xa4\x95'
"""
a = '\xe0\xa4\x95'
return a
import doctest
doctest.testmod()
дает
**********************************************************************
File "hindi.py", line 3, in __main__.convert
Failed example:
convert()
Expected:
'क'
Got:
'\xe0\xa4\x95'
**********************************************************************
1 items had failures:
1 of 1 in __main__.convert
***Test Failed*** 1 failures.
Также не проверяет тип вывода. Он просто сравнивает выходные строки. Например, он сделал некоторый разумный тип, который печатает точно так же, как целое число, если оно целое число. Тогда предположим, что у вас есть функция, возвращающая рациональную. Таким образом, учение не будет дифференцироваться, если вывод является рациональным целым числом или целым числом.
Я предпочитаю системы, основанные на обнаружении ( "нос" и "py.test", используя прежний).
doctest хорош, когда тест также хорош как документация, в противном случае они склонны слишком сильно загромождать код.