Правильный способ автоматического тестирования производительности в 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", подсчете примитивных вызовов, в статистике профиля, и у вас будет что-то приблизительно детерминированное.