test — Пакет регрессионных тестов для Python

Примечание

Пакет test предназначен только для внутреннего использования Python. Он задокументирован для разработчиков ядра Python. Любое использование этого пакета за пределами стандартной библиотеки Python не рекомендуется, поскольку упомянутый здесь код может быть изменён или удален без предварительного уведомления между выпусками Python.


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

Каждый модуль в пакете test, имя которого начинается с test_, представляющий собой наборы для тестирования определённого модуля или функции. Все новые тесты должны быть написаны с использованием модуля unittest или doctest. Некоторые старые тесты написаны с использованием «традиционного» стиля тестирования, в котором выходные данные сравниваются с sys.stdout; данный стиль теста считается устаревшим.

См.также

Модуль unittest
Написание регрессионных тестов PyUnit.
Модуль doctest
Тесты, встроенные в строки документации.

Написание модульных тестов для пакета test

Предпочтительно, чтобы использующие модуль unittest тесты, соответствовали нескольким рекомендациям. Один из них — назвать тестовый модуль, начав его с test_ и завершив его именем тестируемого модуля. Методы тестирования в тестовом модуле должны начинаться с test_ и заканчиваться описанием того, что метод тестирует. Это нужно для того, чтобы методы распознавались тест-драйвером как методы тестирования. Кроме того, не следует включать строку документации для метода. Комментарий (например, # Функция Tests возвращает только True или False) следует использовать для предоставления документации по методам тестирования. Это делается потому, что строки документации распечатываются, если они существуют, и поэтому не указывается, какой тест выполняется.

Часто используется базовый шаблон:

import unittest
from test import support

class MyTestCase1(unittest.TestCase):

    # Используются setUp() и tearDown() только при необходимости

    def setUp(self):
        ... код для выполнения при подготовке к тестам ...

    def tearDown(self):
        ... код для выполнения очистки после тестов ...

    def test_feature_one(self):
        # Тестовая функция номер один.
        ... код тестирования ...

    def test_feature_two(self):
        # Тестовая функция номер два.
        ... код тестирования ...

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

class MyTestCase2(unittest.TestCase):
    ... та же структура, что и у MyTestCase1 ...

... больше тестовых классов ...

if __name__ == '__main__':
    unittest.main()

Данный шаблон кода позволяет запускать множество для тестирования с помощью test.regrtest, как сценарий, поддерживающий интерфейс командной строки unittest, или через интерфейс командной строки python -m unittest.

Цель регрессионного тестирования — попытаться сломать код. Это приводит к нескольким рекомендациям, которым необходимо следовать:

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

  • Тестирование методом «белого ящика» (проверка тестируемого кода во время написания тестов) предпочтительнее. Тестирование «черного ящика» (тестирование только опубликованного пользовательского интерфейса) недостаточно полно, чтобы убедиться, что проверены все граничные и пограничные случаи.

  • Убедиться, что проверены все возможные значения, включая недопустимые. Это гарантирует, что не только все допустимые значения являются приемлемыми, но и что неправильные значения обрабатываются правильно.

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

  • Добавляет явный тест для любых ошибок, обнаруженных в тестируемом коде. Это гарантирует, что ошибка не возникнет снова, если код будет изменён в будущем.

  • Не забывает выполнить очистку после тестов (например, закрыть и удалить все временные файлы).

  • Если тест зависит от определённого состояния операционной системы, убедиться, что условие уже существует, прежде чем пытаться выполнить тест.

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

  • Старается максимизировать повторное использование кода. Иногда тесты будут различаться чем-то вроде того, какой тип ввода используется. Сведите к минимуму дублирование кода, создав подкласс базового тестового класса с классом, определяющим входные данные:

    class TestFuncAcceptsSequencesMixin:
    
        func = mySuperWhammyFunction
    
        def test_func(self):
            self.func(self.arg)
    
    class AcceptLists(TestFuncAcceptsSequencesMixin, unittest.TestCase):
        arg = [1, 2, 3]
    
    class AcceptStrings(TestFuncAcceptsSequencesMixin, unittest.TestCase):
        arg = 'abc'
    
    class AcceptTuples(TestFuncAcceptsSequencesMixin, unittest.TestCase):
        arg = (1, 2, 3)
    

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

См.также

Разработка через тестирование
Книга Кента Бека о написании тестов перед написанием кода.

Запуск тестов с помощью интерфейса командной строки

Пакет test можно запускать как скрипт для запуска набора регрессионных тестов Python благодаря опции -m: python -m test. Под капотом используется test.regrtest; вызов python -m test.regrtest, использовавшийся в предыдущих версиях Python, все ещё работает. Запуск скрипта автоматически запускает все регрессионные тесты в пакете test. Для этого он находит в пакете все модули, имя которых начинается с test_, импортирует их и выполняет функцию test_main(), если она присутствует, или загружает тесты через unittest.TestLoader.loadTestsFromModule, если test_main не существует. Имена тестов для выполнения также могут быть переданы сценарию. Указание одного регрессионного теста (python -m test test_spam) сведет к минимуму выходные данные и напечатает только то, пройдено или не пройдено испытание.

Запуск test напрямую позволяет установить, какие ресурсы доступны для использования тестами. Вы делаете это с помощью параметра командной строки -u. Указание all в качестве значения параметра -u включает все возможные ресурсы: python -m test -uall. Если желательны все ресурсы, кроме одного (более распространенный случай), список нежелательных ресурсов, разделенных запятыми, может быть указан после all. Команда python -m test -uall,-audio,-largefile запустит test со всеми ресурсами, кроме ресурсов audio и largefile. Чтобы получить список всех ресурсов и другие параметры командной строки, запускает python -m test -h.

Некоторые другие способы выполнения регрессионных тестов зависят от того, на какой платформе выполняются тесты. В Unix вы можете запускать make test в каталоге верхнего уровня, где был собран Python. В Windows выполнение rt.bat из вашего каталога PCbuild запустит все регрессионные тесты.

test.support — Утилиты для набора тестов Python

Модуль test.support обеспечивает поддержку набора регрессионных тестов Python.

Примечание

test.support не является общедоступным модулем. Он задокументирован здесь, чтобы помочь разработчикам Python писать тесты. API этого модуля может быть изменён без проблем обратной совместимости между выпусками.

Данный модуль определяет следующие исключения:

exception test.support.TestFailed

Исключение, которое вызывается при сбое теста. Устарело в пользу тестов на основе unittest и методов утверждений unittest.TestCase.

exception test.support.ResourceDenied

Подкласс unittest.SkipTest. Вызывается, когда ресурс (например, сетевое подключение) недоступен. Вызывается функцией requires().

Модуль test.support определяет следующие константы:

test.support.verbose

True, когда включён подробный вывод. Следует проверить, если требуется более подробная информация о выполняющемся тесте. verbose задается test.regrtest.

test.support.is_jython

True, если работающим интерпретатором является Jython.

test.support.is_android

True, если система Android.

test.support.unix_shell

Путь к оболочке, если не в Windows; в противном случае None.

test.support.FS_NONASCII

Не-ASCII-символ, кодируемый os.fsencode().

test.support.TESTFN

Устанавливает имя, которое безопасно использовать в качестве имени временного файла. Любой созданный временный файл должен быть закрыт и отсоединен (удален).

test.support.TESTFN_UNICODE

Задаёт для временного файла имя, отличное от ASCII.

test.support.TESTFN_ENCODING

Устанавливает sys.getfilesystemencoding().

test.support.TESTFN_UNENCODABLE

Устанавливает имя файла (тип str), которое не должно быть закодировано кодировкой файловой системы в строгом режиме. Это может быть None, если невозможно сгенерировать такое имя файла.

test.support.TESTFN_UNDECODABLE

Устанавливает имя файла (тип байтов), которое не должно быть декодировано кодировкой файловой системы в строгом режиме. Может быть None, если невозможно сгенерировать такое имя файла.

test.support.TESTFN_NONASCII

Устанавливает имя файла, содержащее символ FS_NONASCII.

test.support.IPV6_ENABLED

Устанавливает значение True, если на этом хосте включён IPV6, в противном случае — False.

test.support.SAVEDCWD

Устанавливает os.getcwd().

test.support.PGO

Устанавливает, когда тесты могут быть пропущены, если они бесполезны для PGO.

test.support.PIPE_MAX_SIZE

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

test.support.SOCK_MAX_SIZE

Константа, которая, вероятно, больше, чем размер буфера базового сокета ОС, чтобы блокировать запись.

test.support.TEST_SUPPORT_DIR

Устанавливает каталог верхнего уровня, который содержит test.support.

test.support.TEST_HOME_DIR

Устанавливает каталог верхнего уровня для пакета test.

test.support.TEST_DATA_DIR

Устанавливает каталог data в пакете test.

test.support.MAX_Py_ssize_t

Устанавливает sys.maxsize для больших тестов памяти.

test.support.max_memuse

Устанавливается set_memlimit() в качестве предела памяти для больших тестов памяти. Ограничено MAX_Py_ssize_t.

test.support.real_max_memuse

Устанавливается set_memlimit() в качестве предела памяти для больших тестов памяти. Не ограничено MAX_Py_ssize_t.

test.support.MISSING_C_DOCSTRINGS

Возвращает True, если работаете на CPython, а не на Windows, и конфигурация не установлена с WITH_DOC_STRINGS.

test.support.HAVE_DOCSTRINGS

Проверяет наличие строк документации.

test.support.TEST_HTTP_URL

Определяет URL-адрес выделенного HTTP-сервера для сетевых тестов.

test.support.ALWAYS_EQ

Объект, равный чему-либо. Используется для проверки сравнения смешанного типа.

test.support.LARGEST

Объект, который больше всего (кроме самого себя). Используется для проверки сравнения смешанного типа.

test.support.SMALLEST

Объект, который меньше всего (кроме самого себя). Используется для проверки сравнения смешанного типа.

Модуль test.support определяет следующие функции:

test.support.forget(module_name)

Удаляет модуль с именем module_name из sys.modules и удаляет все байт-компилированные файлы модуля.

test.support.unload(name)

Удаляет name из sys.modules.

Вызывает os.unlink() для filename. На платформах Windows это завершается циклом ожидания, который проверяет существование файла.

test.support.rmdir(filename)

Вызывает os.rmdir() для*filename*. На платформах Windows это завершается циклом ожидания, который проверяет существование файла.

test.support.rmtree(path)

Вызывает shutil.rmtree() на path или вызывает os.lstat() и os.rmdir(), чтобы удалить путь и его содержимое. На платформах Windows это завершается циклом ожидания, который проверяет существование файлов.

test.support.make_legacy_pyc(source)

Перемещает файл pyc PEP 3147/PEP 488 в его устаревшее расположение pyc и возвращает путь файловой системы к устаревшему pyc файлу. Значение source — это путь файловой системы к исходному файлу. Он не обязательно должен существовать, однако файл pyc PEP 3147/488 должен существовать.

test.support.is_resource_enabled(resource)

Возвращает True, если resource включён и доступен. Список доступных ресурсов устанавливается только тогда, когда test.regrtest выполняет тесты.

test.support.python_is_optimized()

Возвращает True, если Python не был собран с -O0 или -Og.

test.support.with_pymalloc()

Возврат _testcapi.WITH_PYMALLOC.

test.support.requires(resource, msg=None)

Вызывается ResourceDenied, если resource недоступен. msg является аргументом для ResourceDenied, если он вызван. Всегда возвращает True, если вызывается функцией, чей __name__ равен '__main__'. Используется, когда тесты выполняются test.regrtest.

test.support.system_must_validate_cert(f)

Вызывается unittest.SkipTest при сбоях проверки сертификации TLS.

test.support.sortdict(dict)

Возвращает repr из dict с отсортированными ключами.

test.support.findfile(filename, subdir=None)

Возвращает путь к файлу с именем filename. Если совпадений не найдено, возвращается filename. Это не означает сбой, т. к. это может быть путь к файлу.

Параметр subdir указывает относительный путь, который следует использовать для поиска файла, а не для поиска непосредственно в каталогах путей.

test.support.create_empty_file(filename)

Создаёт пустой файл с filename. Если он уже существует, усекает его.

test.support.fd_count()

Подсчитывает количество открытых файловых дескрипторов.

test.support.match_test(test)

Сопоставляет test с шаблонами, установленными в set_match_tests().

test.support.set_match_tests(patterns)

Определяет тест соответствия с регулярным выражением patterns.

test.support.run_unittest(*classes)

Выполняет unittest.TestCase подклассов, переданных функции. Функция сканирует классы на наличие методов, начинающихся с префикса test_, и выполняет тесты по отдельности.

Также допустимо передавать строки в качестве параметров; это должны быть ключи в sys.modules. Каждый связанный модуль будет просканирован unittest.TestLoader.loadTestsFromModule(). Обычно это видно в следующей функции test_main():

def test_main():
    support.run_unittest(__name__)

Данный код запустит все тесты, определённые в именованном модуле.

test.support.run_doctest(module, verbosity=None, optionflags=0)

Запускает doctest.testmod() на заданном module. Возвращает (failure_count, test_count).

Если у verbosity значение None, doctest.testmod() запускается с уровнем детализации verbose. В противном случае он запускается с подробностями, установленными на None. optionflags передаётся как optionflags в doctest.testmod().

test.support.setswitchinterval(interval)

Устанавливает sys.setswitchinterval() на заданный interval. Определяет минимальный интервал для систем Android, чтобы предотвратить зависание системы.

test.support.check_impl_detail(**guards)

Используйте эту проверку, чтобы защитить специфичные для реализации тесты CPython или запускает их только на реализациях, защищенных аргументами:

check_impl_detail()               # Только на CPython (по умолчанию).
check_impl_detail(jython=True)    # Только на Jython.
check_impl_detail(cpython=False)  # Везде, кроме CPython.
test.support.check_warnings(*filters, quiet=True)

Удобная оболочка для warnings.catch_warnings(), упрощающая проверку правильности появления предупреждения. Это примерно эквивалентно вызову warnings.catch_warnings(record=True) с warnings.simplefilter(), установленным на always, и возможностью автоматической проверки записанных результатов.

check_warnings принимает 2-кортежи формы ("message regexp", WarningCategory) в качестве позиционных аргументов. Если предоставлен один или несколько filters или если необязательный ключевой аргумент quiet равен False, он проверяет, чтобы убедиться, что предупреждения соответствуют ожиданиям: каждый указанный фильтр должен соответствовать хотя бы одному из предупреждений, выдаваемых приложенным кодом, иначе тест не пройден, и если возникают какие-либо предупреждения, которые не соответствуют ни одному из указанных фильтров, тест завершается неудачно. Чтобы отключить первую из данных проверок, устанавливает для quiet значение True.

Если аргументы не указаны, по умолчанию используется:

check_warnings(("", Warning), quiet=True)

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

При входе в менеджер контекста возвращается экземпляр WarningRecorder. Базовый список предупреждений из catch_warnings() доступен через атрибут warnings объекта записи. Для удобства атрибуты объекта, представляющего самое последнее предупреждение, также могут быть доступны непосредственно через объект записи (см. пример ниже). Если предупреждение не было выдано, то любой из атрибутов, которые в противном случае ожидались бы для объекта, представляющего предупреждение, вернёт None.

У объекта рекордера также есть метод reset(), который очищает список предупреждений.

Контекстный менеджер предназначен для использования таким образом:

with check_warnings(("assertion is always true", SyntaxWarning),
                    ("", UserWarning)):
    exec('assert(False, "Hey!")')
    warnings.warn(UserWarning("Hide me!"))

В этом случае, если предупреждение не было поднято, или было поднято какое-то другое предупреждение, check_warnings() вызовет ошибку.

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

with check_warnings(quiet=True) as w:
    warnings.warn("foo")
    assert str(w.args[0]) == "foo"
    warnings.warn("bar")
    assert str(w.args[0]) == "bar"
    assert str(w.warnings[0].args[0]) == "foo"
    assert str(w.warnings[1].args[0]) == "bar"
    w.reset()
    assert len(w.warnings) == 0

Здесь будут перехватываться все предупреждения, а тестовый код напрямую проверяет захваченные предупреждения.

Изменено в версии 3.2: Новые необязательные аргументы filters и quiet.

test.support.check_no_resource_warning(testcase)

Менеджер контекста, чтобы убедиться, что ResourceWarning не был вызван. Вы должны удалить объект, который может выдать ResourceWarning, до завершения контекстного менеджера.

test.support.set_memlimit(limit)

Устанавливает значения для max_memuse и real_max_memuse для больших тестов памяти.

test.support.record_original_stdout(stdout)

Сохраняет значение из stdout. Он предназначен для удержания стандартного вывода в момент начала regrtest.

test.support.get_original_stdout()

Возвращает исходный стандартный вывод, заданный record_original_stdout() или sys.stdout, если он не установлен.

test.support.strip_python_strerr(stderr)

Удаляет stderr процесса Python из потенциальных выходных данных отладки, выдаваемых интерпретатором. Обычно выполняется с результатом subprocess.Popen.communicate().

test.support.args_from_interpreter_flags()

Возвращает список аргументов командной строки, воспроизводящих текущие настройки в sys.flags и sys.warnoptions.

test.support.optim_args_from_interpreter_flags()

Возвращает список аргументов командной строки, воспроизводящих текущие настройки оптимизации в sys.flags.

test.support.captured_stdin()
test.support.captured_stdout()
test.support.captured_stderr()

Менеджер контекста, который временно заменяет именованный поток объектом io.StringIO.

Пример использования с выходными потоками:

with captured_stdout() as stdout, captured_stderr() as stderr:
    print("hello")
    print("error", file=sys.stderr)
assert stdout.getvalue() == "hello\n"
assert stderr.getvalue() == "error\n"

Пример использования с входным потоком:

with captured_stdin() as stdin:
    stdin.write('hello\n')
    stdin.seek(0)
    # вызывает тестовый код, который использует sys.stdin
    captured = input()
self.assertEqual(captured, "hello")
test.support.temp_dir(path=None, quiet=False)

Менеджер контекста, который создаёт временный каталог в path и возвращает каталог.

Если path равен None, временный каталог создаётся с использованием tempfile.mkdtemp(). Если quiet равен False, менеджер контекста вызывает исключение при ошибке. В противном случае, если path указан и не может быть создан, выдается только предупреждение.

test.support.change_cwd(path, quiet=False)

Менеджер контекста, который временно изменяет текущий рабочий каталог на path и возвращает каталог.

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

test.support.temp_cwd(name='tempcwd', quiet=False)

Менеджер контекста, временно создающий новый каталог и изменяет текущий рабочий каталог (CWD).

Менеджер контекста создаёт временный каталог в текущем каталоге с именем name перед временным изменением текущего рабочего каталога. Если name равен None, временный каталог создаётся с использованием tempfile.mkdtemp().

Если quiet равен False и невозможно создает или изменяет CWD, вызывается ошибка. В противном случае выдается только предупреждение и используется оригинальный CWD.

test.support.temp_umask(umask)

Контекстный менеджер, который временно устанавливает umask процесса.

test.support.transient_internet(resource_name, *, timeout=30.0, errnos=())

Менеджер контекста, который вызывает ResourceDenied, когда различные проблемы с подключением к Интернету проявляются как исключения.

test.support.disable_faulthandler()

Менеджер контекста, заменяющий sys.stderr на sys.__stderr__.

test.support.gc_collect()

Собирает как можно больше объектов. Это необходимо, поскольку сборщик мусора не гарантирует своевременное освобождение. Это означает, что методы __del__ могут вызываться позже, чем ожидалось, а слабые ссылки могут оставаться активными дольше, чем ожидалось.

test.support.disable_gc()

Менеджер контекста, отключающий сборщик мусора при входе и снова включает его при выходе.

test.support.swap_attr(obj, attr, new_val)

Менеджер контекста для замены атрибута новым объектом.

Применение:

with swap_attr(obj, "attr", 5):
    ...

Данный код установит для obj.attr значение 5 на время блока with, восстановив старое значение в конце блока. Если attr не существует в obj, он будет создан, а затем удален в конце блока.

Старое значение (или None, если оно не существует) будет присвоено цели предложения as, если оно есть.

test.support.swap_item(obj, attr, new_val)

Контекстный менеджер для замены элемента новым объектом.

Применение:

with swap_item(obj, "item", 5):
    ...

Код установит для obj["item"] значение 5 на время блока with, восстановив старое значение в конце блока. Если item не существует в obj, он будет создан, а затем удален в конце блока.

Старое значение (или None, если оно не существует) будет присвоено цели предложения as, если оно есть.

test.support.wait_threads_exit(timeout=60.0)

Менеджер контекста ожидает завершения всех потоков, созданных в операторе with.

test.support.start_threads(threads, unlock=None)

Менеджер контекста для запуска threads. Она пытается присоединиться к потокам после выхода.

test.support.calcobjsize(fmt)

Возвращает struct.calcsize() для nP{fmt}0n или, если gettotalrefcount существует, 2PnP{fmt}0P.

test.support.calcvobjsize(fmt)

Возвращает struct.calcsize() для nPn{fmt}0n или, если gettotalrefcount существует, 2PnPn{fmt}0P.

test.support.checksizeof(test, o, size)

Для тестового набора test подтверждает, что sys.getsizeof для o плюс размер заголовка сборщика мусора равно size.

Возвращает True, если ОС поддерживает символические ссылки, False в противном случае.

test.support.can_xattr()

Возвращает True, если ОС поддерживает xattr, False в противном случае.

Декоратор для запуска тестов, требующих поддержки символических ссылок.

@test.support.skip_unless_xattr

Декоратор для запуска тестов, требующих поддержки xattr.

@test.support.skip_unless_bind_unix_socket

Декоратор для запуска тестов, требующих функциональной функции bind() для сокетов Unix.

@test.support.anticipate_failure(condition)

Декоратор для условной маркировки тестов unittest.expectedFailure(). Любое использование этого декоратора должно сопровождаться комментарием, определяющим соответствующую проблему с трекером.

@test.support.run_with_locale(catstr, *locales)

Декоратор для запуска функции в другой локали, корректно сбрасывающей её после завершения. catstr — это категория локали в виде строки (например, "LC_ALL"). Переданный locales будет опробован последовательно, и будет использоваться первая допустимая локаль.

@test.support.run_with_tz(tz)

Декоратор для запуска функции в определенном часовом поясе, корректно сбрасывая её после завершения.

@test.support.requires_freebsd_version(*min_version)

Декоратор для минимальной версии при запуске теста на FreeBSD. Если версия FreeBSD ниже минимальной, вызывается unittest.SkipTest.

@test.support.requires_linux_version(*min_version)

Декоратор для минимальной версии при запуске теста в Linux. Если версия Linux меньше минимальной, вызывается unittest.SkipTest.

@test.support.requires_mac_version(*min_version)

Декоратор для минимальной версии при запуске теста в Mac OS X. Если версия MAC OS X меньше минимальной, вызывается unittest.SkipTest.

@test.support.requires_IEEE_754

Декоратор для пропуска тестов на платформах, отличных от IEEE 754.

@test.support.requires_zlib

Декоратор для пропуска тестов, если zlib не существует.

@test.support.requires_gzip

Декоратор для пропуска тестов, если gzip не существует.

@test.support.requires_bz2

Декоратор для пропуска тестов, если bz2 не существует.

@test.support.requires_lzma

Декоратор для пропуска тестов, если lzma не существует.

@test.support.requires_resource(resource)

Декоратор для пропуска тестов, если resource недоступен.

@test.support.requires_docstrings

Декоратор только для запуска теста, если HAVE_DOCSTRINGS.

@test.support.cpython_only(test)

Декоратор для тестов применим только к CPython.

@test.support.impl_detail(msg=None, **guards)

Декоратор для вызова check_impl_detail() на guards. Если это возвращает False, то использует msg в качестве причины пропуска теста.

@test.support.no_tracing(func)

Декоратор для временного отключения трассировки на время теста.

@test.support.refcount_test(test)

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

@test.support.reap_threads(func)

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

@test.support.bigmemtest(size, memuse, dry_run=True)

Декоратор для bigmem тестов.

size — запрошенный размер для теста (в произвольных, интерпретируемых тестом единицах). memuse — кол-во байтов на единицу для теста или его хорошая оценка. Например, тест, которому нужны два байтовых буфера по 4 ГиБ каждый, может быть декорирован @bigmemtest(size=_4G, memuse=2).

Аргумент size обычно передаётся декорированному тестовому методу в качестве дополнительного аргумента. Если dry_run равен True, значение, переданное методу тестирования, может быть меньше запрошенного значения. Если dry_run равен False, это означает, что тест не поддерживает фиктивные прогоны, если -M не указан.

@test.support.bigaddrspacetest(f)

Декоратор для тестов, заполняющих адресное пространство. f — это функция для переноса.

test.support.make_bad_fd()

Создаёт недопустимый дескриптор файла, открыв и закрыв временный файл и вернув его дескриптор.

test.support.check_syntax_error(testcase, statement, errtext='', *, lineno=None, offset=None)

Проверяет наличие синтаксических ошибок в statement, пытаясь скомпилировать statement. testcase — экземпляр unittest для теста. errtext — это регулярное выражение, которое должно соответствовать строковому представлению поднятого SyntaxError. Если lineno не является None, сравнивается со строкой исключения. Если offset не является None, сравнивается со смещением исключения.

test.support.check_syntax_warning(testcase, statement, errtext='', *, lineno=1, offset=None)

Проверяет наличие предупреждения о синтаксисе в statement, пытаясь скомпилировать statement. Проверяет также, что SyntaxWarning генерируется только один раз и что он будет преобразован в SyntaxError при преобразовании в ошибку. testcase — экземпляр unittest для теста. errtext — это регулярное выражение, которое должно соответствовать строковому представлению сгенерированного SyntaxWarning и поднятого SyntaxError. Если lineno не None, сравнивается со строкой предупреждения и исключения. Если offset не является None, сравнивается со смещением исключения.

Добавлено в версии 3.8.

test.support.open_urlresource(url, *args, **kw)

Открывает url. Если открывает не удается, вызывает TestFailed.

test.support.import_module(name, deprecated=False, *, required_on())

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

Сообщения об устаревании модулей и пакетов подавляются во время этого импорта, если deprecated равен True. Если модуль требуется на платформе, но необязателен для других, устанавливает required_on в итерацию префиксов платформы, которые будут сравниваться с sys.platform.

Добавлено в версии 3.1.

test.support.import_fresh_module(name, fresh=(), blocked=(), deprecated=False)

Данная функция импортирует и возвращает новую копию именованного модуля Python, удаляя именованный модуль из sys.modules перед выполнением импорта. Обратите внимание, что в отличие от reload(), исходный модуль не затрагивается этой операцией.

fresh — это итерация имён дополнительных модулей, которые также удаляются из кэша sys.modules перед выполнением импорта.

blocked — это итерация имён модулей, которые заменяются на None в кэше модулей во время импорта, чтобы гарантировать, что попытки импортирует их вызовут ImportError.

Именованный модуль и любые модули, названные в параметрах fresh и blocked, сохраняются перед началом импорта, а затем повторно вставляются в sys.modules после завершения нового импорта.

Сообщения об устаревании модулей и пакетов подавляются во время этого импорта, если deprecated равен True.

Данная функция вызовет ImportError, если именованный модуль не может быть импортирован.

Пример использования:

# Получении копии модуля предупреждений для тестирования, не влияя на
# версию, используемая остальной частью набора тестов. В одном экземпляре используется
# C реализацией, другой вынужден использовать запасной вариант на чистой Python
# реализации
py_warnings = import_fresh_module('warnings', blocked=['_warnings'])
c_warnings = import_fresh_module('warnings', fresh=['_warnings'])

Добавлено в версии 3.1.

test.support.modules_setup()

Возвращает копию sys.modules.

test.support.modules_cleanup(oldmodules)

Удаляет модули, кроме oldmodules и encodings, чтобы сохраняет внутренний кеш.

test.support.threading_setup()

Возвращает текущее количество потоков и копию оборванных потоков.

test.support.threading_cleanup(*original_values)

Очистка потоков, не указанных в original_values. Предназначен для выдачи предупреждения, если тест оставляет запущенные потоки в фоновом режиме.

test.support.join_thread(thread, timeout=30.0)

Присоединяется к thread в timeout. Вызывается AssertionError, если поток все ещё жив после timeout секунд.

test.support.reap_children()

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

test.support.get_attribute(obj, name)

Получает атрибут, вызывая unittest.SkipTest, если вызвано AttributeError.

test.support.bind_port(sock, host=HOST)

Привязывает сокет к свободному порту, и возвращает номер порта. Полагается на эфемерные порты, чтобы гарантировать, что мы используем несвязанный порт. Это важно, т. к. многие тесты могут выполняться одновременно, особенно в среде buildbot. Данный метод вызывает исключение, если sock.family — это AF_INET, а sock.type — это SOCK_STREAM, а для сокета установлено значение SO_REUSEADDR или SO_REUSEPORT. Тесты никогда не должны устанавливать данные параметры сокета для сокетов TCP/IP. Единственный случай установки данных параметров — тестирование многоадресной рассылки через несколько сокетов UDP.

Кроме того, если доступен параметр сокета SO_EXCLUSIVEADDRUSE (например, в Windows), он будет установлен для сокета. Это предотвратит привязку кого-либо ещё к нашему хосту/порту на время теста.

test.support.bind_unix_socket(sock, addr)

Привязка unix сокета, вызвав unittest.SkipTest, если вызвано PermissionError.

test.support.catch_threading_exception()

Менеджер контекста перехватывает исключение threading.Thread, используя threading.excepthook().

Атрибуты устанавливаются при перехвате исключения:

  • exc_type
  • exc_value
  • exc_traceback
  • thread

См. документацию threading.excepthook().

Данные атрибуты удаляются при выходе из контекстного менеджера.

Применение:

with support.catch_threading_exception() as cm:
    # порождающий поток код, вызывающий исключение
    ...

    # проверяет исключение потока, используются атрибуты cm:
    # exc_type, exc_value, exc_traceback, thread
    ...

# exc_type, exc_value, exc_traceback, thread атрибуты cm больше не
# существует на данный момент
# (чтобы избежать ссылочных циклов)

Добавлено в версии 3.8.

test.support.catch_unraisable_exception()

Менеджер контекста перехватывает необработанное исключение с помощью sys.unraisablehook().

Сохранение значения исключения (cm.unraisable.exc_value) создаёт ссылочный цикл. Ссылочный цикл прерывается явным образом при выходе из менеджера контекста.

Сохранение объекта (cm.unraisable.object) может воскресить его, если он установлен на объект, который завершается. Выход из менеджера контекста очищает сохраненный объект.

Применение:

with support.catch_unraisable_exception() as cm:
    # код, создающий "неразрешимое исключение"
    ...

    # проверяет неразрешимое исключение: используйте cm.unraisable
    ...

# cm.unraisable атрибут больше не существует на данный момент
# (разорвать ссылочный цикл)

Добавлено в версии 3.8.

test.support.find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM)

