There are different notions of what an unit test actually is. While most will agree that it is a test that verifies a pretty small part of a software system, we don’t all agree on how big a part this is. Personally I want a unit test to cover as little as possible. This, I think, makes the tests more manageable and makes it more likely that we can execute them with a minimum of fuss and in the shortest time possible. The following sums it up:
A unit test is an automated piece of code that invokes the smallest testable part of a system and then checks a single assumption about the behavior of that part.
Because a these tests verifies such a small part of the system I think a unit test should be in the same bundle as the code it is testing. And since it is only testing code contained withing the same bundle, it won’t need any extra dependencies (except for Junit). Setting this up when using the traditional PDE Build cannot be easily done without including test code in deployed bundles. As a workaround you can create a plug-in fragment to host unit tests. That will work, but causes other complications. Apart from the hassle of managing an extra bundle, you will for example not be able to verify platform specific code hosted in a fragment using tests hosted in another fragment. You’ll want these tests to be in the platform specific fragment.
Hosting the tests in the same bundle as the tested code is not very straightforward when using Tycho and Maven either, but it is possible and well worth the effort. I’d like to propose a solution.
The first thing we’ll do is to set up the project in the Eclipse IDE. As you may know, Maven by default expects a root src folder with main and test subfolders. This layout is not commonly found in Eclipse bundles, nor is it default when creating new plug-ins. Also we don’t want the eclipse-plugin packaged bundles to include the tests. So that’s why I elected to add another src-test folder instead. Do as follows:
- Add a new source folder for tests, src-test
- Exclude this in build.properties by adding
src.excludes = src-test/
- Add Junit libraries to the build path. Go to Project properties > Java Build Path > Libraries. Add “Junit 4”.
Unit tests now go in the src-test folder of the bundle. And because the dependecy to Junit 4 is added to project properties and not the MANIFEST.MF, we can compile and run the test code without the org.junit bundle ending up in the product. To hone you TDD skills you may now consider installing a tool for continusly running your unit tests. Infinitest is a good candidate.
Tycho will not automatically pick up these tests so we need to add some configuration in the pom.xml to let Maven know that we have these:
- The test source folder must be specified (src-test).
- The Maven compiler plug-in must be bound to the test-compile phase so the tests gets compiled.
- The Maven Surefire plug-in must be activated
${project.basedir}/src-test
...
org.apache.maven.plugins
maven-surefire-plugin
2.12.4
test
test
**/*Test.java
test
org.apache.maven.plugins
maven-compiler-plugin
2.5.1
compiletests
test-compile
testCompile
And that’s all there’s to it. Now, integration tests and UI tests should go into separate bundles packaged as eclipse-test-plugin as before. These will be executed in the Maven integration-test phase. Well after the test phase in which these tests will execute. So if there are any issues uncovered by the unit tests, the build will fail as soon as possible.
References: