Я работаю над разработкой старого проекта, написанного на Java. У нас более 10 миллионов LOC и, что еще хуже, более 4000 функциональных тестов.
Тесты, запланированные Хадсоном, проваливаются, как сумасшедшие, с каждым большим изменением кода. Проверка неудачи теста - если это проблема в продукте или в тесте, занимает месяцы. Мы не можем удалить старые тесты, потому что мы не знаем, что они тестируют!
Что мы можем сделать? Как поступить с таким количеством устаревших тестов?
integration-tests
legacy-code
jenkins
Гектор Бросули
источник
источник
Ответы:
Оставь их.
Я знаю, что трудно отпустить что-то, что было явно приложено много усилий, но тесты не работают для вас, они работают против вас. Предполагается, что набор тестов даст вам уверенность в том, что система делает то, что должна делать. Если он этого не делает, то это пассив, а не актив. Неважно, виновата ли система или тесты - пока набор тестов сигнализирует об огромном количестве ошибок, он не может выполнить свою задачу.
Теперь вам нужен новый набор тестов, который работает без ошибок. Это означает, что изначально у него будет мало покрытия, фактически почти нет покрытия. Каждый раз, когда вы исправляете или находите время, чтобы полностью разобраться в вашей системе, вы записываете эти знания в тесте. Со временем это создаст новую сеть безопасности, на которой вы сможете строить в будущем. Попытка залатать старую, плохо понятую систему безопасности - это трата времени, которая почти никогда не стоит.
Я бы даже выступил против переноса тестов из старого набора в новый. Конечно, некоторые из них могут преуспеть сейчас, но потому ли, что они проверяют именно то, что должны проверять, или просто потому, что некоторые случайные выстрелы всегда попадают в цель? Очевидно, вы должны быть прагматичными в отношении того, что можно и что нельзя делать с теми усилиями, которые вы готовы потратить, но вы не можете пойти на компромисс с принципом, что набор тестов должен работать чисто, чтобы выполнять свою работу .
источник
Иди и исправь тесты.
Ваша самая большая ошибка в том, что вы позволили тестам провалиться, и вы, очевидно, некоторое время игнорировали их. То, что у вас есть, это не «устаревшие тесты» - вы работаете над устаревшим кодом. И я считаю каждый код, написанный без тестов, устаревшим.
Похоже, что в вашей организации есть еще большая проблема, поскольку вы не работаете с четкими требованиями. Я не могу понять, что вы (или кто-то еще) не можете подтвердить правильное поведение.
источник
Тесты ценны. По крайней мере, они записывают, что кто-то считал, что им следует потратить время на их написание, поэтому, по-видимому, они когда-то имели какую-то ценность для кого-то. Если повезет, они будут содержать полную запись всех функций и ошибок, над которыми когда-либо работала команда, хотя они также могли быть способом попасть в произвольное число тестов, не будучи тщательно продуманным. Пока вы не посмотрите на них, вы не будете знать, что здесь происходит.
Если большая часть ваших тестов проходит большую часть времени, просто откусите пулю и потратьте время на выяснение того, что пытались выполнить несколько неудачных тестов, а также на исправление или улучшение их, чтобы в следующий раз работа была проще. В этом случае перейдите к разделу Определение цели для каждого раздела теста , чтобы получить советы о том, что делать с небольшим количеством неудачных тестов.
С другой стороны, вы можете столкнуться со сборкой Red и сотнями или даже тысячами тестов, которые не прошли некоторое время, и Дженкинс долгое время не был Green. На этом этапе статус сборки Jenkins стал бесполезным, и ключевой индикатор проблем с вашей регистрацией больше не работает. Вам нужно это исправить, но вы не можете позволить себе остановить весь прогресс, пока вы наводите порядок в своей гостиной.
Чтобы сохранить ваше здравомыслие, выполняя необходимую археологию, чтобы определить, какое значение можно восстановить из неудачных тестов, я рекомендую следующие шаги:
Временно отключите неудачные тесты.
Есть несколько способов сделать это, в зависимости от вашей среды, которые вы не можете четко описать, поэтому я не могу рекомендовать какой-либо конкретный способ.
Некоторые структуры поддерживают понятие ожидаемых отказов. Если у вас есть, то это здорово, так как вы увидите обратный отсчет того, сколько тестов осталось в этой категории, и вам даже сообщат, если некоторые из них начнут проходить неожиданно.
Некоторые фреймворки поддерживают группы тестов и позволяют сообщать Хадсону только о запуске некоторых тестов или пропуске группы тестов. Это означает, что вы можете иногда запускать тестовую группу вручную, чтобы увидеть, проходят ли какие-либо из них сейчас.
Некоторые фреймворки позволяют аннотировать или иным образом отмечать отдельные тесты, которые будут игнорироваться. В этом случае труднее управлять ими как группой, но это мешает им отвлекать вас.
Вы можете переместить тесты в исходное дерево, которое обычно не включено в сборку.
В крайнем случае, вы можете удалить код из HEAD системы контроля версий, но тогда вам будет сложнее распознать, когда третий этап завершен.
Цель состоит в том, чтобы Дженкинс как можно скорее стал Зеленым, чтобы вы могли начать движение в правильном направлении как можно скорее.
Держите тесты актуальными.
Разрешите добавлять новые тесты по мере добавления или изменения кода и обязуйтесь не сдавать все проходящие тесты.
Тесты могут проваливаться по разным причинам, включая тот факт, что они не были хорошо написанными тестами для начала. Но как только Дженкинс станет зеленым, это будет очень важно.
Привыкните к написанию хороших тестов и сделайте так, чтобы тесты начинали проваливаться.
Определите цель каждого теста.
Пройдите отключенные тесты один за другим. Начните с тех, которые влияют на модули, которые вы меняете чаще всего. Определите цель теста и причину неудачи.
Проверяет ли он функцию, которая была специально удалена из базы кода? Тогда вы, вероятно, можете удалить его.
Это ошибка, которую еще никто не заметил? Восстановите тест и исправьте ошибку.
Это сбой, потому что он делал необоснованные предположения (например, предполагая, что текст кнопки всегда будет на английском языке, но теперь вы локализовали свое приложение для нескольких языков)? Затем выясните, как сделать тест сосредоточенным на одной вещи, и изолировать его от несвязанных изменений как можно лучше.
Распространяется ли тест на все приложение и представляет собой системный тест? Затем удалите его из основного набора тестов Jenkins и добавьте его в набор регрессии, который запускается реже.
Изменилась ли архитектура приложения до неузнаваемости, поэтому тест больше не дает ничего полезного? Удали это.
Был ли тест добавлен для искусственного увеличения статистики покрытия кода, но на самом деле он не более чем подтверждает, что код компилируется правильно и не входит в бесконечный цикл? Или же, тест просто подтверждает, что выбранная вами насмешливая структура возвращает результаты, о которых вы только что сказали? Удали это.
В результате этого некоторые тесты будут выдержаны, некоторые будут изменены, некоторые разделены на несколько независимых кусков размера укуса, а некоторые удалены. Пока вы все еще прогрессируете с новыми требованиями, ответственное дело - выделить немного времени для решения технических проблем, подобных этому.
источник
4000 тестов - неразрешимая проблема. 40 тестов более податливы. Произвольно выберите управляемое количество тестов для запуска и анализа. Классифицируйте результаты как:
Если многие тесты попадают в первую категорию, возможно, пришло время выбросить ваш текущий набор тестов и собрать полезный для текущего кода.
Если многие тесты дают сбой таким образом, что они сообщают вам о проблеме в вашем коде, вам нужно разобраться с ошибочными тестами. Вы можете обнаружить, что исправление одной или двух ошибок приводит к большому количеству выполненных тестов.
источник
Если это утверждение верно,
тогда это означает, что если вы откроете код перед «большим изменением кода», то многие тесты пройдут снова. Сделав это, возьмите меньший кусок изменений и посмотрите, какие тесты вновь провалились. Это поможет вам лучше определить, какие изменения кода приводят к сбою тестов. Для каждого теста, как только вы изолировали проблему, вы должны были быть в состоянии определить, был ли новый код ошибочным, или тест был. Если это проблема с новым кодом, обязательно сравните его с последней версией на тот случай, если конкретная ошибка уже исправлена.
Повторяйте, пока у вас не будет последней версии кода.
Это может показаться непосильной задачей, но вполне вероятно, что, как только вы пойдете по этому пути и начнете изолировать некоторые из проблем, начнет появляться шаблон, который может значительно ускорить процесс. Например:
источник
Если вы не знаете, что они тестируют, удалите их, пока не узнаете. Тесты - это простые вещи: если вы удалите функцию, которая больше не требуется, вам следует изменить тест, который тестирует эту функцию! Так что, если вы не знаете, что тестируют тесты, у вас нет надежды изменить кодовую базу с ними на месте.
Вы можете настроить тестовую систему на машинах разработчика и запустить ее там, чтобы разработчики могли видеть, с какими частями взаимодействуют тесты, надеюсь, предоставят эту недостающую документацию и лучше познакомятся с базой кода, которую вы либо не меняете правильно, либо нет дольше тестирую правильно.
Короче говоря - если ваши старые тесты терпят неудачу, когда вы вносите изменения, ваши изменения кода не годятся. Используйте эти тесты как средство обучения тому, как работает система.
источник
@Ignore
аннотация JUnit - вы можете сохранять свои тесты, но не выполнять их. Тогда это просто вопрос их повторного включения и исправления по одному. Это позволяет сузить фокус до нескольких тестов за раз, вместо того, чтобы быть перегруженным тысячами сбоев.Самое важное, что я бы сделал, - это вернусь к основам того, что должно делать тестирование, и что бизнес должен продолжать двигаться. Задача тестирования - выявить проблемы, прежде чем они станут дорогостоящими, чтобы их можно было исправить позже. Я думаю, что ключевое слово в этом предложении «дорого». Эти вопросы требуют бизнес-решения. Дорогие проблемы появляются в поле? Если это так, тестирование не проходит сразу.
Ваше руководство и вам нужно прийти к проверке реальности. Вы обнаружите, что затраты на разработку стремительно растут из-за устаревшего набора тестов. Как эти затраты сравниваются с затратами на доставку неисправного продукта, потому что вы отключили тесты? Как они соотносятся с обременительной задачей на самом деле выяснить, какое поведение нужно пользователям (какие вещи должны быть проверены)?
Это проблемы, которые требуют бизнес-решений, потому что они затрагивают деловую сторону работы. Вы поставляете продукт клиенту, и это является границей, в которой бизнес очень заинтересован. Они могут определить решения, которые вы, как разработчик, не сможете. Например, для них может быть разумным предоставить два продукта: один «унаследованный» продукт для тех, кто нуждается в надежности и желает отказаться от новых функций, с одним «дальновидным» продуктом, который может иметь больше недостатков, но впереди. Это даст вам возможность разработать два независимых набора тестов: один унаследованный с 4000 тестами, а другой с большим количеством тестов, которые, по вашему мнению, необходимо выполнить (и документируйте их, чтобы этот процесс не повторялся).
Затем начинается искусство: как вы можете управлять этим двуглавым зверем, чтобы успехи в одной ветви также помогали другой ветви? Каким образом ваши обновления ветки «visonary» могут возвращаться к ветке «legacy», несмотря на жесткие требования к тестированию. Как постоянные запросы клиентов в «устаревшей» ветке могут улучшить ваше понимание требований, которые потребуются вашим прежним клиентам, если вы в конечном итоге повторно объедините продукты?
источник
Именно поэтому вы должны удалить старые тесты! Если вы не знаете, что они делают, то неудача не имеет смысла, а запуск их - пустая трата времени. Выкинь их и начни сначала.
источник