Возвращает неиспользуемый порт, подходящий для привязки. Это достигается путём создания временного сокета с тем же семейством и типом, что и параметр sock (по умолчанию AF_INET, SOCK_STREAM), и привязкой его к указанному адресу хоста (по умолчанию 0.0.0.0) с портом, установленным на 0, вызывая неиспользуемый эфемерный порт из ОС. Затем временный сокет закрывается и удаляется, а эфемерный порт возвращается.

Либо данный метод, либо bind_port() следует использовать для любых тестов, где сокет сервера должен быть привязан к определенному порту на время теста. Какой из них использовать, зависит от того, создаёт ли вызывающий код сокет Python или неиспользуемый порт должен быть предоставлен в конструкторе или передан внешней программе (например, аргумент -accept для режима s_server openssl). Всегда предпочтительнее bind_port(), чем find_unused_port(), где это возможно. Использование жестко закодированного порта не рекомендуется, поскольку это может сделать невозможным одновременный запуск нескольких экземпляров теста, что является проблемой для билдботов.

test.support.load_package_tests(pkg_dir, loader, standard_tests, pattern)

Общая реализация протокола unittest load_tests для использования в тестовых пакетах. pkg_dir — корневой каталог пакета; loader, standard_tests и pattern — аргументы, ожидаемые load_tests. В простых случаях __init__.py пакета test может быть следующим:

