One of the issues in the current development of my plug-in is better testing. If you have many different tests to run manual testing becomes difficult. Here comes automated testing into play. If you want to further the quality of your code you have to test after every change. Manually this is not possible. So I decided to use an integration server. Hudson springs to mind. The installation is easy: download the Hudson.war and then start it up with java -jar Hudson.war
then you can access it over the browser at http://localhost:8080. The setting up of a project is a bit more complex.
For better illustration let’s take an example. We create a Freestyle project that I named Hudson Integration. As a source of our Suite we take my Eclipse project ch.sahits.hudson. Firstly we add the SCM-System which is SVN and add the root of the project:
https://codegenjava.svn.sourceforge.net/svnroot/codegenjava/trunk/ch.sahits.hudson
As I want to run a build when something on the project changed I set the pull mechanism for the SCM to:
*/30 * * * *
This checks every 30 minutes for changes. That ensures the build to be up to date but prevents a build for small consecutive changes.
Now we can run it for the first time. If something fails you probably have the wrong URL for the repository. Go into the build and check out the console output.
This project comes with a build.xml. Previously I used build.xmls to execute from within Eclipse. I soon learned there are some chinks you have to consider:
- It may be necessary to provide the location for the JAVA_HOME and ANT_HOME. If it is needed and where it is located differs from Installation to Operating System. On my Ubuntu installation it was /usr/share/ant
- In your Eclipse installation some folders exists that are not in the repository (i.e. bin). Since Hundson checks out from the repository the build script must ensure that the needed folder exist.
- The build.xml must be part of the project. It is not possible to reference a file outside the ’scope‘ of the Hudson workspace
- I used my build.xml for loacal builds. That means some of the paths where hard coded. When you check in your build.xml it must be self contained. One way to achieve this is to put i.e. libraries into your project. Another way is to parametrize your build. The local path is defined in Hudson and not in the build script.
- All this does not work in the case of an Eclipse plug-in. Such a project has build dependencies into the installation directories. It is unwise to copy these into your plugin. It would make the plug-in self contained, quite huge and inflexible, because you are responsible for updating the libraries. This is the point where code for this example comes in. Based on the manifest file and the build properties an build.xml is created. Therefore you can first run this build script generation and than run the generated build script. (Basically that’s the same as you do in Eclipse)
Now let’s add our ant build into the Hudson build. It is essential, that you know the inner workings of your build.xml (dependencies). We define a first Ant call: clean compile jar javadoc
The jar target depends on clean and compile. This is O.K. but let’s keep this in mind: If we would put the javadoc target before the jar target, the jar target would clean everything up and the JavaDoc would be lost.
Then we define a separate ant call for the test
target.
To round this off we want to publish the results:
JavaDoc: ch.sahits.hudson/doc
Artifacts: ch.sahits.hudson/sahitsHudson_*.jar
Test-Results: ch.sahits.hudson/test_output/*.xml
Don’t check the aggregate downstream test results if you have no projects to build after that. If you check this your tests are run but not displayed.
Let us make this example a bit more interesting. The build xml contains a target findbugs. To execute successfully you have to download FindBugs and extract findbugs-ant.jar to $ANT_HOME/lib. The build.xml contains also tools for test coverage. Download Cobertura and extract the jars from the base and lib folder into $ANT_HOME/lib.
Next you have to add the FindBugs and Cobertura plug-ins for Hudson. To activate them you have to restart Hudson.
Let us do the simplier one first: Cobertura.
Go back to your configuration. In your ant call for the test append coverage
as second target. The check the publishing results: **/coverage.xml
. Done.
The findbugs is a bit more complicated since you have to pass the home directory of findbugs. On my Ubuntu box I have put them into /opt/findbugs. On Windows it is C:\Programme\findbugs-1.3.9. The findbugs target is dependent on jar so lets put it behind jar in the first ant call. Additionally we must supply the property fidebugs.home. We do this be expanding the ant call and define findbugs.home=C:\\Programme\\findbugs-1.3.9
in the system property. Replace your correct path. Now what’s left to do is publish the analyse result: check the appropriate box and fill **/findbugs.xml
in.
To conclude a word of caution. If some things don’t work out exactly as described here it may also be that you use a different version of Hudson or a plugin. I did for example experience problems with the combination of Hudson 1.322 and FindBugs 3.11, whereas 3.10 worked fine.
Multiple artefacts
I wanted to gather artefacts of different types, i.e. jar files and zip archives. This can easily be done by defining the artefacts to be gathered as follows:
**/*.jar, **/*.zip
Different sources are separated by a comma and a space. I am not sure the space is needed, but it does work that way.