Python - doctest против unittest [закрыто]

160

Я пытаюсь начать с модульного тестирования в Python, и мне было интересно, кто-нибудь может объяснить преимущества и недостатки doctest и unittest.

Для каких условий вы бы использовали каждый?

Шон
источник

Ответы:

178

Оба ценны. Я использую и doctest, и нос вместо места unittest. Я использую doctest для случаев, когда тест дает пример использования, который на самом деле полезен в качестве документации. Обычно я не делаю эти тесты всеобъемлющими, стремясь исключительно к информативности. Я эффективно использую doctest в обратном порядке: не для проверки правильности моего кода на основе моего doctest, а для проверки правильности моей документации на основе кода.

Причина в том, что я нахожу, что всесторонние тесты документов слишком сильно загромождают вашу документацию, поэтому вы либо столкнетесь с неиспользуемыми строками документов, либо с неполным тестированием.

Для реального тестирования кода цель состоит в том, чтобы тщательно протестировать каждый случай, а не проиллюстрировать, что делает пример, что является другой целью, которая, я думаю, лучше достигается другими средами.

Брайан
источник
29
Там намного меньше шаблонов, и я считаю, что тесты гораздо проще писать (и читать). Низкая стоимость запуска для написания тестов (т.е. просто написания функции «test_foo ()» и запуска) также помогает избавиться от соблазна сделать интересные фрагменты кода перед тем, как закрепить ваши тесты.
Брайан
6
Я думаю, что это фантастический ответ.
Джеймс Брэди
Какие еще рамки тестирования вы используете? Или это исключительно нос?
Джо
6
Учитывая возраст этого ответа, вероятно, стоит упомянуть, что большая часть «стандартного» образца более старых версий unittest в значительной степени утрачена. Я все еще люблю Нос лучше, но это довольно много.
Адам Паркин
1
В течение последних нескольких лет, к вашему сведению, находился в «режиме обслуживания» и, скорее всего, прекратит все разработки (без участия третьей стороны). Это сопровождающие рекомендуют новые проекты использовать альтернативу.
Шесть
48

Я использую unittest почти исключительно.

Время от времени я помещаю некоторые вещи в строку документации, которые можно использовать в doctest.

95% тестов являются юнит-тестами.

Зачем? Мне нравится держать строки документов несколько короче и ближе к делу. Иногда тестовые случаи помогают уточнить строку документации. В большинстве случаев тестовые случаи приложения слишком длинны для строки документации.

С. Лотт
источник
Было бы здорово увидеть пример того, что, по вашему мнению, подходит, docstringа что нет. На самом деле мне нравится docstring в термине, который явно показывает, как использовать интерфейс, но использование его для этого и модульного тестирования может не подходить.
user1767754
33

Еще одним преимуществом тестирования документов является то, что вы можете убедиться, что ваш код выполняет то, что написано в документации. Через некоторое время изменения программного обеспечения могут заставить вашу документацию и код делать разные вещи. :-)

Джейсон Бейкер
источник
6
+1 от меня - отличная точка
Даг
28

Я работаю биоинформатиком, и большая часть кода, который я пишу, представляет собой сценарии «один раз, одна задача», код, который будет выполняться только один или два раза и который выполняет одну конкретную задачу.

В этой ситуации написание больших юнит-тестов может быть излишним, а док-тесты - полезный компромисс. Они быстрее пишутся, и поскольку они обычно включаются в код, они позволяют всегда следить за тем, как должен вести себя код, без необходимости открывать другой файл. Это полезно при написании небольших сценариев.

Кроме того, doctests полезны, когда вы должны передать свой сценарий исследователю, который не является экспертом в программировании. Некоторым людям очень трудно понять, как устроены юнит-тесты; с другой стороны, doctests являются простыми примерами использования, поэтому люди могут просто скопировать и вставить их, чтобы увидеть, как их использовать.

Итак, чтобы возобновить мой ответ: doctests полезна, когда вам нужно написать небольшие сценарии и когда вы должны передать их или показать их исследователям, которые не являются компьютерными учеными.

dalloliogm
источник
6
«Док-тесты полезны, когда вам приходится писать небольшие сценарии, а также когда вы должны передать их или показать исследователям, которые не являются компьютерными специалистами». Отличный момент. Я делаю то же самое, и программисты, не являющиеся Python, всегда удивляются, что документация может быть выполнена.
Даниэль Канас
14