import os
from test.support import load_package_tests

def load_tests(*args):
    return load_package_tests(os.path.dirname(__file__), *args)
test.support.fs_is_case_insensitive(directory)

Возвращает True, если файловая система для directory нечувствительна к регистру.

test.support.detect_api_mismatch(ref_api, other_api, *, ignore=())

Возвращает множество атрибутов, функций или методов ref_api, не найденных в other_api, за исключением определённого списка элементов, которые следует игнорировать при этой проверке, указанного в ignore.

По умолчанию это пропускает приватные атрибуты, начинающиеся с «_», но включает все магические методы, т. е. те, которые начинаются и заканчиваются на «__».

Добавлено в версии 3.5.

test.support.patch(test_instance, object_to_patch, attr_name, new_value)

Заменяет object_to_patch.attr_name на new_value. Также добавляет процедуру очистки в test_instance, чтобы восстановить object_to_patch для attr_name. attr_name должен быть допустимым атрибутом для object_to_patch.

test.support.run_in_subinterp(code)

Запускает code в субинтерпретаторе. Вызывается unittest.SkipTest, если tracemalloc включён.

test.support.check_free_after_iterating(test, iter, cls, args=())

Утверждает, что iter освобождается после итерации.

test.support.missing_compiler_executable(cmd_names=[])

