spring-projects / spring-projects/spring-framework

Inconsistent behaviour of inheritance of `@ActiveProfiles`

Open
#35,484 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: test status: waiting-for-triage
Dominant language
Java
Stars
60.2k
Forks
38.8k
Avg merge
5d 2h
Merged PRs (30d)
27

Description

I find the inheritance behaviour of @ActiveProfiles to be a bit confusing. According to the documentation the inheritProfiles property allows to define "Whether bean definition profiles from superclasses and enclosing classes should be inherited.".

Technically, this is indeed the behaviour. If I create this meta-annotation:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@SpringBootTest
@ActiveProfiles("integration-test")
public @interface MyAppSpringBootTest {
}

and I have this base class:

@MyAppSpringBootTest
public abstract class AbstractTestClass {
}

Then, I can write this test and it works:

@ActiveProfiles("extra-profile")
public class ExampleTestUsingClass extends AbstractTestClass {

  @Autowired
  private Environment environment;

  @Test
  void test() {
    assertThat(environment.getActiveProfiles())
        .containsExactlyInAnyOrder("integration-test", "extra-profile");
  }
}

What surprised me was that it does not work with an interface. So if I have this interface:

@MyAppSpringBootTest
public interface AbstractTestInterface {
}

Then this test will fail:

@ActiveProfiles("extra-profile")
public class ExampleTestUsingInterface implements AbstractTestInterface {

  @Autowired
  private Environment environment;

  @Test
  void test() {
    assertThat(environment.getActiveProfiles())
        .containsExactlyInAnyOrder("integration-test", "extra-profile");
  }
}

Only extra-profile is active.

What also fails is this:

@MyAppSpringBootTest
@ActiveProfiles("extra-profile")
public class ExampleTest {

  @Autowired
  private Environment environment;

  @Test
  void test() {
    assertThat(environment.getActiveProfiles())
        .containsExactlyInAnyOrder("integration-test", "extra-profile");
  }
}

This last example is what I actually want to use, I like to avoid base classes or interfaces for my test. Just using meta-annotations feels the "cleanest" to me.

Would it be possible to align this behaviour?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the ActiveProfiles inheritProfiles documentation and compare the superclass, interface, and meta-annotation examples described in the issue. Trace how these annotation forms are handled, then add or update coverage so the intended profile inheritance is consistent and the examples activate both profiles.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.