Если вы только начинаете с идеей модульного тестирования, я бы начал с того, doctestчто он настолько прост в использовании. Это также естественно обеспечивает некоторый уровень документации. А для более всестороннего тестирования doctestвы можете поместить тесты во внешний файл, чтобы он не загромождал вашу документацию.

Я бы посоветовал, unittestесли вы исходите из опыта использования JUnit или чего-то подобного, где вы хотите иметь возможность писать модульные тесты в целом так же, как вы это делали в других местах.

Грег Хьюгилл
источник
4
Я был воодушевлен в этом направлении ( doctestдля начала), но в конце концов пожалел об этом. Для нетривиальных тестовых случаев я потерял подсветку синтаксиса и автозаполнение моего редактора. Когда тесты были в отдельном файле, я больше не мог запускать его прямо из редактора - мне приходилось каждый раз менять контекст на соответствующий исходный файл.
Нечетное
7

Я использую исключительно unittest; Я думаю, что doctest слишком сильно загромождает основной модуль. Это, вероятно, связано с написанием тщательных тестов.

Тони Арклс
источник
7

Использование обоих является допустимым и довольно простым вариантом. doctestМодуль обеспечивает DoctTestSuiteи DocFileSuiteметоды , которые создают UnitTest-совместимые Тесты из модуля или файла, соответственно.

Поэтому я использую оба и обычно использую doctest для простых тестов с функциями, которые практически не требуют настройки (простые типы для аргументов). Я действительно думаю, что несколько тестов doctest помогают документировать функцию, а не отвлекать от нее.

Но для более сложных случаев и для более полного набора тестов я использую unittest, которая обеспечивает больший контроль и гибкость.

davidavr
источник
7

Я не использую doctest в качестве замены для unittest. Хотя они немного перекрывают друг друга, эти два модуля не имеют одинаковую функцию:

  • Я использую unittestв качестве фреймворка для модульного тестирования, это означает, что он помогает быстро определить влияние любой модификации на остальную часть кода.

  • Я использую doctestв качестве гарантии, что комментарии (а именно строки документов) по-прежнему актуальны для текущей версии кода.

Широко документированные преимущества тест-ориентированной разработки, которую я получил unittest. doctestрешает гораздо более тонкую опасность устаревших комментариев, вводящих в заблуждение содержание кода.

rahmu
источник
4

Я почти никогда не пользуюсь документами. Я хочу, чтобы мой код самодокументировался, а строки документации предоставляют документацию пользователю. IMO, добавляющий сотни строк тестов в модуль, делает строки документов гораздо менее читабельными. Я также считаю, что модульные тесты легче модифицировать при необходимости.

JimB
источник
4

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. 

Также не проверяет тип вывода. Он просто сравнивает выходные строки. Например, он сделал некоторый тип рациональным, который печатает как целое число, если это целое число. Тогда предположим, что у вас есть функция, которая возвращает рациональную. Таким образом, doctest не будет дифференцироваться, если результат будет рациональным целым числом или целым числом.

жесткий
источник
5
Вы можете использовать raw docstrings ( r""" ... """) для решения первой проблемы.
icktoofay
Прекрасно работает в Python 3.4. Чтобы заставить его работать и в Python 2.7, используйте '\\xe0\\xa4\\x95'в вашей строке документации.
Сис Тиммерман
Я также обнаружил, что литералы Unicode также не работают с doctests (даже с правильной строкой комментария 'coding utf-8' вверху файла. Обычно doctests не так хорошо поддерживаются, как тесты unittest, поэтому есть некоторые ошибки это не исправить
RichVel
2

Я предпочитаю системы, основанные на открытиях («перенос» и «py.test», использующие первый в настоящее время).

doctest хорош, когда тест также хорош как документация, в противном случае они слишком часто загромождают код.

lazy1
источник
нос выглядит невероятно полезным; У меня еще не было возможности использовать его, но у меня большие надежды :)
Тони Арклес
Нос - в значительной степени самый простой тестовый фреймворк для использования, IMO. Это делает написание и запуск тестовых случаев практически без усилий.
Камил Кисиэль