Проверяет наличие исполняемых файлов компилятора, имена которых перечислены в cmd_names, или всех исполняемых файлов компилятора, если cmd_names пуст, и возвращает первый отсутствующий исполняемый файл или None, если ни один из них не обнаружен.

test.support.check__all__(test_case, module, name_of_module=None, extra=(), blacklist=())

Утверждает, что переменная __all__ module содержит все общедоступные имена.

Общедоступные имена модуля (его API) определяются автоматически на основе того, соответствуют ли они соглашению об общедоступных именах и были определены в module.

Аргумент name_of_module может указывать (в виде строки или её кортежа), какой модуль (модули) API может быть определён, чтобы быть обнаруженным как общедоступный API. Одним из таких случаев является то, что module импортирует часть своего общедоступного API из других модулей, возможно, из бэкэнда C (например, csv и его _csv).

Аргумент extra может быть набором имён, которые в противном случае не были бы автоматически определены как «общедоступные», например объекты без надлежащего атрибута __module__. Если он предоставлен, он будет добавлен к автоматически обнаруженным.

Аргумент blacklist может быть набором имён, которые не должны рассматриваться как часть общедоступного API, даже если их имена указывают на обратное.

Пример использования:

import bar
import foo
import unittest
from test import support

class MiscTestCase(unittest.TestCase):
    def test__all__(self):
        support.check__all__(self, foo)

