Я пишу тесты для проекта, который состоит из нескольких подмодулей. Каждый написанный мной тестовый пример выполняется независимо друг от друга, и я очищаю все данные между тестами.
Несмотря на то, что тесты выполняются независимо, я рассматриваю возможность применения порядка выполнения, поскольку в некоторых случаях требуется более одного подмодуля. Например, подмодуль генерирует данные, а другой выполняет запросы к данным. Если подмодуль, генерирующий данные, содержит ошибку, проверка подмодуля запроса также не будет выполнена, даже если сам подмодуль работает нормально.
Я не могу работать с фиктивными данными, так как основная функция, которую я тестирую, - это подключение к удаленному серверу черного ящика, который получает данные только из первого субмодуля.
В этом случае можно ли принудительно применять порядок выполнения тестов или это плохая практика? Я чувствую, что в этой настройке есть запах, но я не могу найти лучший способ обойти.
редактировать: вопрос от Как структурировать тесты, где один тест является настройкой другого теста? так как «предыдущий» тест не является настройкой, но тестирует код, который выполняет настройку.
источник
Ответы:
Это ключевая часть для меня. Вы можете говорить о «модульных тестах» и о том, что они «работают независимо друг от друга», но все они звучат так, как будто они зависят от этого удаленного сервера и зависят от «первого субмодуля». Так что все звучит тесно взаимосвязанно и зависит от внешнего состояния. Таким образом, вы фактически пишете интеграционные тесты. Выполнение этих тестов в определенном порядке вполне нормально, поскольку они сильно зависят от внешних факторов. Упорядоченный тестовый прогон с возможностью досрочного выхода из тестового прогона, если что-то пойдет не так, вполне приемлем для интеграционных тестов.
Но также стоило бы по-новому взглянуть на структуру вашего приложения. Возможность смоделировать первый подмодуль и внешний сервер потенциально позволит вам написать истинные модульные тесты для всех других подмодулей.
источник
Да, это плохая практика.
Как правило, модульное тестирование предназначено для тестирования одного блока кода (например, одной функции, основанной на известном состоянии).
Если вы хотите проверить цепочку событий, которые могут произойти в дикой природе, вам нужен другой стиль тестирования, такой как интеграционный тест. Это еще более верно, если вы зависите от сторонних услуг.
Чтобы выполнить модульное тестирование подобных вещей, вам нужно найти способ внедрить фиктивные данные, например, реализовать интерфейс службы данных, который отражает веб-запрос, но возвращает известные данные из локального файла фиктивных данных.
источник
Предложенный порядок принудительного выполнения имеет смысл только в том случае, если вы также прервали выполнение теста после первого сбоя.
Отмена запуска теста при первом сбое означает, что каждый запуск теста может выявить только одну проблему и не может найти новые проблемы, пока все предыдущие проблемы не будут устранены. Если в первом тесте обнаружена проблема, для решения которой требуется месяц, то в течение этого месяца тесты не будут выполнены.
Если вы не прервете тестовый запуск при первом сбое, то принудительное выполнение не даст вам ничего, потому что каждый неудачный тест все равно нужно исследовать. Даже если только для подтверждения того, что тест подмодуля запроса не выполняется из-за сбоя, который также был обнаружен в подмодуле создания данных.
Лучший совет, который я могу дать, - написать тесты таким образом, чтобы было легко определить, когда сбой в зависимости приводит к провалу теста.
источник
Запах, на который вы ссылаетесь, является применением неправильного набора ограничений и правил для ваших тестов.
Модульные тесты часто путают с «автоматическим тестированием» или «автоматическим тестированием программистом».
Модульные тесты должны быть небольшими, независимыми и быстрыми.
Некоторые люди неправильно читают это как «автоматизированные тесты, написанные программистом, должны быть небольшими, независимыми и быстрыми» . Но это просто означает, что если ваши тесты не маленькие, независимые и быстрые, они не являются юнит-тестами, и поэтому некоторые правила для юнит-тестов не должны, не могут или не должны применяться к вашим тестам. Тривиальный пример: вы должны запускать свои модульные тесты после каждой сборки, чего не следует делать для не быстрых автоматических тестов.
Хотя ваши тесты не являются юнит-тестами, это означает, что вы можете пропустить одно правило и иметь возможность иметь некоторую взаимозависимость между тестами, но вы также обнаружили, что существуют другие правила, которые вы, возможно, пропустили и должны будете ввести заново - что-то для целей другого вопроса. ,
источник
Как отмечалось выше, то, что вы запускаете, похоже, является интеграционным тестом, однако вы заявляете, что:
И это может быть хорошим местом для начала рефакторинга. Модуль, выполняющий запросы к данным, не должен зависеть от конкретной реализации первого (генерирующего данные) модуля. Вместо этого было бы лучше внедрить интерфейс, содержащий методы для доступа к этим данным, а затем их можно смоделировать для тестирования запросов.
например
Если у вас есть:
Вместо этого предпочитаю:
Это удаляет зависимость от запросов к вашему источнику данных и позволяет вам настраивать легко повторяемые модульные тесты для определенных сценариев.
источник
В других ответах упоминается, что упорядочивание тестов является плохим (что верно в большинстве случаев), но есть одна веская причина для обеспечения порядка при выполнении тестов: убедитесь, что ваши медленные тесты (т.е. интеграционные тесты) выполняются после ваших более быстрых тестов (тестов). которые не полагаются на другие внешние ресурсы). Это гарантирует, что вы выполняете больше тестов быстрее, что может ускорить цикл обратной связи.
источник