Как бороться с длительными юнит-тестами?

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

15.12.2008 15:02:12
6 ОТВЕТОВ
РЕШЕНИЕ

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

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

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

10
15.12.2008 15:06:32
Поэтому я предполагаю, что правильным шагом будет: рефакторинг кода таким образом, чтобы у меня не было такой большой связи. Затем запускать функциональные тесты ежедневно, но запускать юнит-тесты после каждой сборки?
dr. evil 15.12.2008 15:29:24
Вы можете даже запускать все функциональные тесты при каждой регистрации с помощью Continuous Integration. Когда я пишу модульные тесты, я склонен запускать те, которые локально соответствуют тому, над чем я работаю, очень часто, затем реже ставить большие наборы и все перед тем, как делать коммит.
Brad Wilson 15.12.2008 16:00:48
Я не думал о создании решения для непрерывной интеграции, так как это команда одинокого волка. Только я работаю над проектом как разработчик. Но я думаю, что настройка такой системы может помочь мне, или даже просто настроить расписание задач и сообщать об ошибках.
dr. evil 15.12.2008 17:17:37

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

8
15.12.2008 15:07:11

Во-первых, это не юнит-тесты.

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

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

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

3
15.12.2008 15:39:47

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

2
15.12.2008 15:42:37
Я думаю, что мне нужно играть с панелями VS TS, я обычно использую NUnit, но каким-то образом после финальных обновлений .NET Framework графический интерфейс NUnit не работает, поэтому я застрял с глупыми тестами MS Suite и Gallio.
dr. evil 15.12.2008 17:20:09

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

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

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

1
15.12.2008 15:43:55
На самом деле в настоящее время это то, что я делаю. Просто запускаю юнит-тесты примерно 3 раза в день.
dr. evil 15.12.2008 15:46:07

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

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

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

8
15.12.2008 15:57:43