class OtherTestCase(unittest.TestCase):
    def test__all__(self):
        extra = {'BAR_CONST', 'FOO_CONST'}
        blacklist = {'baz'}  # Недокументированное имя.
        # bar импортирует часть своего API из _bar.
        support.check__all__(self, bar, ('bar', '_bar'),
                             extra=extra, blacklist=blacklist)

Добавлено в версии 3.6.

Модуль test.support определяет следующие классы:

class test.support.TransientResource(exc, **kwargs)

Экземпляры — это менеджер контекста, который вызывает ResourceDenied, если вызывается указанный тип исключения. Любые ключевые аргументы обрабатываются как пары атрибут/значение для сравнения с любым исключением, вызванным в операторе with. Только если все пары правильно совпадают с атрибутами в исключении, вызывается ResourceDenied.

class test.support.EnvironmentVarGuard

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

Изменено в версии 3.1: Добавлен интерфейс словаря.

EnvironmentVarGuard.set(envvar, value)

Временно устанавливает для переменной среды envvar значение value.

EnvironmentVarGuard.unset(envvar)

Временно отключает переменную среды envvar.

class test.support.SuppressCrashReport

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

В Windows он отключает диалоговые окна отчетов об ошибках Windows с помощью SetErrorMode.

В UNIX resource.setrlimit() используется для установки мягкого ограничения resource.RLIMIT_CORE на 0, чтобы предотвратить создание файла дампа памяти.

