Skip to content

Provide meta-annotation support for test-related annotations [SPR-7827] #12483

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
15 tasks done
spring-projects-issues opened this issue Dec 17, 2010 · 7 comments
Closed
15 tasks done
Assignees
Labels
in: test Issues in the test module type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Dec 17, 2010

Sam Brannen opened SPR-7827 and commented

Overview

Spring 3.0 already allows component stereotypes to be used in a meta-annotation fashion, for example by creating a custom @TransactionalService stereotype annotation which combines @Transactional and @Service in a single, reusable, application-specific annotation.

As mentioned in various forums, a JIRA comment, and discussions I've had with Spring users, it would be beneficial to provide similar meta-annotation support for test-related annotations.

Given a custom @TransactionalTest stereotype annotation (see code listing below), multiple test classes in the application's test suite could rely on centralized configuration of the context and transaction configuration and thus avoid unnecessary duplication. See UserRepositoryIntegrationTests for an example.

Notes on JUnit

Naturally, Spring cannot provide meta-annotation support for JUnit's @RunWith annotation, since @RunWith is processed by JUnit internals. Developers would therefore still be required to specify SpringJUnit4ClassRunner as the runner for each individual test class.


Deliverables

Provide meta-annotation support for the following annotations within the context of the TestContext framework.

  1. @ContextConfiguration
  2. @WebAppConfiguration
  3. @ContextHierarchy
  4. @ActiveProfiles
  5. @DirtiesContext
  6. @TestExecutionListeners
  7. @IfProfileValue
  8. @ProfileValueSourceConfiguration
  9. @Transactional
  10. @BeforeTransaction
  11. @AfterTransaction
  12. @TransactionConfiguration
  13. @Rollback
  14. @Repeat
  15. @Timed

Code Examples

@Transactional
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
public @interface TransactionalTest {}
@TransactionalTest
@RunWith(SpringJUnit4ClassRunner.class)
public class UserRepositoryIntegrationTests { /* ... */ }

Further Resources


Affects: 3.0.5

Issue Links:

Referenced from: commits 5e7021f, 2bd5a53, 412f74f

8 votes, 11 watchers

@spring-projects-issues
Copy link
Collaborator Author

Neale Upstone commented

That's the job.

I recall having raised the issue of meta-annotations for JUnit a while back and it getting declined. Can't find it now. Prob pre-dates their shift to githubs issue tracking.

@spring-projects-issues
Copy link
Collaborator Author

Neale Upstone commented

