As you code, you should write a unit test for each class to test the functionality and robustness of the class. This is made much easier by using JUnit.
JUnit is very good at:
- capturing a Jira bug report in a reproducable manner
- allowing you to specify exactly the behaviour your want - before you start coding
- unit testing
The general idea:
- If you are testing src/org/geotools/module/HelloWorld.java
- create a file test/org/geotools/module/HelloWorldTest.java
- any public void methods starting with test will be run by JUnit
- maven will run all tests for your module using: mvn test
tests can be ignored using you pom.xml file - maven will not "release" your module into the repository while it still fails unit testing
| Code Coverage vs Regression Testing Code Coverage reports are available via: mvn site The percentage reported is based on the lines of code your test cases manage to test, please limit this to "real" tests - although we demand 60% test coverage for supported modules we would much rather this is produced honestly. Creating boiler plate tests that just call assertEquals against every method, and cutting and pasting the current result is an example of a regression test. While this will catch changes in our codebase it is not nearly as useful as actually testing for what you expect. |
Use of Maven Test Profiles
You can also make use of maven profiles to isolate long running tests from the day to day grind of other GeoTools developers.
Install with all normal tests:
mvn install
Install with online tests (will connect to servers around the world):
mvn -P online install
Install with stress tests (long running tests that try to break the code using many threads):
mvn -P stress install
You can combine profiles as needed:
mvn -P online,stress install
|
To keep build times down (so tests are run at all) we ask you to stay in the following time limits.
|
Tests on unsupported modules are not subject to a time limit, to run your tests in an unsupported module you will need to make use of the provided profile:
mvn -P unsupported install
Example TestCase
package org.geotools.module; import org.geotools.map.BoundingBox; /** * Unit test for BoundingBox. * * @author Cameron Shorter */ public class HelloWorldTest extends TestCase { /** Test suite for this test case */ private TestSuite suite = null; /** * Constructor with test name. */ public HelloWorldTest(String testName) { super(testName); } /** * Main for test runner. */ public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } /** * Required suite builder. * @return A test suite for this unit test. */ public static Test suite() { TestSuite suite = new TestSuite(HelloWorldTest.class); return suite; } /** * Initialize variables */ protected void setUp() { // initialize variables } /** Test normal constuctors. */ public void testHello(){ assertTrue("HelloWorld should return null is true",HelloWorld.isNull()); } }
Testing with junit is as easy as copying HelloWorldTest.java and adding more tests, and then executing it. If you want more information, look at the junit documentation or read one of the many junit tutorials.
Online Tests
We make use of a naming convention, ie ensure the name of your TestCase ends in OnlineTest, to indicate the use of external web services and databases.
These tests will be skipped as part of the normal build process, but will be executed by certain build boxes and .
In addition to the naming convention, such tests should extend the OnlineTestCase class, since it will extract connection parameters from fixture properties files in the user's ~/.geotools directory with minimal hassle. Test cases extending this class will need to implement the getFixtureId() method which will return the identifier for a fixture; a fixture id of "postgis.typical" will attempt to read the file "~/.geotools/postgis/typical.properties".
Each module should try to provide default fixture files pointing to publicly accessible servers. Users running online tests will copy these defaults and customize them accordingly. If a fixture file is missing, its tests will not be run; therefore, if one deletes the ~/.geotools/oracle directory, for example, all oracle online tests will be disabled.
For more details see: Online Test Fixtures, which defines the identity of each fixture and what its expected qualities and contents are.
Example Use
Example use (using PostgisOnlineTestCase):
public abstract class PostgisOnlineTestCase extends OnlineTestCase { protected DataStore dataStore; protected abstract String getFixtureId(); protected void connect() throws Exception { Map params = getParams(); dataStore = new PostgisDataStoreFactory().createDataStore(params); } public Map getParams() { Map params = new HashMap(); params.put(PostgisDataStoreFactory.DBTYPE.key, "postgis"); params.put(PostgisDataStoreFactory.HOST.key, fixture.getProperty("host")); params.put(PostgisDataStoreFactory.PORT.key, fixture.getProperty("port")); params.put(PostgisDataStoreFactory.SCHEMA.key, fixture.getProperty("schema")); params.put(PostgisDataStoreFactory.DATABASE.key, fixture.getProperty("database")); params.put(PostgisDataStoreFactory.USER.key, fixture.getProperty("user")); params.put(PostgisDataStoreFactory.PASSWD.key, fixture.getProperty("password")); if (fixture.containsKey("wkbEnabled")) { params.put(PostgisDataStoreFactory.WKBENABLED.key, fixture.getProperty("wkbEnabled")); } if (fixture.containsKey("looseBbox")) { params.put(PostgisDataStoreFactory.LOOSEBBOX.key, fixture.getProperty("looseBbox")); } return params; } protected void disconnect() throws Exception { dataStore = null; } }
Example LocalPostgisOnlineTest
And here is a sample use:
class LocalPostgisOnlineTest extends PostgisOnlineTestCase { protected abstract String getFixtureId(){ return "local"; } }
|
As a rule of thumb, online tests should not fail if a server is unavailable. |
Example Fixture
Example fixture ~/.geotools/postgis/local.properties:
host=localhost
port=15234
schema=bc
user=postgres
passwd=postgres
database=bc
wkbEnabled=true
|
In windows you cannot create a ".geotools" folder!
|
Examples:
PostgisOnlineTestCase - Abstract Testcase class which connects to a specified database and creates a datastore
PostgisPermissionOnlineTest - Simple online test which makes use of PostgisOnlineTestCase