Spring Boot / JUnit, запустите все модульные тесты для нескольких профилей
У меня есть класс BaseTest, который состоит из нескольких тестов. Каждое испытание выполняется для каждого профиля I списка.
Я думал об использовании параметризованных значений таких как:
@RunWith(Parameterized.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
// @ActiveProfiles("h2-test") // <-- how to iterate over this?
public abstract class BaseTest {
@Autowired
private TestRepository test;
// to be used with Parameterized/Spring
private TestContextManager testContextManager;
public BaseTest(String profile) {
System.setProperty("spring.profiles.active", profile);
// TODO what now?
}
@Parameterized.Parameters
public static Collection<Object[]> data() {
Collection<Object[]> params = new ArrayList<>();
params.add(new Object[] {"h2-test" });
params.add(new Object[] {"mysql-test" });
return params;
}
@Before
public void setUp() throws Exception {
this.testContextManager = new TestContextManager(getClass());
this.testContextManager.prepareTestInstance(this);
// maybe I can spinup Spring here with my profile?
}
@Test
public void testRepository() {
Assert.assertTrue(test.exists("foo"))
}
Как бы я сказал Spring запускать каждый тест с этими разными профилями? Фактически, каждый профиль будет разговаривать с разными источниками данных (в памяти h2, внешний mysql, внешний oracle, ..) поэтому мой репозиторий / источник данных должен быть повторно инициализирован.
Я знаю, что Я могу указать @ActiveProfiles(...) и я даже могу расширить BaseTest и переопределить аннотацию ActiveProfile. Хотя это будет работать, я показываю только часть моего набора тестов. Многие мои тестовые классы простираются от BaseTest, и я не хочу создавать несколько разных заглушек профилей для каждого класса. В настоящее время работает, но уродливое решение:
- BaseTest (@ActiveProfiles ("mysql"))
- FooClassMySQL (аннотация от BaseTest)
- FooClassH2 (@ActiveProfiles ("h2"))
- BarClassMySQL (аннотация из BaseTest)
- BarClassH2 (@ActiveProfiles ("h2"))
- FooClassMySQL (аннотация от BaseTest)
спасибо
2 ответов
Если вы используете Maven, вы можете указать активный профиль из командной строки (или переменную env, если необходимо):
mvn clean test -Dspring.profiles.active=h2-test
подход с параметризованным тестом может не работать в этом случае, потому что профиль должен быть указан до того, как Spring загрузит его контекст. В этом случае при выполнении параметризованного интеграционного теста контекст будет уже загружен до запуска теста Test runner. Также параметризованные тесты JUnit были изобретены по другим причинам (running unit тесты с различными рядами данных).
EDIT: также еще одна вещь - когда вы решите использовать @RunWith(Parameterized.class)
вы не сможете использовать другой бегун. Во многих случаях( если не все, если дело доходит до интеграционного тестирования) вы хотите указать другой бегун, например SpringRunner.class
- С параметризованным тестом вы не сможете это сделать.
профили весны не конструированы для работы в этом путе.
В вашем случае, каждый профиль использует определенный источник данных.
Таким образом, каждый из них требует загрузки Spring для запуска тестов с ожидаемым источником данных.
на самом деле, то, что вы хотите сделать, - это сделать столько Maven, сколько профилей Spring, которые вы хотите протестировать.
кроме того, сборки в локальном env должны быть как можно быстрее.
Умножение выполнения автоматизированных тестов СУБД реализация, требующая перезагрузки Spring Boot для каждого из них, не поможет.
вам не нужно указывать @ActiveProfiles
.
это похоже на задачу для инструмента непрерывной интеграции, где вы можете определить задание, которое выполняет (последовательно или параллельно) каждую сборку Maven, указав конкретный профиль загрузки Spring :
mvn clean test -Dspring.profiles.active=h2
mvn clean test -Dspring.profiles.active=mysql
etc...
вы также можете попробовать выполнить его на локальном языке, написав сценарий, который выполняет выполнение из maven строит.
Но, как уже было сказано, это замедлит вашу локальную сборку, а также усложнит ее.