Правильный способ автоматического тестирования производительности в Python (для всех разработчиков)?
В нашем приложении Python (классной веб-службе) есть полный набор тестов (модульные тесты, интеграционные тесты и т.д.), которые все разработчики должны выполнять перед выполнением кода.
Я хочу добавить некоторые тесты производительности в набор, чтобы убедиться, что никто не добавляет код, который заставляет нас работать слишком медленно (для некоторого довольно произвольного определения медленного).
Очевидно, что я могу собрать некоторую функциональность в тест, время и сравнить с некоторым предопределенным порогом.
Сложные требования:
- Я хочу, чтобы каждый разработчик мог проверить код на своем компьютере (зависит от мощности процессора, ОС (! Linux и некоторых Windows) и внешних конфигураций - версия Python, библиотеки и модули одинаковы). Тест-сервер, хотя в целом неплохая идея, не решает этого.
- Я хочу, чтобы тест был DETERMINISTIC - независимо от того, что происходит на машине, на которой выполняются тесты, я хочу, чтобы несколько прогонов теста возвращали те же результаты.
Мои предварительные мысли:
- Использовать тайм-аут и выполнять тест системы каждый раз, когда я запускаю тесты. Сравните результаты теста производительности с эталонным тестом.
- Используйте cProfile, чтобы заставить интерпретатор игнорировать "внешний шум". Я не уверен, что знаю, как читать структуру
pstats
, но я уверен, что это выполнимо.
Другие мысли?
Спасибо!
Tal.
Ответы
Ответ 1
Отъезд funkload - это способ запуска ваших модульных тестов в качестве функциональных или нагрузочных тестов для оценки того, насколько хорошо работает ваш сайт.
Другим интересным проектом, который может быть использован в сочетании с funkload, является codespeed. Это внутренняя панель мониторинга, которая измеряет "скорость" вашей кодовой базы для каждой фиксации, которую вы делаете для своего кода, с графическими графиками с течением времени. Это предполагает, что у вас есть несколько автоматических тестов, которые вы можете запустить, но это может быть полезным способом получить авторитетный учет производительности с течением времени. Лучшее использование кода, которое я видел до сих пор, это speed.pypy.org.
Что касается вашего требования к детерминизму - возможно, лучшим подходом к этому является использование статистики в ваших интересах? Автоматически запускать тест N раз, производить минимальное, максимальное, среднее и стандартное отклонение всех ваших прогонов? Посмотрите эту статью на бенчмаркинг для некоторых указателей на это.
Ответ 2
Я хочу, чтобы тест был DETERMINISTIC - независимо от того, что происходит на машине, на которой выполняются тесты, я хочу, чтобы несколько прогонов теста возвращали те же результаты.
нормально. Более или менее по определению это совершенно невозможно в многопроцессорной системе с несколькими пользователями.
Переосмыслите это требование или найдите новую среду, в которой можно запускать тесты, которые не включают в себя ни одну из современных многопроцессорных операционных систем.
Кроме того, ваше работающее веб-приложение не является детерминированным, поэтому наложение какого-то "детерминированного" тестирования производительности мало помогает.
Когда мы выполняли критическую по времени обработку (в радаре, где "реальное время" фактически означало реальное время), мы не пытались провести детерминированное тестирование. Мы проводили проверки кода и выполняли простые тесты производительности, которые включали простые средние и максимальные значения.
Используйте cProfile, чтобы заставить интерпретатор игнорировать "внешний шум". Я не уверен, что знаю, как читать структуру pstats, но я уверен, что это выполнимо.
Объект Stats
, созданный профилировщиком, является тем, что вы ищете.
http://docs.python.org/library/profile.html#the-stats-class
Сосредоточьтесь на "pcalls", подсчете примитивных вызовов, в статистике профиля, и у вас будет что-то приблизительно детерминированное.