Что делать с длительными модульными тестами?

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

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

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

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

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

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

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

Дополнительное пояснение Правка:

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

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

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


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

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

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

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


person dr. evil    schedule 15.12.2008    source источник


Ответы (6)


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

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

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

person Brad Wilson    schedule 15.12.2008
comment
Поэтому я предполагаю, что правильным шагом будет: рефакторинг кода таким образом, чтобы у меня не было такой большой связи. Затем запускать функциональные тесты ежедневно, но запускать модульные тесты после каждой сборки? - person dr. evil; 15.12.2008
comment
Вы даже можете запускать все функциональные тесты при каждой регистрации с помощью непрерывной интеграции. Когда я пишу модульные тесты, я обычно очень часто запускаю те, над которыми я работаю, затем более крупные наборы реже, и все это до того, как я сделаю коммит. - person Brad Wilson; 15.12.2008
comment
Я не рассматривал возможность создания решения для непрерывной интеграции, так как это команда-одиночка. Только я работаю над проектом как разработчик. Но я думаю, что настройка такой системы могла бы мне помочь, или даже просто настроить расписание задач и сообщать об ошибках. - person dr. evil; 15.12.2008

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

person Nathaniel Flath    schedule 15.12.2008

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

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

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

person Ilja Preuß    schedule 15.12.2008

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

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

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

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

person John Sonmez    schedule 15.12.2008

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

person Patrick Desjardins    schedule 15.12.2008
comment
Я думаю, что мне нужно поиграть с панелями VS TS, обычно я использую NUnit, но почему-то после финальных обновлений .NET Framework графический интерфейс NUnit не работает, поэтому я остановился на дурацком тестовом пакете MS и Gallio. - person dr. evil; 15.12.2008

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

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

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

person Bryan    schedule 15.12.2008
comment
На самом деле в настоящее время это то, что я делаю. Просто запускаю юнит-тесты примерно 3 раза в день. - person dr. evil; 15.12.2008