Покрытие кода Python и многопроцессорность

Я использую комбинезоны в сочетании с coverage.py для отслеживания охвата кода Python моих тестовых скриптов. Я использую следующие команды:

coverage run --parallel-mode --source=mysource --omit=*/stuff/idont/need.py ./mysource/tests/run_all_tests.py
coverage combine
coveralls --verbose

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

Есть ли возможность также отслеживать многопроцессорный код? Какой-то конкретный вариант мне не хватает? Может быть, добавить обертки в библиотеку многопроцессорной обработки, чтобы запускать покрытие каждый раз, когда порождается новый процесс?

ИЗМЕНИТЬ:

Я (а также Джонршарп :-) нашел monkey-patch для многопроцессорной обработки.

Однако у меня это не работает, моя сборка Tracis-CI убивается почти сразу после старта. Я проверил проблему на своем локальном компьютере и, очевидно, добавление патча к многопроцессорной обработке разрушает мою память. Тесты, которые занимают намного меньше 1 ГБ памяти, требуют более 16 ГБ с этим исправлением.

EDIT2:

Патч-обезьяна работает после небольшой модификации: удаление config_file синтаксического анализа (config_file=os.environ['COVERAGE_PROCESS_START']) помогло. Это решило проблему раздутой памяти. Соответственно, соответствующая строка становится просто:

cov = coverage(data_suffix=True)

person SmCaterpillar    schedule 03.02.2015    source источник
comment
Разве вы не тестируете код для этих дочерних процессов напрямую?   -  person jonrsharpe    schedule 03.02.2015
comment
Ну да, большую часть я делаю. Но есть определенные части, которые полезны и выполняются только в случае использования многопроцессорности (например, обертывание доступа к базе данных блокировками или очередью многопроцессорности для принудительного хранения последовательных данных). И я по себе знаю, что этот код работает благодаря успешным тестам. Было бы неплохо, если бы это появилось и на комбинезонах :-)   -  person SmCaterpillar    schedule 03.02.2015
comment
См. bitbucket.org/ned/coveragepy. /issue/117/ через nedbatchelder.com/code/coverage/trouble.html   -  person jonrsharpe    schedule 03.02.2015
comment
Спасибо, я тоже наткнулся на это. Однако у меня обезьяний патч не работает. Добавление этого к моему сценарию почти мгновенно убивает мой Travis-CI. Я проверил это и на своей локальной машине. Судя по всему, патч с обезьянами портит мне память. Покрытие выделяет более 16 ГБ памяти для тестов, которым обычно требуется гораздо меньше 1 ГБ.   -  person SmCaterpillar    schedule 03.02.2015
comment
@SmCaterpillar Мне очень интересно узнать о вашем опыте. Идея убрать парсинг конфигурационного файла кажется очень странной: я не могу представить, как парсинг конфигурационного файла радикально изменит объем памяти. В чем ценность COVERAGE_PROCESS_START для вас? У вас есть файл .coveragerc? Напишите мне по электронной почте, если хотите покопаться в этом.   -  person Ned Batchelder    schedule 05.02.2015
comment
Эй, нет, я не использую файл coverrc. Вот я перепроверил и соответственно config_file=os.environ['COVERAGE_PROCESS_START'] выдает ошибку ключа. Однако основная программа продолжает работать и порождает новые процессы. Может быть, это было причиной того, что память была искажена?   -  person SmCaterpillar    schedule 05.02.2015


Ответы (2)


Покрытие 4.0 включает параметр командной строки --concurrency=multiprocessing для решения этой проблемы. Вы должны использовать coverage combine после этого. Например, если ваши тесты находятся в regression_tests.py, вы можете просто сделать это в командной строке:

coverage run --concurrency=multiprocessing regression_tests.py
coverage combine
person David Ketcheson    schedule 26.04.2016
comment
Спасибо, что указали на необходимость использования coverage combine после этого. Я некоторое время крутил колеса, пытаясь понять, почему concurrency=multiprocessing, который был у меня в моем файле .coveragerc, не работал. - person Mike Jarvis; 19.09.2016
comment
Не могли бы вы добавить простой базовый пример к этому ответу? Это бы мне очень помогло. - person Luca Cappelletti; 03.12.2018
comment
@LucaCappelletti Готово; надеюсь, это поможет. - person David Ketcheson; 03.12.2018

Я потратил некоторое время, пытаясь убедиться, что покрытие работает с multiprocessing.Pool, но это так и не сработало.

Наконец-то я сделал исправление, которое заставляет его работать - был бы рад, если бы кто-то направил меня, если я делаю что-то не так.

https://gist.github.com/andreycizov/ee59806a3ac6955c127e511c5e84d2b6

person Andrey Cizov    schedule 28.12.2016
comment
Я считаю, что эта ссылка здесь может вам помочь: pytest-cov .readthedocs.io/en/latest/ — кажется, вам нужно вызвать соединение в потоках после, чтобы избежать нескольких проблем. - person Davis Z. Cabral; 18.06.2018
comment
Большое спасибо, Дэвис - я пропустил это несколько лет спустя. :) - person Andrey Cizov; 20.06.2018