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 function returns only True or False). Это делается потому, что строки документации распечатываются, если они существуют, и таким образом не указывается, какой тест выполняется.

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

import unittest
from test import support

class MyTestCase1(unittest.TestCase):

    # Only use setUp() and tearDown() if necessary

    def setUp(self):
        ... code to execute in preparation for tests ...

    def tearDown(self):
        ... code to execute to clean up after tests ...

    def test_feature_one(self):
        # Test feature one.
        ... testing code ...

    def test_feature_two(self):
        # Test feature two.
        ... testing code ...

    ... more test methods ...

class MyTestCase2(unittest.TestCase):
    ... same structure as MyTestCase1 ...

... more test classes ...

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

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

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

  • Набор тестов должен проверять все классы, функции и константы. Сюда входит не только внешний 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.LOOPBACK_TIMEOUT

Таймаут в секундах для тестов, использующих сетевой сервер, прослушивающий локальный петлевой интерфейс сети, например 127.0.0.1.

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

Таймаут должен быть достаточно длинным для методов connect(), recv() и send() из socket.socket.

Его значение по умолчанию - 5 секунд.

См. также INTERNET_TIMEOUT.

test.support.INTERNET_TIMEOUT

Тайм-аут в секундах для сетевых запросов, идущих в Интернет.

Таймаут достаточно короткий, чтобы тест не ждал слишком долго, если интернет-запрос заблокирован по какой-либо причине.

Обычно таймаут, использующий INTERNET_TIMEOUT, не должен помечать тест как неудачный, а пропускать его: см. transient_internet().

Его значение по умолчанию - 1 минута.

См. также LOOPBACK_TIMEOUT.

test.support.SHORT_TIMEOUT

Таймаут в секундах для отметки теста как неудачного, если тест длится «слишком долго».

Значение тайм-аута зависит от опции командной строки regrtest --timeout.

Если тест, использующий SHORT_TIMEOUT, начинает беспорядочно выходить из строя на медленных билдботах, используйте вместо него LONG_TIMEOUT.

Его значение по умолчанию - 30 секунд.

test.support.LONG_TIMEOUT

Тайм-аут в секундах для определения момента зависания теста.

Он достаточно длинный, чтобы снизить риск провала теста на самых медленных билдботах Python. Его не следует использовать для пометки теста как неудачного, если тест длится «слишком долго». Значение тайм-аута зависит от опции командной строки regrtest --timeout.

Значение по умолчанию - 5 минут.

См. также LOOPBACK_TIMEOUT, INTERNET_TIMEOUT и SHORT_TIMEOUT.

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.support.TEST_DATA_DIR

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

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, если Python собран без документальных строк (макрос WITH_DOC_STRINGS не определен). См. опцию configure --without-doc-strings.

См. также переменную HAVE_DOCSTRINGS.

test.support.HAVE_DOCSTRINGS

Установите значение True, если доступны докстринги функций. См. опцию python -OO, которая удаляет документацию функций, реализованных в Python.

См. также переменную MISSING_C_DOCSTRINGS.

test.support.TEST_HTTP_URL

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

test.support.ALWAYS_EQ

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

test.support.NEVER_EQ

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

test.support.LARGEST

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

test.support.SMALLEST

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

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

test.support.is_resource_enabled(resource)

Возвращает True, если ресурс включен и доступен. Список доступных ресурсов устанавливается только тогда, когда 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, если ресурс недоступен. msg является аргументом для ResourceDenied, если она вызвана. Всегда возвращает True, если вызывается функцией, чьим __name__ является '__main__'. Используется, когда тесты выполняются test.regrtest.

test.support.sortdict(dict)

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

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

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

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

test.support.match_test(test)

Определите, соответствует ли test шаблонам, заданным в set_match_tests().

test.support.set_match_tests(accept_patterns=None, ignore_patterns=None)

Определите шаблоны соответствия имен файлов тестов и имен методов тестирования для фильтрации тестов.

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() на заданном модуле. Возврат (failure_count, test_count).

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

test.support.setswitchinterval(interval)

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

test.support.check_impl_detail(**guards)

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

check_impl_detail()               # Only on CPython (default).
check_impl_detail(jython=True)    # Only on Jython.
check_impl_detail(cpython=False)  # Everywhere except CPython.
test.support.set_memlimit(limit)

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

test.support.record_original_stdout(stdout)

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

test.support.get_original_stdout()

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

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)
    # call test code that consumes from sys.stdin
    captured = input()
self.assertEqual(captured, "hello")
test.support.disable_faulthandler()

Менеджер контекста, который временно отключает faulthandler.

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.print_warning(msg)

Выведите предупреждение в sys.__stderr__. Отформатируйте сообщение как: f"Warning -- {msg}". Если msg состоит из нескольких строк, добавьте префикс "Warning -- " к каждой строке.

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

test.support.wait_process(pid, *, exitcode, timeout=None)

Дождитесь завершения процесса pid и проверьте, что код завершения процесса равен exitcode.

Вызывает сообщение AssertionError, если код выхода процесса не равен exitcode.

Если процесс выполняется дольше timeout секунд (SHORT_TIMEOUT по умолчанию), завершите процесс и выдайте сообщение AssertionError. Функция таймаута недоступна в Windows.

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

test.support.calcobjsize(fmt)

Возвращает размер PyObject, члены структуры которого определены fmt. Возвращаемое значение включает размер заголовка объекта Python и выравнивание.

test.support.calcvobjsize(fmt)

Возвращает размер PyVarObject, члены структуры которого определены fmt. Возвращаемое значение включает размер заголовка объекта Python и выравнивание.

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

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

@test.support.anticipate_failure(condition)

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

test.support.system_must_validate_cert(f)

Декоратор, который пропускает декорированный тест при ошибках проверки сертификации TLS.

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

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

@test.support.run_with_tz(tz)

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

@test.support.requires_freebsd_version(*min_version)

Декоратор для минимальной версии при запуске теста на FreeBSD. Если версия FreeBSD меньше минимальной, тест будет пропущен.

@test.support.requires_linux_version(*min_version)

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

@test.support.requires_mac_version(*min_version)

Декоратор для минимальной версии при запуске теста на macOS. Если версия macOS меньше минимальной, тест будет пропущен.

@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)

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

@test.support.requires_docstrings

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

@test.support.cpython_only

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

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

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

@test.support.no_tracing

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

@test.support.refcount_test

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

@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

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

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

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

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

Открыть url. При неудачном открытии выдает сообщение TestFailed.

test.support.reap_children()

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

test.support.get_attribute(obj, name)

Получить атрибут, поднимая unittest.SkipTest, если поднимается AttributeError.

test.support.catch_unraisable_exception()

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

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

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

Использование:

with support.catch_unraisable_exception() as cm:
    # code creating an "unraisable exception"
    ...

    # check the unraisable exception: use cm.unraisable
    ...

# cm.unraisable attribute no longer exists at this point
# (to break a reference cycle)

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

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

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

import os
from test.support import load_package_tests

def load_tests(*args):
    return load_package_tests(os.path.dirname(__file__), *args)
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)

Выполнить код в субинтерпретаторе. Поднять unittest.SkipTest, если включено tracemalloc.

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

Убедитесь, что экземпляры cls удаляются после итерации.

test.support.missing_compiler_executable(cmd_names=[])

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

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

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

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

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

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

Аргумент not_exported может быть набором имен, которые не должны рассматриваться как часть общедоступного 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'}
        not_exported = {'baz'}  # Undocumented name.
        # bar imports part of its API from _bar.
        support.check__all__(self, bar, ('bar', '_bar'),
                             extra=extra, not_exported=not_exported)

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

test.support.skip_if_broken_multiprocessing_synchronize()

Пропустите тесты, если отсутствует модуль multiprocessing.synchronize, если нет доступной реализации семафора или если создание блокировки вызывает ошибку OSError.

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

test.support.check_disallow_instantiation(test_case, tp, *args, **kwds)

Утверждение, что тип tp не может быть инстанцирован с помощью args и kwds.

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

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

class test.support.SuppressCrashReport

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

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

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

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

class test.support.SaveSignals

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

save(self)

Сохраните обработчики сигналов в словарь, сопоставляющий номера сигналов с текущим обработчиком сигналов.

restore(self)

Установите номера сигналов из словаря save() в сохраненный обработчик.

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

Попытайтесь найти соответствие между одним диктом и заданными аргументами.

match_value(self, k, dv, v)

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

class test.support.BasicTestRunner
run(test)

Выполните тест и верните результат.

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

Модуль test.support.socket_helper обеспечивает поддержку тестов сокетов.

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

test.support.socket_helper.IPV6_ENABLED

Устанавливается в True, если IPv6 включен на этом хосте, False в противном случае.

test.support.socket_helper.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.socket_helper.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.socket_helper.bind_unix_socket(sock, addr)

Связывает unix-сокет, поднимая unittest.SkipTest, если поднимается PermissionError.

@test.support.socket_helper.skip_unless_bind_unix_socket

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

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

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

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.

Изменено в версии 3.9: Функция больше не удаляет пробельные символы из stderr.

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

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

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

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

Изменено в версии 3.9: Функция больше не удаляет пробельные символы из stderr.

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

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

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

Изменено в версии 3.9: Функция больше не удаляет пробельные символы из stderr.

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

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

kw - дополнительное ключевое слово args для передачи в subprocess.Popen(). Возвращает объект subprocess.Popen.

test.support.script_helper.kill_python(p)

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

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, который содержит файлы в имя_скрипта. 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-файла.

test.support.bytecode_helper — Поддержка инструментов для тестирования правильности генерации байткода

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

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

Модуль определяет следующий класс:

class test.support.bytecode_helper.BytecodeTestCase(unittest.TestCase)

Этот класс имеет пользовательские методы утверждения для проверки байткода.

BytecodeTestCase.get_disassembly_as_string(co)

Возвращает разборку co в виде строки.

BytecodeTestCase.assertInBytecode(x, opname, argval=_UNSPECIFIED)

Возвращает instr, если opname найдено, иначе бросает AssertionError.

