Reputation: 1545
I have a Java codebase that is developed exclusively in Eclipse. There are a set of JUnit4 tests that can be divided into two mutually exclusive subsets based on when they are expected to run:
The two types of tests might sit adjacent to each other in the same Java package. (Ideally we could intermix them in the same class, though that's not a hard requirement.)
My first solution was to annotate the "Runtime" test classes with a new
@TestOnLaunch
annotation. The application is able to find these classes,
and was running the tests contained in them (annotated with @Test
) using
JUnitCore.run(Class<?>...)
. However, these tests leak into the
"Standard" scenario above, because the Eclipse test runner will run any
method annotated with @Test
, regardless of the intent of my custom class
annotation.
Next I tried moving the @TestOnLaunch
annotation to the method level.
This prevents the "leakage" of the "Runtime" tests into the "Standard"
scenario, but now I can't seem to get JUnitCore
to run those test
methods. run.(Request)
with a Request
targeted at the correct class and
method, for example, fails with "No runnable methods", presumably
because it can't find the @Test
annotation (because it's not there).
I'm very interested to know if there's a "JUnit way" of solving this
kind of problem. Presumably I could write my own Runner
(to run methods
annotated with @TestOnLaunch
)—is this the right approach? If so, how do
I then kick off the testing programmatically with a bunch of classes,
analogous to calling JUnitCore.run(Class<?>...)
?
Upvotes: 2
Views: 2921
Reputation: 7283
If you don't mix the two type test method in the same test class, this below may help:
http://johanneslink.net/projects/cpsuite.jsp
You can use the filter feature to setup two test suite.
I setup three test suites in my project by defining several mark interfaces:
UnitTests, IntegrationTests, DeploySmokeTests, AcceptanceTests
And three test suites:
@RunWith(ClasspathSuite.class)
@SuiteTypes({UnitTests.class, IntegrationTests.class})
public class CommitTestSuite {}
@RunWith(ClasspathSuite.class)
@SuiteTypes({DeploySmokeTests.class})
public class DeploySmokeTestSuite {}
@RunWith(ClasspathSuite.class)
@SuiteTypes({AcceptanceTests.class})
public class AcceptanceTestSuite {}
Now you could achieve your goal by running specific test suite. An alternative solution is using junit category:
@Category(IntegrationTests.class)
public class SomeTest {
@Test
public void test1() {
...
}
@Test
public void test2() {
....
}
}
@RunWith(Categories.class)
@IncludeCategory(UnitTests.class, IntegrationTests.class)
@SuiteClasses( { //all test classes })
public class CommitTestSuite {}
As I said if you mix differenct type test method in one test class, the first one can't help you, but by using the seconde solution you could annotate your category interface on test method (I annotated it on test class in the example above). But if you choose the second solution, you have to maintain your test suite every time you add a new test class.
Upvotes: 3
Reputation: 77167
First, you should reevaluate why you're using JUnit tests at runtime; that seems like an odd choice for a problem that probably has a better solution.
However, you should look at using a Filter
to determine which tests to run, possibly in conjunction with a custom annotation.
Upvotes: 2