This affects 4.3

When I have a base class like:

@ContextConfiguration(classes = A.class)
class Base extends AbstractTestNGSpringContextTests {}

and a child class:

@ContextConfiguration(classes = A.class)
class Child extends Base {}

I noticed Spring creates separate ApplicationContext for both test classes.

This is not the expected behavior since according to the docs:

An ApplicationContext can be uniquely identified by the combination of configuration parameters that are used to load it

So by the definition outlined in the docs, these two test classes should being using the same ApplicationContext .

When I enabled cache debugging I noticed this being logged:

Storing ApplicationContext in cache under key [[MergedContextConfiguration@4f190018 testClass = Base, locations = '{}', classes = '{class A}

when trying to retrieve the ApplicationContext for the base class.

Storing ApplicationContext in cache under key [[MergedContextConfiguration@4f190017 testClass = Child, locations = '{}', classes = '{class A, class A}

when trying to retrieve the ApplicationContext for the child class.

I expect the cache key to be the same here, why is it different?

Deliverables

Ignore duplicate test configuration annotation (for the following list of annotations) when a given test class declares the exact same annotation (or equivalent merged annotation) as the next level above the current test class in the inheritance class hierarchy or enclosing class hierarchy.

Effectively, we want to remove exact duplication resulting from copy-n-paste errors before building the MergedContextConfiguration for a given test class.

  • [x] @ContextConfiguration
  • [x] @ActiveProfiles
  • duplicates are already removed via the use of a LinkedHashSet in ActiveProfilesUtils.resolveActiveProfiles()
  • See also #25973
  • [x] @TestPropertySource

Comment From: sbrannen

I expect the cache key to be the same here, why is it different?

They are different, because Base only declares A.class; whereas, Child declares A.class and also inherits A.class from Base.

If you don't want this to happen, you have two options.

  1. Don't redeclare @ContextConfiguration(classes = A.class) on Child, because it's inherited from Base.
  2. Instruct Spring not to inherit the configuration classes via @ContextConfiguration(classes = A.class, inheritLocations = false) on Child.

Out of curiosity, why do you redeclare the exact same configuration on Child?

Comment From: sbrannen

In any case, I'll investigate whether it's feasible to ignore such duplicate configuration metadata within a test class hierarchy for Spring Framework 5.3.

Comment From: dfit99

Hi Sam,

Thank you for the quick response.

As to answer your question, we had no good reason (just dumb copying and pasting) to use the same ContextConfiguration in the child class.

However, we also didn't expect it to behave this way either.

Thank you again for looking into this issue!

Comment From: sbrannen

I've added a "Deliverables" section to this issue's description to define and limit the scope of this issue.

Comment From: sbrannen

Current work on this issue can be viewed in the following feature branch.

https://github.com/spring-projects/spring-framework/compare/master...sbrannen:issues/gh-25800