На обеих платформах старое значение восстанавливается по __exit__().

class test.support.CleanImport(*module_names)

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

with CleanImport('foo'):
    importlib.import_module('foo')  # Новая ссылка.
class test.support.DirsOnSysPath(*paths)

Менеджер контекста для временного добавления каталогов в sys.path.

Это создаёт копию sys.path, добавляет любые каталоги, указанные в качестве позиционных аргументов, а затем возвращает sys.path к скопированным настройкам, когда контекст заканчивается.

Обратите внимание, что все изменения sys.path в теле контекстного менеджера, включая замену объекта, будут отменены в конце блока.

class test.support.SaveSignals

Класс для сохранения и восстановления обработчиков сигналов, зарегистрированных обработчиком сигналов Python.

class test.support.Matcher
matches(self, d, **kwargs)

Пытается сопоставить один словарь с предоставленными аргументами.

match_value(self, k, dv, v)

Пытается сопоставить одно сохраненное значение (dv) с предоставленным значением (v).

class test.support.WarningsRecorder

Класс, используемый для записи предупреждений для модульных тестов. Дополнительные сведения см. в документации check_warnings() выше.

class test.support.BasicTestRunner
run(test)

Запускает test и возвращает результат.

class test.support.TestHandler(logging.handlers.BufferingHandler)

