Введение

Модуль Python doctest — эффективный инструмент для проверки и тестирования примеров кода. Чтобы убедиться, что код работает должным образом, он ищет в литературе интерактивные экземпляры, напоминающие диалог с Python. Его можно использовать для самых разных целей, включая написание учебной документации, регрессионное тестирование и проверку примеров документации. Проще говоря, doctest служит надежным помощником, который проверяет, работают ли ваши примеры кода должным образом.

doctest — Протестируйте интерактивные примеры Python

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

Вот несколько приложений для использования doctest:

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

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

Пример

import math

def factorial(n):
  """Calculate the factorial of a non-negative integer.
  Args:
    n (int): The number to calculate the factorial of.

  Returns:
        int: The factorial of the given number.

    Raises:
        ValueError: If the number is negative.
        ValueError: If the number is not an integer.
        OverflowError: If the number is too large.

    Examples:
    >>> factorial(5)
        120

        >>> factorial(0)
        1

        >>> factorial(10)
        3628800

        >>> factorial(-1)
        Traceback (most recent call last):
        ...
        ValueError: The number must be non-negative.

        >>> factorial(3.5)
        Traceback (most recent call last):
        ...
        ValueError: The number must be an integer.

        >>> factorial(1e100)
        Traceback (most recent call last):
        ...
        OverflowError: The number is too large.
    """

  if n < 0:
    raise ValueError("The number must be non-negative.")

  if not isinstance(n, int):
     raise ValueError("The number must be an integer.")

  if n + 1 == n:
    raise OverflowError("The number is too large.")

  result = 1

 for i in range(2, n + 1)
   result *= i

 return result

if __name__ == "__main__":
    import doctest
    doctest.testmod()
  • Когда вы запускаете с помощью команды
python2 example.py
  • Ничего не покажет

  • Но когда вы запускаете его с помощью этой команды
python3 example.py -v
  • Флаг или параметр -v — это то, что вы предоставляете команде Python. Флаг «подробный» или «-v» изменяет поведение команды Python.
  • Параметр -v указывает программе Python предоставить более подробную информацию о том, что она делает при запуске файла example.py, когда вы его включаете.
  • Параметр -v указывает модулю doctest, который используется в example.py, выводить журнал каждого примера, который он пытается выполнить, вместе с результатом каждого примера в контексте файла example.py. Он предлагает более подробные выходные данные, которые позволяют вам точно наблюдать за тем, что происходит в процессе тестирования.

  • Модуль doctest автоматически проверяет правильность работы интерактивных примеров в файле example.py, когда вы запускаете его прямо из командной строки.
  • Когда вы выполняете файл, если все идет по плану, вывода не будет. Это указывает на то, что каждый пример в файле был успешным.
  • Если вы запустите файл с флагом -v, doctest предоставит более подробную информацию о том, что он делает. В результате doctest будет публиковать журнал каждого примера, который он пытается выполнить, вместе со статусом успеха или неудачи. В заключении также будет представлено краткое изложение результатов испытаний.
  • Проще говоря, использование doctest для выполнения example.py похоже на наличие встроенной проверки, которая определяет, являются ли примеры кода в файле точными. В идеальном мире не было бы никакого выхода. Однако, если есть какие-либо проблемы, doctest предупредит вас, предоставив подробную информацию о неисправных экземплярах.

Проверка примеров в строках документации

  1. Ваш модуль желательно заканчивать основным, допустим, имя моего файла m.py
if __name__ == "__main__":
    import doctest
    doctest.testmod()

2. Затем запустите его обычной командой

python3 m.py
  • Если все примеры пройдены успешно, ничего не отображается
  • если какой-либо пример не пройден, doctest напечатает неудачные примеры и причины сбоев в стандартный вывод (stdout).
  • В последней строке вывода будет указано количество сбоев с сообщением «Тест не пройден N сбоев», где N представляет собой количество примеров, которые не прошли тест.
python M.py -v

Примечание:

  1. testmod(), она не проверяет аргументы командной строки (хранящиеся в sys.argv
  2. вы можете явно установить уровень детализации, передав параметр verbose в функцию testmod().
  3. Если вы установите verbose=True, он активирует подробный режим, что означает, что подробная информация будет напечатана в процессе тестирования.
  4. С другой стороны, если вы установите verbose=False, режим подробного вывода будет запрещен, что приведет к меньшему объему вывода.
  5. Запустите testmod() также с помощью ярлыка командной строки. Передав имена модулей в командной строке, вы можете указать интерпретатору Python запустить модуль doctest прямо из стандартной библиотеки:

Ярлык командной строки для testmode()

python -m doctest -v example.py
  • Имейте в виду, что это может работать неправильно, если файл импортирует дополнительные подмодули из другого пакета, к которому он принадлежит.

Проверка примеров в текстовом файле

Тестирование интерактивных примеров в текстовом файле — еще одно простое применение инструмента doctest. Для этого можно использовать Testfile(): test.py

import doctest
doctest.testfile("example.txt")
  • Этот скрипт считывает файл example.txt, чтобы определить, содержит ли он какие-либо интерактивные примеры Python.
  • В качестве файла может быть использован любой текстовый файл; полная программа Python не требуется. Он рассматривает содержимое файла как длинное объяснение или руководство.
The ``example`` module
======================

Using ``factorial``
-------------------

This is an example text file in reStructuredText format.  First import
``factorial`` from the ``example`` module:

    >>> from example import factorial

Now use it:

    >>> factorial(6)
    120
  • Сценарий запустится и проверит пример, если файл содержит инструкции по использованию модуля Python с именем «пример» и его функции «факториал».
  • Это достигается путем запуска кода, написанного в файле, в качестве интерпретатора Python.
  • В файле представлен пример, демонстрирующий использование функции «факториал», включенной в модуль «пример».
  • Функция импортируется с помощью оператора импорта, а затем ее применение демонстрируется путем вычисления факториала 6, что равно 120. Сценарий запустит этот код, чтобы увидеть, получен ли желаемый результат.
python3 test.py

Выход

Функция testfile() в doctest работает аналогично функции testmod(), но с некоторыми отличиями.

  1. Метод testmod() используется для тестирования кода Python непосредственно внутри модуля. Функция testfile() используется для тестирования и проверки интерактивных примеров Python, помещенных в текстовый файл.
  2. Testfile() ничего не выводит до тех пор, пока пример не завершится ошибкой, в отличие от testmod(). Если все примеры успешны, вывода не будет. Неудачный пример(ы) и причина(ы) отказа, тем не менее, отправляются на стандартный вывод (stdout) так же, как testmod(), если какие-либо примеры терпят неудачу.
  3. Расположение файла. По умолчанию скрипт Python, запускающий testfile(), ищет файлы в каталоге вызывающего модуля. Однако местоположение файла можно указать с помощью дополнительных параметров.
  4. Подробность: уровень детализации Testfile() можно изменить точно так же, как для testmod(). Параметр командной строки -v или необязательный параметр ключевого слова verbose можно использовать для управления уровнем детализации сценария. Более подробные выходные данные о выполняемых тестах предоставляются при более высоких настройках детализации.

Ярлык командной строки для testfile()

python -m doctest -v example.txt

Какие строки документации проверяются?

При использовании doctest он сканирует и ищет определенные разделы вашего кода, называемые строками документации, чтобы найти и протестировать предлагаемые там примеры.

Просматриваемые строки документации состоят из:

  • основная строка документации модуля, которая представляет собой введение в файл.
  • строки документации для классов, методов и функций, которые определяет модуль.
  • Тем не менее, важно помнить, что любые элементы, импортированные в модуль из внешних источников, не подлежат поиску.
  • Кроме того, если существует специальная переменная с именем M.__test__, которая считается «истинной» (обычно из-за непустого значения), предполагается, что она является словарем. Каждая запись в этом словаре сопоставляет имя строки с объектом функции, объектом класса или строкой. Если какие-либо строки документации объекта функции или класса будут найдены в M.__test__, они также будут найдены. Строки в M.__test__ обрабатываются так, как если бы они были строками документации.
  • В выводе тестов появится ключ K в M.__test__ с именем ‹name of M›.__test__.K.
  • Строки документации любых классов, обнаруженных во время поиска, рекурсивно просматриваются, включая строки документации любых вложенных методов и вложенных классов.

Как распознаются примеры строк документации?

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

Каждый пример в строке документации обычно начинается с ‘››› ‘ для представления строки ввода кода. Любые комментарии в примере игнорируются. Ожидаемый вывод следует сразу за строкой ввода кода ии продолжается до следующей строки '››› ' или строки, состоящей только из пробелов.

Правила, которым нужно следовать

Правило первое

Ожидаемый вывод не должен содержать строку, состоящую из пробелов, так как это считается концом ожидаемого вывода. Если вам нужна пустая строка в ожидаемом выводе, вместо нее можно использовать заполнитель ‹BLANKLINE›.

Пример

  • На этом рисунке каждая строка, начинающаяся с ›››, обозначает строку ввода кода, а следующая за ней строка без ››› обозначает желаемый результат.
  • Давайте представим, что мы хотим добавить пустую строку между вторым и третьим экземплярами в ожидаемом выводе. Для этого мы можем использовать заполнитель BLANKLINE›. Пересмотренная строка документации представлена ​​ниже:

  • Мы сигнализируем, что в ожидаемом выводе в этот момент должна быть пустая строка, используя символ BLANKLINE›. Делая это, мы можем определить требуемый вывод, даже если он содержит пустые строки. Когда выполняется doctest, он выполняет примеры, сравнивает результаты с ожидаемыми и отмечает любые несоответствия или проблемы.

Правило ✌️

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

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

# Enable the NORMALIZE_WHITESPACE option
doctest.NORMALIZE_WHITESPACE = True

# Run the doctest with the enabled option
doctest.testmod()
  • Перепишите тест, чтобы получить и сравнить выходные данные: вместо того, чтобы полагаться на прямое сравнение выходных данных, вы можете изменить тест, чтобы он собирал сгенерированные выходные данные, а затем сравнивал их с ожидаемым значением, используя собственную логику сравнения. Таким образом, у вас будет больше контроля над тем, как вкладки обрабатываются при сравнении.

Правило 👌

3. Захватывается стандартный вывод (stdout), но не стандартная ошибка (stderr).

  • Две строки кода, начинающиеся с ››› в этом примере, вызывают метод Division_numbers() с различными параметрами. За каждой строкой ввода кода следует желаемый результат.
  • doctest запустит примеры и запишет стандартный вывод (stdout) по мере его выполнения. Однако стандартная ошибка (stderr) не будет получать никакого вывода.
  • Результат операции деления печатается в первом примере, и мы ожидаем, что он будет записан и сравнен с ожидаемым результатом. Когда на втором рисунке создается исключение ZeroDivisionError, мы ожидаем, что сообщение об ошибке будет отправлено в stderr, а не перехвачено.
  • Если выходные данные doctest собраны и соответствуют ожидаемым, тест считается успешным. Тест завершается неудачно и показывает сравнение между фактическими и ожидаемыми выходными данными, если выходные данные не совпадают.
  • Захватив stdout, мы можем убедиться, что вывод нашего кода соответствует желаемому поведению, и игнорировать любые некритические сигналы или ошибки, записанные в stderr.

Правило ✌️✌️😂

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

В качестве альтернативы, если вы решите не использовать необработанную строку документации, вы должны удвоить каждую обратную косую черту в версии doctest примера. Обратная косая черта считается escape-символом в стандартных строках документации; однако, удваивая их, они рассматриваются как буквальные обратные косые черты.

Наша реакция сейчас😂😂

Что такое контекст выполнения?

  • По умолчанию doctest создает неглубокую копию глобального пространства имен модуля (globals) для этого конкретного теста, когда обнаруживает строку документации для тестирования. Такое поведение предотвращает любые непредвиденные зависимости или взаимодействия между различными тестами и гарантирует, что выполнение тестов не изменит реальные глобальные переменные модуля.
  • Это указывает на то, что каждый тест, который запускает doctest, работает в своем собственном отдельном контексте выполнения. Доступ и использование любых имен (переменных, функций и т. д.), объявленных ранее в отдельной тестируемой строке документации, а также любых имен, определенных на верхнем уровне тестируемого модуля (обозначаемых как M), является бесплатным.
  • Важно помнить, что примеры, содержащиеся в одной строке документации, не могут получить доступ или просмотреть имена, указанные в другой строке документации. Во время выполнения теста каждая строка документации обрабатывается как отдельный объект с уникальным изолированным контекстом.
  • Вместо использования глобальных переменных модуля вы можете предоставить свою собственную уникальную среду выполнения, передав словарь (your_dict) в качестве параметра globs методам testmod() или testfile(). Поступая таким образом, вы можете управлять контекстом, в котором запускаются примеры doctest, и указывать определенные имена или значения для нужд тестирования.

Пример

  • Метод add() в этом примере принимает на вход два целых числа и возвращает их сумму. Чтобы подтвердить ожидаемый результат при вызове метода add(), у нас есть два примера doctest в строке документации. Когда мы используем метод testmod() для запуска doctest для math_utils.py, он запустит примеры и проверит, соответствуют ли результаты ожидаемым.

запустить доктест

  • Для каждого теста doctest по умолчанию создает поверхностную копию глобальных переменных модуля (в данном примере math_utils). Это гарантирует, что запуск тестов не изменит реальные глобальные переменные модуля.
  • На нашем рисунке имена верхнего уровня модуля math_utils, включая саму функцию add, свободно доступны и могут использоваться функцией add().
  • Примеры doctest для метода add() не будут работать, если мы попытаемся сослаться на другую функцию, определенную в модуле, скажем, subtract(). Примеры, содержащиеся в одной строке документации, не могут видеть или использовать имена, определенные в другой строке документации.

В качестве параметра globs для testmod() вы можете указать словарь, если хотите указать свой собственный уникальный контекст выполнения. Вот иллюстрация:

Как насчет исключений?

Вы можете просто вставить трассировку исключения в качестве желаемого вывода при тестировании исключений с помощью doctest. Вот краткое описание:

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

В качестве примера возьмем следующий код, вызывающий ошибку ValueError:

На этом рисунке код пытается удалить элемент 42 из списка, даже если его там нет. Это приводит к выдаче ValueError с трассировкой, содержащей точное сообщение об ошибке и строку кода, вызвавшую ее.

Вы можете добавить код, вызывающий исключение, и вставить трассировку в качестве желаемого вывода, чтобы проверить это с помощью doctest. В этом случае желаемый результат:

Когда прогнозируемые и фактические результаты совпадают, Doctest считает тест успешным.

Заголовок трассировки, который может быть либо Traceback (последний последний вызов): либо Traceback (самый внутренний последний):, должен быть включен, это очень важно помнить. Если стек трассировки не содержит важной для примера информации, вы также можете его опустить.

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

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

Флаги опций

Модуль doctest Python имеет ряд опций, которые регулируют его поведение. Как константы модуля, эти флаги опций можно комбинировать с помощью побитового оператора ИЛИ (|) и отправлять в различные подпрограммы doctest.

Флаги параметров используются для изменения поведения doctest, а также для включения или выключения определенных функций. Их также можно использовать в директивах doctest, которые являются уникальными комментариями кода, предоставляющими дополнительные инструкции doctest framework. Кроме того, вы можете использовать параметр -o, чтобы передать эти флаги параметров интерфейсу командной строки doctest.

doctest.DONT_ACCEPT_TRUE_FOR_1

  • Если ожидаемый результат представляет собой просто число 1, по умолчанию фактический результат 1 или True считается совпадением. Это связано с тем, что Python часто заменяет числа (1/0) логическими значениями (True/False). Замена не разрешена, когда этот флаг применяется, поэтому 1 и True должны обрабатываться по-разному в предполагаемых и фактических выходных данных.

Пример файла

Команда

doctest.DONT_ACCEPT_BLANKLINE

  • Обычно пустая строка в фактическом выводе соответствует строке «ПУСТАЯ СТРОКА›» в ожидаемом выводе. Это используется, чтобы сигнализировать о том, что ожидается пустая строка. Однако прогнозируемые и фактические выходные данные должны иметь одинаковое количество пустых строк, пока этот флаг активен.

Пример файла

команда

doctest.NORMALIZE_WHITESPACE

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

Пример файла

команда

doctest.ELLIPSIS

  • Любая подстрока в фактическом выводе будет совпадать, если в ожидаемом выводе используется маркер многоточия (…). Сюда включаются подстроки, пересекающие множество строк, и даже пустые подстроки. Чтобы предотвратить неожиданные совпадения, рекомендуется использовать этот флаг редко и сделать его использование простым.

Пример файла

команда

doctest.IGNORE_EXCEPTION_DETAIL

  • При указании, даже если сведения об исключении не совпадают, пример завершается успешно, если инициируется требуемый тип исключения. Например, тест, предвосхищающий ValueError: 42, завершится успешно, если фактическое полученное исключение имеет значение ValueError: 3*14, но он завершится ошибкой, например, если выдается TypeError.

Пример

команда

doctest.SKIP

Пример не запускается и не тестируется при использовании doctest.SKIP. Если вы хотите добавить пример для документации, но не хотите, чтобы он рассматривался как тестовый пример, это полезно. Кроме того, его можно использовать для мгновенного «закомментирования» экземпляров.

В этом примере третий тестовый пример пропущен и не будет выполняться или проверяться.

doctest.COMPARISON_FLAGS

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

При выполнении тестов в этом примере различные флаги сравнения задаются вместе с помощью переменной doctest.COMPARISON_FLAGS. Различные флаги сравнения могут быть объединены (|) для формирования значения битовой маски.

Флаги отчетности:

Следующие флаги управляют тем, как сообщается об ошибках тестирования: doctest.REPORT_UDIFF:если задано, для отображения ошибок с многострочным ожидаемые и фактические результаты.

doctest.REPORT_CDIFF: сбои с многострочными ожидаемыми и фактическими выходными данными отображаются с использованием разницы контекста, когда он предоставляется.

doctest.REPORT_NDIFF: Различия рассчитываются с использованием библиотеки difflib, когда она задана. Различайте и выделяйте несоответствия как внутри, так и между строками.

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

import doctest

doctest.testmod(report=True, optionflags=doctest.REPORT_UDIFF | doctest.REPORT_ONLY_FIRST_FAILURE)

В этом случае отчет включается с помощью функции testmod с параметром report=True. Несколько флагов отчетов (REPORT_UDIFF и REPORT_ONLY_FIRST_FAILURE) можно указать с помощью побитового оператора ИЛИ (|) в аргументе optionflags. Эти команды обеспечивают гибкость и возможности настройки, позволяя управлять выполнением теста doctest и поведением отчетов.

FAIL_FAST

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

Параметр -f в интерфейсе командной строки doctest может использоваться для сокращения -o FAIL_FAST. Это позволяет быстро включить поведение FAIL_FAST при запуске doctest из командной строки.

В этом случае для параметра optionflags устанавливается значение doctest при запуске функции testmod. Поведение FAIL_FAST стало возможным благодаря FAIL_FAST. Процедура тестирования завершится мгновенно, а оставшиеся примеры не будут запускаться, если какой-либо пример не пройден.

Аргумент -f в этой команде служит сокращением для -o FAIL_FAST. При тестировании myfile.py он информирует интерфейс командной строки doctest о остановке после первого неудачного примера.

Директивы

как использовать специальные комментарии, известные как «директивы doctest», для изменения поведения модуля Python, называемого «doctest».

Специальные комментарии, известные как «директивы doctest», могут быть введены в Python после примера кода.

Синтаксис

  • Они начинаются со знака «#», затем имеют текст «doctest:» и несколько вариантов. При выполнении этого примера эти параметры изменяют поведение модуля doctest. С помощью символов «+» и «-» можно включать и выключать параметры.

Например, вывод образца может быть изменен с помощью параметров «NORMALIZE_WHITESPACE» и «ELLIPSIS». Модуль doctest будет сравнивать фактический вывод с предполагаемым выводом модифицированным способом, если после кода включены директивы «# doctest: +NORMALIZE_WHITESPACE» или «# doctest: +ELLIPSIS».

def add_numbers(a, b):
    """
    Adds two numbers and returns the result.

    >>> add_numbers(2, 3) # doctest: +NORMALIZE_WHITESPACE
    5
    """
    return a + b
  • В этом примере используется директива «NORMALIZE_WHITESPACE». Это допускает разницу в интервалах между ожидаемым и фактическим выходом. Поэтому, пока значения совпадают, doctest будет считать результат точным, даже если он содержит дополнительные пробелы.
def generate_range(start, end):
    """
    Generates a range of numbers from start to end (exclusive).

    >>> generate_range(1, 5) # doctest: +ELLIPSIS
    [1, 2, ..., 4]
    """
    return list(range(start, end))
  • На этом рисунке используется команда «ELLIPSIS». Это позволяет предполагаемому выводу использовать многоточие для обозначения диапазона чисел. В результате вместо того, чтобы перечислять каждое число отдельно, реальный вывод может включать в себя определенный диапазон чисел.
# Example with multiple directive comments for a single example
print(list(range(20))) # doctest: +ELLIPSIS
...                    # doctest: +NORMALIZE_WHITESPACE
  • Для удобства чтения мы разделили несколько инструкций в этом примере на независимые строки комментариев. Директива «+ELLIPSIS», указанная в первой строке, указывает doctest рассматривать многоточие (…) как представление диапазона значений. Во второй строке указана директива «+NORMALIZE_WHITESPACE», которая предписывает doctest игнорировать различия в пробелах. Поведение doctest изменяется путем объединения двух директив, которые применяются к одному и тому же примеру.
# Example with directives on a separate line for a long example
print(list(range(5)) + list(range(10, 20)) + list(range(30, 40)))
... # doctest: +ELLIPSIS
  • В этом случае код создает длинный список, объединяя несколько меньших диапазонов. Мы разместили директиву на отдельной строке после кода, чтобы облегчить понимание doctest. Эллипс (…) можно использовать для представления отсутствующих значений в списке благодаря команде «+ELLIPSIS». Это позволяет нам проиллюстрировать закономерность в ожидаемом результате, а не предоставлять все отдельные числа.

Предупреждения

Пакет Python doctest очень серьезно относится к необходимости точных совпадений в ожидаемом выводе. Это указывает на то, что тест не пройден, если хотя бы один символ между фактическим выводом и прогнозируемым выводом отличается. Иногда это может стать неожиданностью, особенно когда Python не гарантирует порядок пар ключ-значение в словарях или когда форматирование чисел с плавающей запятой различается в разных системах.

Пример

  • Чтобы повысить надежность ваших тестов при использовании doctest, вы должны внимательно относиться к ожидаемому результату и учитывать определенные параметры. Вот несколько иллюстраций:
def foo():
    """
    Returns a dictionary with characters and corresponding objects.

    >>> foo() == {"Hermione": "hippogryph", "Harry": "broomstick"}
    True
    """
    return {"Harry": "broomstick", "Hermione": "hippogryph"}
  • Чтобы сравнить фактический вывод функции foo() с ожидаемым результатом в этом примере, мы используем оператор ==. Учитывая, что Python не гарантирует порядок пар ключ-значение при печати словарей, мы делаем это, чтобы обеспечить точное соответствие между двумя словарями.

Пример

def print_instance():
    """
    Prints an instance of the class C.

    >>> print_instance() #doctest: +ELLIPSIS
    <__main__.C instance at 0x...>
    """
    class C: pass
    print(C())
  • На этом рисунке мы тестируем метод print_instance(), который печатает экземпляр класса C. Мы не можем ожидать точного совпадения в выводе, так как repr() по умолчанию для экземпляров встраивает адрес, который может измениться. Тест будет успешным независимо от адреса, поскольку мы используем директиву ELLIPSIS, чтобы сказать, что в выводе вместо адреса могут использоваться любые символы.

Пример

def print_fraction():
    """
    Prints a simple fraction.

    >>> print_fraction()
    0.75
    """
    print(3. / 4)
  • В данном случае мы тестируем функцию print_fraction(), которая выводит прямую дробь. Вывод чисел с плавающей запятой может несколько различаться в зависимости от системы. Мы можем явно предложить ожидаемый результат как точную цифру, которую мы хотим наблюдать, чтобы повысить надежность теста.

Заключение

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

Вы можете подключить 🌹me на:

Твиттер: https://twitter.com/Noransaber11

Linkedin: https://www.linkedin.com/in/noran-saber-abdelfattah-6198471ba/

С уважением, Норан🌹