0

I've been looking for resources on how to extend JUnit4 with my own annotations.

I'd like to be able to define a @ExpectedProblem with which I could label some of my tests. I've seen there seems to be some material on the net on how to extend TestNG, but I could fine none to extend JUnit4.

Has anyone here extended JUnit4 in the past?

Thanks

devoured elysium
  • 101,373
  • 131
  • 340
  • 557
  • If by @ ExpectedProblem, you mean you're expecting the test to fail, you may be interested in a JUnit @ Rule, available at: https://github.com/ttsui/pending (Disclaimer: that was written by a colleague of mine). – Grundlefleck Aug 04 '11 at 08:20
  • Thanks, but it is not related in any way to pending tests nor expecting the test to fail. What I need is something similar, indeed, to @Test(expecting = Exception), but only a bit different. – devoured elysium Aug 04 '11 at 08:29

2 Answers2

2

Depending on what you want your @ExpectedProblem annotation to do, another option is to create a @Rule.

This requires JUnit 4.7+, but should be simpler than implementing your own Runner.

For instance, if you want an annotation to say, "this test should throw an exception" then you'll want to take a look at the @ExpectedException rule. Even if that's not enough for your needs it can provide a good starting point for implementing your own rule.

Alistair A. Israel
  • 6,417
  • 1
  • 31
  • 40
  • Rules seemed like a nice idea at first until I saw that "The advantage of this approach over Rules is that Rules are always class scoped" @ http://stackoverflow.com/questions/6099633/does-testng-support-something-like-junit4s-rule/6100111#6100111. I need them to be method scoped (I may want to have 1 method with my annotation and another one without it!). – devoured elysium Aug 04 '11 at 08:53
  • @devoured elysium Within your method rule, you can check for the presence of any particular annotation on the method, and have the Rule act as a noop if the annotation is missing. – Grundlefleck Aug 04 '11 at 09:23
  • +1 on Grundlefleck's comment @devoured elysium That's exactly what I'd do—check the target of the `MethodRule` upon invocation for the annotation we're interested in, and modify the test execution based on that. – Alistair A. Israel Aug 04 '11 at 13:18
1

Basic approach is to create your own class runner. For instance, by extending the org.junit.runners.ParentRunner or org.junit.runners.BlockJUnit4ClassRunner classes. You would then annotate your test class with @RunWith(<your class runner>.class). In your runner, you could then analyze the test-class to check for annotations and take appropriate actions etc. Found this googling: http://tedyoung.me/2011/01/23/junit-runtime-tests-custom-runners/

This is how Spring modeled their JUnit support, using the org.springframework.test.context.junit4.SpringJUnit4ClassRunner

pap
  • 27,064
  • 6
  • 41
  • 46
  • Thanks! I'm just going to ask you the obvious: isn't there a way to avoid having to pollute all my test methods with that clumsy @RunWith()? – devoured elysium Aug 04 '11 at 08:44
  • No, AFAIK there is no way to configure a runner globally. Worth noting though is that JUnit itself recommends always using the @RunWith annotation on all your test-classes to ensure future proofing. If your test-class is a JUnit 4 test, it should be annotated @RunWith(JUnit4.class). The current release (JUnit 4) defaults to a BlockJUnit4ClassRunner unless otherwise specified. – pap Aug 04 '11 at 09:04