Как бороться с длительными юнит-тестами? - PullRequest
5 голосов
/ 15 декабря 2008

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

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

Тест включает в себя:

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

Большая часть функциональности требует чтения HTTP, выполнения TCP и т. Д. Я не могу их изменить, потому что в этом и заключается идея проекта, если я изменю эти тесты, тестирование будет бессмысленным.

Также я не думаю, что у меня есть самые быстрые инструменты для запуска модульных тестов. Моя текущая настройка использует VS TS с Gallio и nUnit в качестве фреймворка. Я думаю, что VS TS + Gallio немного медленнее, чем другие.

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

Дальнейшее уточнение Править:

Код сильно связан! К сожалению, изменение - это огромный процесс рефаторинга. И в этом есть синдром куриного яйца, где мне нужны юнит-тесты для рефакторинга такого большого кода, но у меня не может быть больше юнит-тестов, если я не рефакторинг его :))

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

И я могу подтвердить, что все модульные тесты (с надлежащей изоляцией) довольно быстрые, и у меня нет проблем с производительностью.


Дальнейшее уточнение:

Код сильно связан! К сожалению, изменение - это огромный процесс рефаторинга. И там есть синдром куриного яйца, когда мне нужны юнит-тесты для рефакторинга такого большого кода, но у меня не может быть больше юнит-тестов, если я не рефакторинг его :))

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

И я могу подтвердить, что все модульные тесты (с надлежащей изоляцией) довольно быстрые, и у меня нет проблем с производительностью.

Ответы [ 6 ]

10 голосов
/ 15 декабря 2008

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

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

Можете ли вы сказать, какие тесты у вас есть, которые являются юнит-тестами (тестирование только 1 вещь) по сравнению с функциональными тестами (тестирование 2 или более вещей одновременно)? Какие из них быстрые, а какие медленные?

7 голосов
/ 15 декабря 2008

Я бы порекомендовал комбинированный подход к вашей проблеме:

  • Часто запускайте подмножество тестов, близких к коду, в который вы вносите изменения (например, тесты из того же пакета, модуля или аналогичного). Реже запускайте тесты, которые дальше удаляются из кода, над которым вы сейчас работаете.
  • Разделите ваш пакет как минимум на два: быстрые и медленные тесты. Чаще запускайте быстрые тесты.
  • Рассмотрите возможность выполнения некоторых из менее вероятных неудачных тестов только автоматическим сервером продолжения интеграции.
  • Изучите методы для повышения производительности ваших тестов. Самое главное, заменив доступ к медленным системным ресурсам более быстрыми подделками. Например, используйте в памяти потоки вместо файлов. Заглушка / макет доступа http. и т.д.
  • Узнайте, как использовать методы устранения зависимости с низким риском, подобные тем, которые перечислены в (очень настоятельно рекомендованной) книге «Эффективная работа с устаревшим кодом». Это позволяет вам эффективно сделать ваш код более тестируемым без применения рефакторинга с высоким риском (часто за счет временного ухудшения фактического проекта, например, разрушения инкапсуляции, до тех пор, пока вы не сможете выполнить рефакторинг до лучшего проекта с сеткой безопасности тестов).

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

7 голосов
/ 15 декабря 2008

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

3 голосов
/ 15 декабря 2008

Во-первых, это не модульные тесты.

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

Во-вторых, не бойтесь издеваться над Http-частью приложения. Если вы действительно хотите провести модульное тестирование приложения, оно ДОЛЖНО. Если вы не хотите этого делать, вы потратите гораздо больше времени, пытаясь проверить свою реальную логику, ожидая возвращения HTTP-запросов и пытаясь настроить данные.

Я бы сохранил ваши тесты уровня интеграции, но постараюсь создать реальные модульные тесты. Это решит ваши проблемы со скоростью. В реальных модульных тестах нет взаимодействия с БД или HTTP.

1 голос
/ 15 декабря 2008

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

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

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

1 голос
/ 15 декабря 2008

Я всегда использую категорию для "LongTest". Эти тесты выполняются каждую ночь, а не днем. Таким образом, вы можете значительно сократить время ожидания. Попробуй: разбери свое юнит-тестирование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...