[Biojava-l] Unit tests
Matthew Pocock
mrp@sanger.ac.uk
Mon, 14 May 2001 16:02:07 +0100
Cool Keith.
Is there any way to get ant to put the test & src files into seperate
build directories? That way the resulting biojava.jar can trivialy not
contain any test code.
I look forward to having testing in here.
M
Keith James wrote:
>>>>>> "Matthew" == Matthew Pocock <mrp@sanger.ac.uk> writes:
>>>>>
>
> Matthew> Testing would have caught several of our recurent
> Matthew> bugs. Long over-due. Parallel source trees get my
> Matthew> vote. Munging test cases under the src/ tree is an
> Matthew> over-my-dead-body option (but then you can always depose
> Matthew> me). JUnit is fine by me and seems to be the defacto
> Matthew> standard. We can let the classloader do the tree merging
> Matthew> magic necisary to test private API, but as Thomas said,
> Matthew> most of the time you will be wanting to validate that
> Matthew> implementations conform to interfaces. Does JUnit allow
> Matthew> you to define tests for an interface and then apply that
> Matthew> to a collection of objects that implement it? That would
> Matthew> be ideal for us.
>
> As far as I can see, there isn't a built-in system within JUnit for
> testing interfaces. I think we would need to write a test fixture to
> do this - is there a neat way to get from a Class object for an
> interface a list of everything which implements it?
>
> Anyway, I've set up a trial system on my local copy of the source
> which seems to work fine:
>
> source is in src/org/biojava/*
> tests are in test/org/biojava/*
>
> The copy and compile tasks take both trees and compile them in
> ant-build/src so that the source and tests stay in sync.
>
> A 'runtests' target is added which will run if JUnit is in your
> CLASSPATH:
>
> <property name="env.classpath" value="${java.class.path}" />
>
> <available classpath="${env.classpath}"
> classname="junit.framework.TestCase"
> property="junit.present" />
>
> <!-- Run tests -->
> <target name="runtests" depends="init,compile" if="junit.present">
> <junit printsummary="yes" haltonfailure="no" dir="${build.dest}">
> <formatter type="plain" usefile="true" />
> <classpath>
> <pathelement path="${classpath}" />
> <pathelement path="${env.classpath}" />
> <pathelement path="${build.dest}" />
> </classpath>
> <batchtest fork="yes" todir="${reports.tests.dir}">
> <fileset dir="${build.dest}">
> <include name="**/*JUTest*" />
> </fileset>
> </batchtest>
> </junit>
> </target>
>
> Tests are run in a forked VM to avoid accidental exiting from the VM
> Ant is running in. At the moment tests are located by Ant scanning the
> ant-build/classes directory with the pattern "**/*JUTest*" because
> there are a few non-JUnit tests in the main source tree which get
> picked up using "**/*Test*" or "**/*Test.class".
>
> The Ant test runner looks for a static suite() method in matching
> classes and runs any resulting Test returned by it. If none is present
> it makes a TestSuite (which implements Test) and adds all methods
> starting with the string 'test' to it, then runs that.
>
> Any new test classes will be picked up automatically by Ant, provided
> their names contain 'JUTest' (naming convention negiotiable). These
> are omitted from the jar packaging using the same pattern.
>
> Requires Ant 1.3 and JUnit > 3.2 (I used JUnit 3.6). JUnit should be
> on the CLASSPATH, otherwise the tests will be skipped. It doesn't add
> any external dependencies.
>
> Example test (in this case not defining it own TestSuite):
>
> package org.biojava.bio.symbol;
>
> import junit.framework.TestCase;
>
> public class RangeLocationJUTest extends TestCase
> {
> protected Location r1;
>
> public RangeLocationJUTest(String name)
> {
> super(name);
> }
>
> protected void setUp()
> {
> r1 = new RangeLocation(1, 100);
> }
>
> public void testEquals()
> {
> assertEquals(r1, r1);
> assertEquals(r1, new RangeLocation(1, 100);
> }
> }
>
>
> If this seems sensible, let me know and I'll apply the changes. If
> not, give an idea of what needs fixing.
>
> cheers,