Класс для поддержки журналирования.

class test.support.FakePath(path)

Простой путеподобный объект. Он реализует метод __fspath__(), который просто возвращает аргумент path. Если path является исключением, он будет вызван в __fspath__().

test.support.script_helper — Утилиты для выполнения тестов Python

Модуль test.support.script_helper обеспечивает поддержку тестов выполнения сценариев Python.

test.support.script_helper.interpreter_requires_environment()

Возвращает True, если sys.executable interpreter требует переменных среды, чтобы иметь возможность работать вообще.

Она предназначена для использования с @unittest.skipIf() для аннотирования тестов, которые должны использовать функцию assert_python*() для запуска процесса субинтерпретатора в изолированном режиме (-I) или без режима среды (-E).

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

Установка PYTHONHOME — это один из способов заставить большую часть набора тестов работать в такой ситуации. PYTHONPATH или PYTHONUSERSITE — другие распространенные переменные среды, которые могут повлиять на запуск интерпретатора.

test.support.script_helper.run_python_until_end(*args, **env_vars)

Настраивает среду на основе env_vars для запуска интерпретатора в подпроцессе. Значения могут включать __isolated, __cleanenv, __cwd и TERM.

test.support.script_helper.assert_python_ok(*args, **env_vars)

Подтверждает, что запуск интерпретатора с args и необязательными переменными среды env_vars выполнен успешно (rc == 0) и возвращает кортеж (return code, stdout, stderr).

