Spring Boot / JUnit, run all unit-tests for multiple profiles

Viewed 10409

I have a BaseTest class which consists of several tests. Each test shall be executed for EVERY profile I list.

I thought about using Parameterized values such as:

@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"))
}

How would I tell Spring to run each test with these different profiles? In fact, each profile will talk to different datasources (in-memory h2, external mysql, external oracle, ..) so my repository/datasource has to be reinitialized.


I know that I can specify @ActiveProfiles(...) and I can even extend from BaseTest and override the ActiveProfile annotation. Although this will work, I only show a portion of my test-suite. Lots of my test-classes extend from BaseTest and I don't want to create several different profile-stubs for each class. Currently working, but ugly solution:

  • BaseTest (@ActiveProfiles("mysql"))
    • FooClassMySQL(annotation from BaseTest)
      • FooClassH2(@ActiveProfiles("h2"))
    • BarClassMySQL(annotation from BaseTest)
      • BarClassH2(@ActiveProfiles("h2"))

Thanks

3 Answers

For what it's worth:

My use case was to run a specific test class for multiple spring profiles, this is how I achieved it:

@SpringBootTest
abstract class BaseTest {
 @Test void doSomeTest() {... ARRANGE-ACT-ASSERT ...}
}

@ActiveProfiles("NextGen")
class NextGenTest extends BaseTest {}

@ActiveProfiles("Legacy")
class LegacyTest extends BaseTest {}
Related