Мы достигли точки в нашем проекте, когда у нас есть почти тысяча тестов, и люди перестали беспокоиться о том, чтобы запускать их, прежде чем делать регистрацию, потому что это занимает много времени. В лучшем случае они запускают тесты, относящиеся к фрагменту кода, который они изменили, а в худшем случае просто регистрируют его без тестирования.
Я полагаю, что эта проблема связана с тем, что решение выросло до 120 проектов (мы обычно выполняем гораздо меньшие проекты, и это только второй раз, когда мы правильно выполняем TDD), а время сборки + тестирование увеличилось до двух-трех минут. на меньших машинах.
Как уменьшить время выполнения тестов? Есть ли техники? Подделывать больше? Подделывать меньше? Может быть, большие интеграционные тесты не должны запускаться автоматически при запуске всех тестов?
Изменить: в качестве ответа на несколько ответов мы уже используем CI и сервер сборки, вот как я знаю, что тесты не пройдены. Проблема (на самом деле симптом) в том, что мы продолжаем получать сообщения о неудачных сборках. Частичные тесты - это то, что большинство людей делают, но не все. Что касается тестов, они на самом деле довольно хорошо сделаны, они используют подделки для всего, и IO вообще не существует.
источник
Ответы:
Возможным решением было бы перенести часть тестирования с машин для разработки на установку с непрерывной интеграцией ( например, Jenkins ) с использованием программного обеспечения для контроля версий ( Git , SVN и т. Д.).
Когда необходимо написать новый код, данный разработчик создаст ветку для всего, что он делает в репозитории. Вся работа будет выполнена в этой ветке, и они могут в любое время зафиксировать свои изменения в ветке, не испортив основной строки кода.
Когда данная функция, исправление ошибки или что-то еще, над чем они работают, были завершены, эту ветвь можно объединить обратно в ствол (или как вы предпочитаете это делать), где выполняются все модульные тесты. Если тест не пройден, слияние отклоняется, и разработчик получает уведомление, чтобы они могли исправить ошибки.
Вы также можете сделать так, чтобы ваш CI-сервер запускал модульные тесты в каждой ветви функций, когда выполняются коммиты. Таким образом, разработчик может внести некоторые изменения, зафиксировать код и позволить серверу запускать тесты в фоновом режиме, пока они продолжают работать над дополнительными изменениями или другими проектами.
Отличное руководство по одному из способов такой настройки можно найти здесь (специфично для git, но должно работать для других систем контроля версий): http://nvie.com/posts/a-successful-git-branching-model/
источник
Большинство юнит-тестов должно занимать менее 10 миллисекунд каждый или около того. «Почти тысяча тестов» - ничто, и запуск может занять несколько секунд.
Если это не так, то вам следует прекратить написание сильно связанных интеграционных тестов (если это не то, что нужно коду) и начать писать хорошие модульные тесты (начиная с хорошо отделенного кода и правильного использования fakes / mocks / stubs / etc). Эта связь будет влиять на качество теста и время, необходимое для их написания, так что дело не только в сокращении времени выполнения теста.
источник
py.test
) выполнял кучу магии в фоновом режиме, и все было в чистом коде Python («100x»). медленнее, чем С "), выполнение около 500 тестов в моем проекте занимает менее 6 секунд на медленном нетбуке нескольких лет. Эта цифра примерно линейна по количеству тестов; хотя при запуске возникают некоторые накладные расходы, они амортизируются во всех тестах, а накладные расходы на тест составляют O (1).Есть несколько подходов, которые я использовал для решения аналогичной проблемы:
Кроме того, вы можете использовать следующие инструменты, чтобы сделать вашу жизнь проще, а тесты - быстрее
pnunit
и конфигурация CI с несколькими узлами.источник
0. Слушайте своих программистов.
Если они не запускают тесты, это означает, что они воспринимают стоимость (ожидание выполнения тестов, устранение ложных сбоев) больше, чем значение (обнаружение ошибок сразу). Уменьшите затраты, увеличьте ценность, и люди будут постоянно выполнять тесты.
1. Сделайте ваши тесты на 100% надежными.
Если у вас когда-нибудь будут тесты, которые не пройдут с ложными негативами, разберитесь с этим немедленно. Исправьте их, измените их, устраните все, что нужно, чтобы гарантировать 100% надежность. (Это нормально иметь набор ненадежных, но все же полезных тестов, которые вы можете запускать отдельно, но основная часть тестов должна быть надежной.)
2. Измените ваши системы, чтобы гарантировать, что все тесты проходят все время.
Используйте системы непрерывной интеграции, чтобы гарантировать, что только проходящие коммиты будут объединены с основной / официальной / релизной / любой веткой.
3. Измените свою культуру, чтобы оценить 100% прохождения тестов.
Преподайте урок, что задача не «выполнена» до тех пор, пока 100% тестов не пройдут и она не будет объединена с основной / официальной / версией / какой-либо веткой.
4. Сделайте тесты быстрыми.
Я работал над проектами, где тесты занимают секунду, и над проектами, где они занимают весь день. Существует тесная взаимосвязь между временем выполнения тестов и моей производительностью.
Чем дольше выполняются тесты, тем реже вы их запускаете. Это означает, что вы продержитесь дольше, не получая отзывов об изменениях, которые вы делаете. Это также означает, что вы будете идти дольше между коммитами. Фиксация чаще означает меньшие шаги, которые легче объединить; легче следить за историей коммитов; найти ошибку в истории легче; откат тоже проще.
Представьте себе тесты, которые выполняются так быстро, что вы не возражаете против их автоматического запуска при каждой компиляции.
Быстрые тесты могут быть трудными (об этом спрашивал ОП, верно!). Разделение является ключевым. С издевательствами и подделками все в порядке, но я думаю, что вы можете добиться большего успеха путем рефакторинга, чтобы лишние издевательства / подделки стали ненужными. См. Блог Арло Белши, начиная с http://arlobelshee.com/post/the-no-mocks-book .
5. Сделайте тесты полезными.
Если тесты не проваливаются, когда ты облажался, тогда какой смысл? Научитесь писать тесты, которые будут выявлять ошибки, которые вы, вероятно, создадите. Это навык сам по себе, и он займет много внимания.
источник
Пара минут в порядке для модульных тестов. Однако имейте в виду, что существует 3 основных типа тестов:
Они перечислены в порядке скорости. Модульные тесты должны быть быстрыми. Они не поймают каждую ошибку, но они устанавливают, что программа вменяемая. Модульные тесты должны выполняться за 3 минуты или меньше или приличное оборудование. Вы говорите, что у вас есть только 1000 модульных тестов, и они занимают 2-3 минуты? Ну, это, наверное, хорошо.
Вещи, чтобы проверить:
Убедитесь, что ваши модульные и интеграционные тесты разделены. Интеграционные тесты всегда будут медленнее.
Убедитесь, что ваши модульные тесты работают параллельно. У них нет причин не делать это, если они являются настоящими юнит-тестами
Убедитесь, что ваши модульные тесты свободны от зависимостей. Они никогда не должны обращаться к базе данных или файловой системе
Кроме этого, ваши тесты сейчас звучат не так уж плохо. Однако, для справки, один из моих друзей из команды Microsoft имеет 4000 модульных тестов, которые выполняются менее чем за 2 минуты на приличном оборудовании (и это сложный проект). Возможны быстрые юнит-тесты. Устранение зависимостей (и издеваться столько, сколько нужно) - главное, чтобы получить скорость.
источник
Обучите своих разработчиков Личному процессу программного обеспечения (PSP), помогая им понять и улучшить свою производительность, используя больше дисциплины. Написание кода не имеет ничего общего с ударом пальцами по клавиатуре, а затем нажмите кнопку компиляции и регистрации.
Раньше PSP был очень популярен, когда компиляция кода была процессом, который занимал много времени (часы / дни на мэйнфрейме, поэтому всем приходилось делиться компилятором). Но когда персональные рабочие станции стали более мощными, мы все согласились принять этот процесс:
Если вы думаете перед тем, как печатать, а затем после того, как набрали, просмотрите написанное, вы можете уменьшить количество ошибок, прежде чем запускать сборку и набор тестов. Научитесь не нажимать на сборку 50 раз в день, но, может быть, один или два раза, тогда не имеет значения, что время сборки и тестирования занимает несколько минут больше.
источник
Один из возможных способов: разделить ваше решение. Если решение имеет 100 проектов, то оно совершенно неуправляемо. Тот факт, что два проекта (скажем, A и B) используют некоторый общий код из другого проекта (например, Lib), не означает, что они должны быть в одном решении.
Вместо этого вы можете создать решение A с проектами A и Lib, а также решение B с проектами B и Lib.
источник
Я в похожей ситуации. У меня есть юнит-тесты, которые проверяют связь с сервером. Они тестируют поведение с таймаутами, отменой соединений и т. Д. Весь набор тестов длится 7 минут.
7 минут - это относительно короткое время, но это не то, что вы будете делать перед каждым коммитом.
У нас также есть набор автоматизированных тестов пользовательского интерфейса, их время выполнения составляет 2 часа. Это не то, что вы хотите запускать каждый день на вашем компьютере.
Так что делать?
Важно то, что все ваши тесты должны выполняться часто, потому что важно находить ошибки. Тем не менее, не обязательно найти их до фиксации.
источник
Хотя ваше описание проблемы не дает полного понимания кодовой базы, я думаю, что могу с уверенностью сказать, что ваша проблема двоякая.
Учитесь писать правильные тесты.
Вы говорите, что у вас есть почти тысяча тестов, и у вас есть 120 проектов. Предполагая, что не более половины из этих проектов являются тестовыми проектами, у вас есть 1000 тестов для 60 проектов с производственным кодом. Это дает вам около 16-17 тестов пр. проект !!!
Это, вероятно, количество тестов, которое мне нужно было бы охватить примерно 1-2 классами в производственной системе. Таким образом, если у вас нет только 1-2 классов в каждом проекте (в этом случае структура вашего проекта слишком мелкозернистая), ваши тесты слишком велики, они охватывают слишком много места. Вы говорите, что это первый проект, который вы делаете TDD правильно. Например, цифры, которые вы указываете, указывают на то, что это не так, вы не используете свойство TDD.
Вам нужно научиться писать правильные тесты, что, вероятно, означает, что вам нужно научиться в первую очередь тестировать код. Если вы не можете найти в команде опыт для этого, я бы предложил нанять помощь извне, например, в виде одного или двух консультантов, помогающих вашей команде в течение 2-3 месяцев научиться писать тестируемый код, и небольших минимальные юнит-тесты.
Для сравнения, над проектом .NET, над которым я сейчас работаю, мы можем выполнить примерно около 500 модульных тестов менее чем за 10 секунд (а это даже не было измерено на машине с высокими техническими характеристиками). Если бы это были ваши цифры, вы бы не боялись запускать их локально.
Научитесь управлять структурой проекта.
Вы разделили решение на 120 проектов. Это по моим меркам ошеломляющее количество проектов.
Так что, если есть смысл иметь такое количество проектов (что, как мне кажется, не так, но ваш вопрос не дает достаточно информации, чтобы квалифицированно оценить это), вам нужно разделить проекты на более мелкие компоненты, которые может быть собран, версионирован и развернут отдельно. Поэтому, когда разработчик запускает модуль набора тестов, ему / ей нужно только запустить тесты, относящиеся к компоненту, над которым он / она работает в настоящее время. Сервер сборки должен позаботиться о том, чтобы все правильно интегрировалось.
Но разделение проекта на несколько компонентов, сборку, управление версиями и развертывание которых по отдельности, требует, по моему опыту, очень зрелой команды разработчиков, команды, которая более зрелая, чем я, чувствую, что ваша команда такова.
Но, во всяком случае, вам нужно что-то сделать со структурой проекта. Либо разделите проекты на отдельные компоненты, либо начните объединять проекты.
Спросите себя, действительно ли вам нужно 120 проектов?
PS Вы можете проверить NCrunch. Это плагин Visual Studio, который автоматически запускает тест в фоновом режиме.
источник
Тест JUnit обычно должен быть быстрым, но некоторые из них просто должны занять некоторое время, чтобы выполнить его.
Например, тестирование базы данных обычно занимает некоторое время для инициализации и завершения.
Если у вас есть сотни тестов, даже если они быстрые, они требуют много времени для выполнения из-за их количества.
Что можно сделать, это:
1) Определите важные тесты. Те для самых важных частей библиотек и те, которые, скорее всего, потерпят неудачу после изменений. Только те тесты должны выполняться всегда при компиляции. Если какой-то код часто ломается, его тесты должны быть обязательными, даже если для их выполнения требуется много времени, с другой стороны, если какая-то часть программного обеспечения никогда не вызывала проблемы, вы можете безопасно пропустить тесты для каждой сборки.
2) Подготовьте сервер непрерывной интеграции, который будет запускать все тесты в фоновом режиме. Это зависит от вас, если вы решите строить каждый час или строить после каждого коммита (второй имеет смысл, только если вы хотите автоматически определить, чей коммит вызвал проблему).
источник
Проблемы, которые я видел:
а) Использование МОК для создания тестовых элементов. 70 секунд -> 7 секунд, удалив контейнер.
б) Не издеваться над всеми классами. Держите свои юнит-тесты на одном элементе. Я видел тесты, которые проходят через пару классов. Это не юнит-тесты и гораздо чаще ломаются.
в) Профиль их, чтобы узнать, что происходит. Я обнаружил, что конструктор собирал вещи, которые мне не нужны, поэтому я локализовал их и сократил время выполнения.
г) Профиль. возможно, код не так хорош, и вы можете получить некоторую эффективность из обзора.
e) Удалить зависимости. Небольшой тестовый исполняемый файл сократит время загрузки. Используйте интерфейсную библиотеку и контейнеры IOC для запуска вашего окончательного решения, но ваши основные тестовые проекты должны иметь только определенную интерфейсную библиотеку. Это обеспечивает разделение, облегчает тестирование, а также уменьшает размер отпечатка.
источник
Я чувствую вашу боль, и я столкнулся с несколькими местами, где скорость сборки может быть значительно улучшена. Тем не менее, число, которое я рекомендую, состоит в том, чтобы измерить детализацию, чтобы определить, где ваша сборка занимает больше всего времени. Например, у меня есть сборка с 30 проектами, выполнение которой занимает чуть более минуты. Однако это только часть картины. Я также знаю, какие проекты требуются больше всего времени, что помогает сосредоточить мои усилия.
Вещи, которые съедают время сборки:
Библиотеки макетов либо используют рефлексию, либо внедряют код, используя библиотеки байт-кода для генерации макета для вас. Хотя это очень удобно, оно съедает время тестирования. Если вы генерируете макеты внутри цикла в своем тесте, это может добавить измеримое время к юнит-тестам.
Есть способы решения проблем:
Когда ваше решение содержит более 100 проектов, у вас есть комбинация кода библиотеки, тестов и кода приложения. Каждая из библиотек может быть ее собственным решением со связанными тестами. Jet Brains Team City - это сервер сборки CI, который работает как сервер Nuget, и я уверен, что он не единственный. Это дает вам возможность перемещать те библиотеки, которые, вероятно, не часто меняются, в свои собственные решения / проекты и использовать Nuget для разрешения зависимостей для кода вашего приложения. Меньшие решения означают, что вы можете вносить изменения в библиотеку быстро и без суеты и пользоваться преимуществами основного решения.
источник
Может ли ваша тестовая среда работать где-нибудь? Если это возможно, используйте облачные вычисления для запуска тестов. Разделите тесты среди N виртуальных машин. Если время для запуска тестов на одной машине составляет T1 секунды, тогда время для их разделения, T2, может приблизиться к T2 = T1 / N. (Предполагается, что каждый тестовый пример занимает примерно одинаковое количество времени.) И вам нужно платить только за виртуальные машины, когда вы их используете. Таким образом, у вас нет кучки тестовых машин, сидящих где-то в лаборатории 24/7. (Я бы хотел сделать это там, где я работаю, но мы привязаны к конкретному оборудованию. Никаких виртуальных машин для меня.)
источник