Just working on the JUnit end on this with aim of getting it merged in to 4.9, such that the above example would go further and add the @RunWith to TransactionalTest (the JUnit issue tracking this, with associated patches is https://github.com/KentBeck/junit/issues/194/)

On the Spring end, what you've identified for the test component is also applicable elsewhere, in that meta-annotations are inconsistently supported, which is not a good position to be in as a Spring user.

I'd like to see the scope of this broadened to be that AnnotationUtils is used as widely as possible in place of Method.getAnnotation() and Class.getAnnotation().

@spring-projects-issues
Copy link
Collaborator Author

Giovanni Dall'Oglio Risso commented

I'm working on a project, whose architecture is plugin-structured, and the Application Context files are loaded with "classpath*:**/*-Context.xml" directive.

The structure of the project is a "matrix":

  • common-core and common-batch are the core libraries
  • ext1-core and ext1-batch are the extensions

In short: the library ext1-batch depends on all the others, but ext1-core and common-batch does not mix.

So: I imagined this configuration, which makes use of meta-annotations described in this issue.

@ContextConfiguration([...]) // config for HSQLDB environment
public @interface InRamEnvironment
@ContextConfiguration([...]) // config for Oracle test environment
public @interface OracleEnvironment
@ContextConfiguration([...]) // config for common-core part
public @interface CommonCoreIntegrationTest
@ContextConfiguration([...]) // config for common-batch part
@CommonCoreIntegrationTest // decorating with common-core
public @interface CommonBatchIntegrationTest
@ContextConfiguration([...])  // config for ext1-core part
@CommonCoreIntegrationTest // decorating with common-core
public @interface ExtOneCoreIntegrationTest
@ContextConfiguration([...]) // config for ext1-batch part
@CommonBatchIntegrationTest // decorating with common-batch
@ExtOneCoreIntegrationTest // decorating with ext1-core
public @interface ExtOneBatchIntegrationTest
@ExtOneBatchIntegrationTest
@InRamEnvironment
public class OneBatchTest {

[...]

}

...but to use this configuration, it is necessary set up the recognition of meta-annotations, at least for part of the @ContextConfiguration.

So, I picked up your code, I developed the feature, and I allowed myself to make a pull request: #201

For the rest of the issue, I realize that there's more work to be done.

In the meantime I would be grateful if you would consider my little addition, and make available this improvement as soon as possible, perhaps since the version 3.2

Thank you for the attention, and for your great framework...

@spring-projects-issues
Copy link
Collaborator Author

Neale Upstone commented

Update on earlier JUnit link (although not strictly relevant to this. JUnit has moved repo to junit-team: so above link becomes junit-team/junit4#194).

Also, above pull request has now been superceded by #219

@spring-projects-issues
Copy link
Collaborator Author

Giovanni Dall'Oglio Risso commented

My pull request is a year old.

I would not bet a dollar that can be rebased without going crazy...
By the way, is there someone who is already working on, and has already figured out what to do?
Otherwise I would neither bet that you can make into the 4.0.RC1 milestone (10 days from now, and some other things to work)...

If you agree to postpone this issue to the 4.0.RC2 (and give me a month), I would love to try to help.
Obviously (since you know your framework better than me) you should also support me, discussing together to figure out the best solution :)

Thank you.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Oct 23, 2013

Sam Brannen commented

Giovanni Dall'Oglio Risso et al,

I have in fact been working on this feature in my #12483 branch on GitHub. So feel free to track the progress there.

Please note, however, that the current implementation is in line with the original intent of this issue: to allow test-related annotations to be used as meta-annotations within the TestContext framework (TCF). In other words, after this work is committed to master, developers will be able to create custom stereotype annotations for use with the TCF. Therefore, the implementation that will make it into 4.0 RC1 does not allow for sourcing @ContextConfiguration or @ContextHierarchy from multiple custom stereotype annotations on a single test class.

Regards,

Sam

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

This issue has been addressed as described in the comments for GitHub commit 2bd5a535e1.

Provide meta-annotation support in the TCF

Spring 3.0 already allows component stereotypes to be used in a
meta-annotation fashion, for example by creating a custom
@TransactionalService stereotype annotation which combines
@Transactional and @Service in a single, reusable, application-specific
annotation. However, the Spring TestContext Framework (TCF) currently
does not provide any support for test-related annotations to be used as
meta-annotations.

This commit overhauls the TCF with regard to how annotations are
retrieved and adds explicit support for the following annotations to be
used as meta-annotations in conjunction with the TCF.

  • @ContextConfiguration
  • @ContextHierarchy
  • @ActiveProfiles
  • @DirtiesContext
  • @IfProfileValue
  • @ProfileValueSourceConfiguration
  • @BeforeTransaction
  • @AfterTransaction
  • @TransactionConfiguration
  • @Rollback
  • @TestExecutionListeners
  • @Repeat
  • @Timed
  • @WebAppConfiguration

Note that meta-annotation support for @Transactional was already
available prior to this commit.

The following is a summary of the major changes included in this commit.

  • Now using AnnotationUtils.getAnnotation() instead of
    Class.getAnnotation() where appropriate in the TestContext Framework.
  • Now using AnnotationUtils.findAnnotation() instead of
    Class.isAnnotationPresent() where appropriate in the TestContext
    Framework.
  • Introduced findAnnotationPrefersInteracesOverLocalMetaAnnotations() in
    AnnotationUtilsTests in order to verify the status quo.
  • AnnotationUtils.findAnnotationDeclaringClass() and
    AnnotationUtils.findAnnotationDeclaringClassForTypes() now support
    meta annotations.
  • Introduced MetaAnnotationUtils and AnnotationDescriptor in the
    spring-test module.
  • Introduced UntypedAnnotationDescriptor in MetaAnnotationUtils.
  • Introduced findAnnotationDescriptorForTypes() in MetaAnnotationUtils.
  • ContextLoaderUtils now uses MetaAnnotationUtils for looking up
    @ActiveProfiles as a potential meta-annotation.
  • TestContextManager now uses MetaAnnotationUtils for looking up
    @TestExecutionListeners as a potential meta-annotation.
  • DirtiesContextTestExecutionListener now uses AnnotationUtils for
    looking up @DirtiesContext as a potential meta-annotation.
  • Introduced DirtiesContextTestExecutionListenerTests.
  • ProfileValueUtils now uses AnnotationUtils for looking up
    @IfProfileValue and @ProfileValueSourceConfiguration as potential
    meta-annotations.
  • @BeforeTransaction and @AfterTransaction now support ANNOTATION_TYPE
    as a target, allowing them to be used as meta-annotations.
  • TransactionalTestExecutionListener now uses AnnotationUtils for
    looking up @BeforeTransaction, @AfterTransaction, @Rollback, and
    @TransactionConfiguration as potential meta-annotations.
  • Introduced TransactionalTestExecutionListenerTests.
  • @Repeat and @Timed now support ANNOTATION_TYPE as a target, allowing
    them to be used as meta-annotations.
  • SpringJUnit4ClassRunner now uses AnnotationUtils for looking up
    @Repeat and @Timed as potential meta-annotations.
  • Moved all remaining logic for building the MergedContextConfiguration
    from the DefaultTestContext constructor to
    ContextLoaderUtils.buildMergedContextConfiguration().
  • Verified meta-annotation support for @WebAppConfiguration and
    @ContextConfiguration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: test Issues in the test module type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants