Глава 13. Комплект тестов

CPython обладает устойчивым комплектом тестирования, охватывающим собственно ядро интерпретатора, его стандартную библиотеку , имеющиеся инструменты и сам дистрибутив для Windows, Linux и macOS. Он располагается в Lib/test и написан в основном на Python. Весь комплект тестирования является пакетом Python, а потому вы можете исполнить его применяя тот интерпретатор Python, который вы скомпилировали.

Выполнение комплекта тестов в Windows

В Windows воспользуйтесь сценарием rt.bat внутри папки PCBuild. Например, вот как запустить быстрый режим для конфигурации с отладкой в архитектуре x64:


> cd PCbuild
> rt.bat -q -d -x64

== CPython 3.9
== Windows-10-10.0.17134-SP0 little-endian
== cwd: C:\repos\cpython\build\test_python_2784
== CPU count: 2
== encodings: locale=cp1252, FS=utf-8
Run tests sequentially
0:00:00 [  1/420] test_grammar
0:00:00 [  2/420] test_opcodes
0:00:00 [  3/420] test_dict
0:00:00 [  4/420] test_builtin
		

Для запуска возвратного комплекса тестов для конфигурации выпуска (Release), удалите флаг -d из командной строки.

Выполнение комплекта тестов в Linux или macOS

В Linux и macOS исполните цель test make для компиляции и запустите тесты:


$ make test
== CPython 3.9
== macOS-10.14.3-x86_64-i386-64bit little-endian
== cwd: /Users/anthonyshaw/cpython/build/test_python_23399
== CPU count: 4
== encodings: locale=UTF-8, FS=utf-8
0:00:00 load avg: 2.14 [  1/420] test_opcodes passed
0:00:00 load avg: 2.14 [  2/420] test_grammar passed
		

В качестве альтернативы воспользуйтесь путём скомпилированного исполняемого файла python или python.exe с пакетом python:


$ ./python -m test
== CPython 3.9
== macOS-10.14.3-x86_64-i386-64bit little-endian
== cwd: /Users/anthonyshaw/cpython/build/test_python_23399
== CPU count: 4
== encodings: locale=UTF-8, FS=utf-8
0:00:00 load avg: 2.14 [  1/420] test_opcodes passed
0:00:00 load avg: 2.14 [  2/420] test_grammar passed
...
		

Вот дополнительные цели make для тестов:

Таблица 13-1. Цели тестирования для make
Цель Назначение

test

Запустить базовый набор тестов возврата

testall

Выполнить полный комплект тестов дважды - один раз без файлов .pyc, второй раз с ними

quicktest

Исполнить более быстрое возвратное тестирование, исключая те тесты, которые занимают много времени

testuniversal

Запуск комплекта тестов для osX для обеих архитектур в универсальной сборке

coverage

Скомпилировать и запустить тесты с gcov

coverage-lcov

Создать отчёты HTML областей действия

Флаги теста

Некоторые тесты требуют определённые флаги, либо они будут пропущены. Например, многие из тестов IDLE требуют GUI.

Чтобы просмотреть список комплектов тестов в вашей конфигурации воспользуйтесь флагом --list-tests:


./python -m test --list-tests

test_grammar
test_opcodes
test_dict
test_builtin
test_exceptions
...
		

Исполнение особых тестов

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

Вот некий пример для Linux и macOS:


$ ./python -m test test_webbrowser

Run tests sequentially
0:00:00 load avg: 2.74 [1/1] test_webbrowser

== Tests result: SUCCESS ==

1 test OK.

Total duration: 117 ms
Tests result: SUCCESS
		

Вот пример в Windows:


> rt.bat -q -d -x64 test_webbrowser
		

Вы также можете просмотреть подробный список исполненных тестов совместно с их результатами, воспользовавшись аргументом -v:


$ ./python -m test test_webbrowser -v

== CPython 3.9 
== macOS-10.14.3-x86_64-i386-64bit little-endian
== cwd: /Users/anthonyshaw/cpython/build/test_python_24562
== CPU count: 4
== encodings: locale=UTF-8, FS=utf-8
Run tests sequentially
0:00:00 load avg: 2.36 [1/1] test_webbrowser
test_open (test.test_webbrowser.BackgroundBrowserCommandTest) ...ok
test_register (test.test_webbrowser.BrowserRegistrationTest) ...ok
test_register_default (test.test_webbrowser.BrowserRegistrationTest) ...ok
test_register_preferred (test.test_webbrowser.BrowserRegistrationTest) ...ok
test_open (test.test_webbrowser.ChromeCommandTest) ...ok
test_open_new (test.test_webbrowser.ChromeCommandTest) ...ok
...
test_open_with_autoraise_false (test.test_webbrowser.OperaCommandTest) ...ok

----------------------------------------------------------------------

Ran 34 tests in 0.056s

OK (skipped=2)

== Tests result: SUCCESS ==

1 test OK.

Total duration: 134 ms
Tests result: SUCCESS
		

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

Модули тестирования

Для расширений C или модулей Python вы можете импортировать их и провести тестирование применяя модуль unittest. Тесты собираются по модулям или пакетам.

Например, тип строк Unicode Python обладает тестами в Lib.test.test_unicode.py. Пакет asyncio имеет тесты в Lib/test/test_asyncio.

[Совет]Смотри также

Если вы новичок в отношении модуля unittest или тестирования в Python, отсылаем вас к книге Real Python “Getting Started With Testing in Python”.

Вот некое извлечение из класса UnicodeTest:


class UnicodeTest(string_tests.CommonTest,
        string_tests.MixinStrUnicodeUserStringTest,
        string_tests.MixinStrUnicodeTest,
        unittest.TestCase):
...
    def test_casefold(self):
        self.assertEqual('hello'.casefold(), 'hello')
        self.assertEqual('hELlo'.casefold(), 'hello')
        self.assertEqual('ß'.casefold(), 'ss')
        self.assertEqual('fi'.casefold(), 'fi')
 	   

Вы можете расширить свой оператор почти- равенства, который вы реализовали в более ранних главах для строк Unicode Python, добавив новый метод тестирования внутри имеющегося класса UnicodeTest:


    def test_almost_equals(self):
        self.assertTrue('hello' ~= 'hello')
        self.assertTrue('hELlo' ~= 'hello')
        self.assertFalse('hELlo!' ~= 'hello')
 	   

Вы можете исполнить конкретно этот модуль тестирования в Windows:


> rt.bat -q -d -x64 test_unicode
		

Или же вы можете запустить его в macOS или Linux:


$ ./python -m test test_unicode -v
		

Утилиты тестирования

Импортировав модуль test.support.script_helper вы можете получить доступ к вспомогательным функциям для тестирования Python времени исполнения:

  • assert_python_ok(*args, **env_vars) исполняет некий процесс Python с предписанными аргументами и вернуть некий кортеж (код возврата, stdout, stderr).

  • assert_python_failure(*args, **env_vars) аналогичен assert_python_ok(), но декларирует что он испытал неудачу.

  • make_script(script_dir, script_basename, source) изготовляет некий сценарий в script_dir с script_basename и source, затем возвращает значение пути этого сценария. Это полезно в сочетании с assert_python_ok() или assert_python_failure().

Если вы желаете создать некий тест, который будет пропускаться когда этот модуль не был собран, тогда вы можете воспользоваться функцией утилиты test.support.import_module(). Это возбудит SkipTest и выдаст сигнал исполнителю теста пропустить данный пакет тестов. Вот некий пример:


import test.support

_multiprocessing = test.support.import_module('_multiprocessing')

# Your tests...
 	   

Выводы

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

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