BytecodeTestCase.assertNotInBytecode(x, opname, argval=_UNSPECIFIED)

Выбрасывает AssertionError, если найдено opname.

test.support.threading_helper — Утилиты для потоковых тестов

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

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

test.support.threading_helper.join_thread(thread, timeout=None)

Присоединиться к потоку в течение timeout. Поднять AssertionError, если поток все еще жив после timeout секунд.

@test.support.threading_helper.reap_threads

Декоратор для обеспечения очистки потоков даже в случае неудачи теста.

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

Контекстный менеджер для запуска threads, который представляет собой последовательность потоков. unlock - это функция, вызываемая после запуска потоков, даже если возникло исключение; примером может служить threading.Event.set(). start_threads будет пытаться присоединиться к запущенным потокам после выхода.

test.support.threading_helper.threading_cleanup(*original_values)

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

test.support.threading_helper.threading_setup()

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

test.support.threading_helper.wait_threads_exit(timeout=None)

Менеджер контекста подождет, пока все потоки, созданные в операторе with, выйдут.

test.support.threading_helper.catch_threading_exception()

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

Атрибуты, устанавливаемые при возникновении исключения:

  • exc_type

  • exc_value

  • exc_traceback

  • thread

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

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

Использование:

with threading_helper.catch_threading_exception() as cm:
    # code spawning a thread which raises an exception
    ...

    # check the thread exception, use cm attributes:
    # exc_type, exc_value, exc_traceback, thread
    ...

# exc_type, exc_value, exc_traceback, thread attributes of cm no longer
# exists at this point
# (to avoid reference cycles)

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

test.support.os_helper — Утилиты для os-тестов

Модуль test.support.os_helper обеспечивает поддержку тестов os.

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

test.support.os_helper.FS_NONASCII

Символ не ASCII, который можно закодировать с помощью os.fsencode().

test.support.os_helper.SAVEDCWD

Установите значение os.getcwd().

test.support.os_helper.TESTFN

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

test.support.os_helper.TESTFN_NONASCII

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

test.support.os_helper.TESTFN_UNENCODABLE

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

test.support.os_helper.TESTFN_UNDECODABLE

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

test.support.os_helper.TESTFN_UNICODE

Устанавливается на имя временного файла, не являющееся именем в формате ASCII.

class test.support.os_helper.EnvironmentVarGuard

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

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

class test.support.os_helper.FakePath(path)

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

EnvironmentVarGuard.set(envvar, value)

Временно установите переменную окружения envvar в значение value.

EnvironmentVarGuard.unset(envvar)

Временно снимите значение переменной окружения envvar.

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

test.support.os_helper.can_xattr()

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

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

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

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

test.support.os_helper.create_empty_file(filename)

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

test.support.os_helper.fd_count()

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

test.support.os_helper.fs_is_case_insensitive(directory)

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

test.support.os_helper.make_bad_fd()

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

test.support.os_helper.rmdir(filename)

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

test.support.os_helper.rmtree(path)

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

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

@test.support.os_helper.skip_unless_xattr

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

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

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

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

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

test.support.os_helper.temp_dir(path=None, quiet=False)

Контекстный менеджер, который создает временный каталог по адресу path и выдает этот каталог.

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

test.support.os_helper.temp_umask(umask)

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

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

test.support.import_helper — Утилиты для тестирования импорта

Модуль test.support.import_helper обеспечивает поддержку тестов импорта.

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

test.support.import_helper.forget(module_name)

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

test.support.import_helper.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, если именованный модуль не может быть импортирован.

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

# Get copies of the warnings module for testing without affecting the
# version being used by the rest of the test suite. One copy uses the
# C implementation, the other is forced to use the pure Python fallback
# implementation
py_warnings = import_fresh_module('warnings', blocked=['_warnings'])
c_warnings = import_fresh_module('warnings', fresh=['_warnings'])

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

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

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

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

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

test.support.import_helper.modules_setup()

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

test.support.import_helper.modules_cleanup(oldmodules)

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

test.support.import_helper.unload(name)

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

test.support.import_helper.make_legacy_pyc(source)

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

class test.support.import_helper.CleanImport(*module_names)

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

with CleanImport('foo'):
    importlib.import_module('foo')  # New reference.
class test.support.import_helper.DirsOnSysPath(*paths)

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

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

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

test.support.warnings_helper — Утилиты для проверки предупреждений

Модуль test.support.warnings_helper обеспечивает поддержку тестов предупреждений.

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

test.support.warnings_helper.check_no_resource_warning(testcase)

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

test.support.warnings_helper.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.warnings_helper.check_warnings(*filters, quiet=True)

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

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

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

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

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

При входе в контекстный менеджер возвращается экземпляр WarningRecorder. Основной список предупреждений из catch_warnings() доступен через атрибут warnings объекта recorder. Для удобства атрибуты объекта, представляющего самое последнее предупреждение, также могут быть доступны непосредственно через объект recorder (см. пример ниже). Если предупреждение не было вызвано, то любой из атрибутов, которые в противном случае ожидались бы для объекта, представляющего предупреждение, вернет 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.

class test.support.warnings_helper.WarningsRecorder

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

Вернуться на верх