I am currently using JUnit 4 and have a need to divide my tests into groups that can be run selectively in any combination. I know TestNG has a feature to annotate tests to assi
You can create suites, although that puts all the configuration in the suite, and not in annotations.
my advice is simply ditch JUnit and use TestNG. Once you get used to TestNG, Junit looks like Stone Age.
No, there is no similar concept to TestNG groups, unfortunately. It was planned for JUnit4, but for some unclear reason, it was dropped from the planning.
Check out Spring's SpringJUnit4ClassRunner. I've used it to optionally run tests based on a System property, using the IfProfileValue annotation.
This:
@IfProfileValue(name="test-groups", values={"unit-tests", "integration-tests"})
public void testWhichRunsForUnitOrIntegrationTestGroups() {
// ...
}
Will run if the System property 'test-groups' is set to either 'unit-tests' or 'integration-tests'.
Update: JUnitExt has @Category
and @Prerequisite
annotations and looks like it should do what you need. However, I've never used it myself, so I can't vouch for it.
TestNG has my vote. It's annotation based, can run as Groups, single Tests, etc, can be linked into Maven, and can run all JUnit tests as part of it's test runs.
I highly recommend it over JUnit.
First, you are addressing two problems - unit tests (often in the same package as the unit under test) and integration tests. I usually keep my integration tests in a separate package, something like com.example.project.tests. In eclipse, my projects look like:
project/
src/
com.example.project/
tsrc/
com.example.project/
com.example.project.tests/
Right-clicking on a package and selecting 'run' runs the tests in the package; doing the same on the source folder runs all the tests.
You can acheive a similar effect, although you expressed a disinterest in it, by using the Suite runner. However, this violates DRY - you have to keep copies of the test names up to date in the suite classes. However, you can easily put the same test in multiple suites.
@RunWith(Suite.class)
@Suite.SuiteClasses( {
TestAlpha.class,
TestBeta.class })
public class GreekLetterUnitTests {
}
Of course, I really should be keeping these things automated. A good method for doing that is to use the Ant task.
<target name="tests.unit">
<junit>
<batchtest>
<fileset dir="tsrc">
<include name="**/Test*.java"/>
<exclude name="**/tests/*.java"/>
</fileset>
</batchtest>
</junit>
</target>
<target name="tests.integration">
<junit>
<batchtest>
<fileset dir="tsrc">
<include name="**/tests/Test*.java"/>
</fileset>
</batchtest>
</junit>
</target>