Тестирование производительности лучшие практики при выполнении TDD? - PullRequest
9 голосов
/ 15 апреля 2009

Я работаю над проектом, который нуждается в некоторой настройке производительности.

Как мне написать тест, который не проходит, если мои оптимизации не улучшают скорость программы?

Для уточнения:

Проблема не в том, чтобы определить, какие части оптимизировать. Для этого я могу использовать различные инструменты профилирования и бенчмаркинга.

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

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

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

Или, может быть, ответ - сохранить старые версии программы и сравнить результаты до и после? Это был бы мой предпочтительный метод, так как он в основном не зависит от окружающей среды. У кого-нибудь есть опыт работы с таким подходом? Я полагаю, что будет необходимо сохранить только одну более старую версию, если все тесты можно будет пройти, если производительность последней версии будет, по крайней мере, такой же хорошей, как и у предыдущей версии.

Ответы [ 9 ]

5 голосов
/ 16 апреля 2009

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

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

3 голосов
/ 15 апреля 2009

Во многих серверных приложениях (возможно, не в вашем случае) проблема производительности проявляется только при одновременном доступе и под нагрузкой. Поэтому измерение абсолютного времени выполнения подпрограммы и попытка ее улучшить не очень помогают. Есть проблемы с этим методом даже в однопоточных приложениях. Измерение абсолютного обычного времени основано на часах, которые предоставляет платформа, и они не всегда очень точны ; вам лучше полагаться на среднее время, которое занимает рутина.

Мой совет:

  • Используйте профилирование для определения подпрограмм, которые выполняются чаще всего и занимают больше времени.
  • Используйте такой инструмент, как JMeter или Grinder , чтобы разрабатывать репрезентативные тестовые случаи, моделировать параллельный доступ, подвергать приложение нагрузке и измерять (что более важно) пропускную способность и среднее время ответа. Это даст вам лучшее представление о том, как ваше приложение ведет себя, если смотреть со стороны.

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

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

3 голосов
/ 15 апреля 2009

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

2 голосов
/ 15 апреля 2009

Запишите время выполнения текущего кода.

if (newCode.RunningTime >= oldCode.RunningTime) Fail
1 голос
/ 16 апреля 2009

Запустите тесты + профилирование на CI сервере. Вы также можете периодически запускать нагрузочные тесты.

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

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

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

0 голосов
/ 23 ноября 2015

Хотя я в целом согласен с ответом Карла Манастера, с помощью современных инструментов можно получить некоторые преимуществ, которые предлагает TDD для функционального тестирования, в тестирование производительности.

С большинством современных сред тестирования производительности (большая часть моего опыта с Gatling , но я верю, что то же самое относится и к более новым версиям большинства сред тестирования производительности), возможно интегрировать автоматизированные тесты производительности в непрерывные построить интеграцию и настроить ее таким образом, чтобы сборка CI не выполнялась, если не соблюдаются требования к производительности.

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

Требования к хорошей производительности соответствуют следующим правилам: «при наличии 5000 заказов в час 95% поездок пользователей должны включать не более 10 секунд ожидания и переход экрана не занимает более 1 секунды».

Это также зависит от развертывания в производственной тестовой среде в конвейере CI.

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

0 голосов
/ 09 января 2012

Кент Бек и его команда автоматизировали все тесты в TDD.

здесь для тестирования производительности также мы можем автоматизировать тесты в TDD.

критерии здесь при тестировании производительности - мы должны проверить случаи да или нет

если мы хорошо знаем спецификации и хорошо, мы можем автоматизировать их также в TDD

0 голосов
/ 20 апреля 2009

Еще не сталкивался с такой ситуацией;) однако, если бы я это сделал, вот как я бы это сделал. (Я думаю, что взял это из книги Дэйва Астела)

Шаг # 1: Придумайте спецификацию для «приемлемой производительности», так что, например, это может означать «Пользователь должен иметь возможность выполнять Y за N секунд (или миллисекунд)»
Шаг № 2: Теперь напишите неудачный тест. Используйте свой удобный класс таймера (например, .NET имеет класс StopWatch) и Assert.Less(actualTime, MySpec)
Шаг № 3: Если тест уже пройден, все готово. Если красный, вам нужно оптимизировать и сделать его зеленым. Как только тест станет зеленым, производительность станет «приемлемой».

0 голосов
/ 17 апреля 2009

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

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

Вы говорите «серьезно нуждаетесь в настройке производительности». Куда? Какие запросы? Какие функции? Кто говорит, бизнес, пользователи? Какова приемлемая производительность? 3 секунды? 2 секунды? 50 миллисекунд?

Отправной точкой для любого анализа производительности является определение критерия прохождения / отказа. После этого вы МОЖЕТЕ автоматизировать тесты производительности.

Для надежности вы можете использовать (простой) статистический подход. Например, выполнить один и тот же запрос в тех же условиях 100 раз. Если 95% из них возвращаются менее чем за n секунд, это пропуск.

Лично я сделал бы это во время интеграции со стандартного компьютера или с самого сервера интеграции. Запишите значения для каждого теста где-нибудь (круиз-контроль имеет некоторые приятные функции для такого рода вещей). Если вы сделаете это, вы сможете увидеть, как производительность растет с течением времени и с каждой сборкой. Вы даже можете сделать график. Менеджерам нравятся графики.

При тестировании производительности всегда сложно создать стабильную среду, независимо от того, выполняете вы автоматические тесты или нет. Вы будете иметь эту конкретную проблему независимо от того, как вы развиваетесь (TDD, Waterfall и т. Д.).

...