Как решать задачу запуска тестов с разными данными в разных окружениях
Что проверяют
Умеете ли вы отделить тест от окружения: один и тот же код прогоняется локально, на dev и на stage, а меняются только конфигурация и данные. Следом спрашивают, где хранить секреты и как запустить часть тестов только на одном стенде.
Как отвечать
Задача раскладывается на две оси. Данные внутри теста решает параметризация JUnit 5 (Jupiter):
@ParameterizedTestс@CsvSourceили@ValueSource: короткие наборы прямо в коде;@MethodSource: объекты посложнее, которые собирает фабричный метод;@CsvFileSource: наборы во внешних файлах, например отдельный CSV на окружение;- TestNG: тот же приём делает
@DataProvider, а значения изtestng.xmlпередаёт@Parameters.
Окружение выбирается снаружи, а не в коде:
- ключ окружения:
-Denv=stageили переменнаяENV, по которой грузитсяstage.properties. В Maven этоsystemPropertyVariablesв Surefire, удобная обёртка над конфигом есть в библиотеке Owner; - Spring: профили
application-stage.ymlи@ActiveProfiles, адреса контейнеров из Testcontainers подставляет@DynamicPropertySource; - отбор тестов:
@Tag("smoke")и группы в Surefire, условные аннотации@EnabledIfSystemPropertyи@EnabledIfEnvironmentVariable; - CI: матрица в GitLab CI или GitHub Actions, где каждая ветка матрицы запускает тот же набор со своим ключом окружения. Пароли и токены приходят из секретов CI и в репозиторий не попадают.
Хорошо добавить позицию про данные: тест сам создаёт то, что ему нужно, через API или базу, а не рассчитывает, что на stage «лежит пользователь с id 42».
Где спотыкаются
Пишут пример на JUnit 4 с @RunWith(Parameterized.class). Это устаревший подход, а смешение аннотаций из org.junit и org.junit.jupiter без vintage-движка даёт тесты, которые молча не запускаются.
Зашивают URL стенда и логины прямо в тест. Для каждого окружения появляется копия класса, а пароль уезжает в историю git.
Гоняют на проде тот же набор, что на stage. На проде допустим только читающий smoke-набор, тесты с созданием заказов и платежей туда не пускают.