[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,