Тестирование только затронутого кода в Python

Я работал над довольно большим проектом Python с несколькими тестами.

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

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

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

Похоже, что Mighty Moose использует аналогичный подход для языков CLR. Используя их как источник вдохновения, я задаюсь вопросом: какие есть альтернативы (если таковые имеются) для интеллектуального выборочного тестирования в проектах Python?

Если их нет, каковы были бы хорошие начальные подходы для создания чего-то подобного?

Ответ 1

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

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

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

Поэтому я считаю, что ваш подход использовать теги для тестирования разделов в разных "группах" является умным, хотя, как вы говорите, управление ими становится затруднительным с помощью большого набора тестов. Учитывая это, может быть целесообразно сосредоточиться на создании инструментов, помогающих в управлении вашим набором тестов, в частности, в управлении тегами. Такая система может быть построена путем сбора информации из:

  • Результат тестового результата (пропуск/сбой, время выполнения, журнал)
  • Выход покрытия кода
  • Анализ исходного кода

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

Ответ 2

Если вы используете unittest.TestCase, вы можете указать, какие файлы выполнять с параметром pattern. Затем вы можете выполнять тесты на основе измененного кода. Даже если вы не используете unittest, ваши тесты будут обработаны функциональной областью/модулем, чтобы вы могли использовать аналогичный подход.

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

Достаточно сочетания ночных заданий всех тестов и тестов на каждую ветвь каждые 15-30 минут (если есть новые коммиты).

Ответ 3

Несколько случайных мыслей на эту тему, основанные на работе, которую я делал ранее на кодовой базе Perl с аналогичными проблемами "полная сборка слишком долго":

  • Знание ваших зависимостей является ключом к выполнению этой работы. Если модуль A зависит от B и C, тогда вам нужно проверить A, когда любой из них будет изменен. Похоже, Snakefood - хороший способ получить словарь, который описывает зависимости в вашем коде; если вы берете это и переводите его в make файл, тогда вы можете просто "сделать тест" при регистрации, и все зависимости (и только необходимые) будут перестроены и протестированы.

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

Ответ 4

Если вы пишете результаты теста в файл, вы можете использовать make или аналогичную альтернативу, чтобы определить, когда нужно "перестроить" тесты. Если вы пишете результаты в файл, make может сравнивать отметку времени даты тестов с зависимыми файлами python.

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

Я бы использовал соглашение об именах, чтобы разрешить make решить это в целом. Наивный пример:

%.test_result : %_test.py
python $< > [email protected]

Определяет новое неявное правило для преобразования между _test.py и результатами теста. Затем вы можете рассказать о своих дополнительных зависимостях для тестов, например:

my_module_test.py : module1.py module2.py external\module1.py

Ответ 5

Подумайте о том, чтобы задать вопрос: какие тесты нужно исключить, чтобы сделать работу неприемлемой. Набор тестов CPython в Lib/test исключает тяжелые тесты ресурсов до тех пор, пока они не будут запрошены (как они могут быть на buildbot). Некоторые дополнительные ресурсы - это "cpu" (время), "большой файл" (дисковое пространство) и "сеть" (соединения). (python -m test -h (на 3.x, test.regrtest на 2.x) дает весь список.)

К сожалению, я не могу сказать, как это сделать, поскольку "пропускать, если ресурс недоступен" - это функция более старого run.regrtest, используемого в тестовом наборе. В трекере есть проблема с добавлением ресурсов для unittest.

Что может работать в то же время, это примерно так: добавьте файл, специфичный для машины, exclusions.py, содержащий список строк, подобных приведенным выше. Затем импортируйте исключения и пропустите тесты, случаи или модули, если соответствующая строка находится в списке.

Ответ 6

Мы сталкивались с этой проблемой несколько раз в прошлом и смогли ответить на нее путем улучшения и повторного факторинга тестов. Вы не указали свои методы разработки и не потратили время на проведение тестов. Я бы сказал, что если вы делаете TDD, вам нужно проработать не более нескольких секунд. Все, что работает дольше, чем вам нужно переместить на сервер. Если ваши тесты занимают больше времени, чем один день, то у вас есть реальная проблема, и это ограничит вашу способность быстро и эффективно выполнять функции.

Ответ 7

Я полагаю, вы ищете инструмент для непрерывного тестирования?

Я создал инструмент, который работает в фоновом режиме и запускает только проверенные тесты: (Вам понадобится плагин PyCharm и pycrunch-engine из pip)

https://github.com/gleb-sevruk/pycrunch-engine

Это будет особенно полезно, если вы используете PyCharm.

Более подробно в этом ответе:fooobar.com/questions/16703545/...