Если задано ключевой аргумент __cleanenv, в качестве новой среды используется env_vars.

Python запускается в изолированном режиме (параметр командной строки -I), за исключением случаев, когда для ключевого слова __isolated установлено значение False.

test.support.script_helper.assert_python_failure(*args, **env_vars)

Подтверждает, что запуск интерпретатора с args и необязательными переменными среды env_vars завершится ошибкой (rc != 0) и вернёт кортеж (return code, stdout, stderr).

Дополнительные параметры см. в assert_python_ok().

test.support.script_helper.spawn_python(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw)

Запускает подпроцесс Python с заданными аргументами.

kw — это дополнительные ключевые аргументы для перехода к subprocess.Popen(). Возвращает объект subprocess.Popen.

test.support.script_helper.kill_python(p)

Запускает данный процесс subprocess.Popen до завершения и возвращает стандартный вывод.

test.support.script_helper.make_script(script_dir, script_basename, source, omit_suffix=False)

Создаёт скрипт, содержащий source в пути script_dir и script_basename. Если omit_suffix — это False, добавляет к имени .py. Возвращает полный путь к скрипту.

test.support.script_helper.make_zip_script(zip_dir, zip_basename, script_name, name_in_zip=None)

Создаёт zip-файл в zip_dir и zip_basename с расширением zip, который содержит файлы в script_name. name_in_zip — имя архива. Возвращает кортеж, содержащий (full path, full path of archive name).

test.support.script_helper.make_pkg(pkg_dir, init_source='')

Создаёт каталог с именем pkg_dir, содержащий файл __init__ с содержимым init_source.

test.support.script_helper.make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, source, depth=1, compiled=False)

Создаёт каталог zip-пакета с путём zip_dir и zip_basename, содержащий пустой файл __init__ и файл script_basename, содержащий source. Если compiled равен True, оба исходных файла будут скомпилированы и добавлены в zip-пакет. Возвращает кортеж из полного zip-пути и имени архива для zip-файла.