1

I'm trying to write a specific JUnit Runner, and I did not find good tutorials / examples online.

The requirements are the following :

  • I will have some categorized tests (e.g A.java from category catA, B.java from category catA, C.java from Category catC
  • Each test has a single @BeforeClass method that needs to be run if the test is launched alone
  • When launching all tests from the same category, the @BeforeClass method must only be launched once.
  • Each @Test method from a Junit Test also has @Before and @After methods.

That being said, I looked at the different options available.

I started by creating Test Suites which would represent my test categories, using the provided junit Suite Runner. (@RunWith(Suite.class)) You need to manually provide the Tests in the suite, using @SuiteClasses() which is annoying.

So I looked at the ClasspathSuite Runner, which allows to put all classes from the classpath in every suite, and filter them after with @Category

It also provides a @BeforeSuite annotation that is launched once when the suite is launched.

=> Everything is almost perfect.

  • When a single test is launched, the @BeforeClass from this test is launched
  • When a Test Suite is launched, the correct Tests are launched (thanks to the @Category), the @BeforeSuite is called only once, but the @BeforeClass of every Test is also called, where it should not.

=> All these things led me to think about implementing my own Runner. I tried extending the ClasspathSuite Runner, but it is not designed to do so. I tried extending the stock Suite Runner, but I did not succeed.

Could you help me understand how to implement these requirements in a JUnit Runner?

Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121
facewindu
  • 705
  • 3
  • 11
  • 31
  • Can you be more specific as to what your problems were with extending the `ClasspathSuite` and `Suite` runners? Also, doesn't `org.junit.experimental.categories.Categories` do what you want? – blalasaadri May 26 '14 at 13:51

1 Answers1

1

How about doing it without writing a runner? Instead, write a @BeforeClass method that uses a singleton list that records each before-category method that has been run in the current test run, and that knows how to run all the before-category methods (each probably in its own class). The @BeforeClass method determines its class's @Category, checks the list, and

  • does nothing if that @Category's before-category method has already run, or
  • runs the before-category method and note in the list that that @Category's method has been run.

Not requiring a custom runner is better because it will work in environments that provide their own runners, such as IDEs and continuous integration servers.

Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121