[geos-devel] First glance at the Unit Test

Mateusz Łoskot mateusz at loskot.net
Sun Mar 5 20:16:24 EST 2006


Hi,

I'm sending some example of single Test Suite with a bunch of Test Cases
based on Boost Unit Test Framework.
This Test Suite is dedicated to test Envelope class, so it's called
envelope_class_test suite.
It's based on EnvelopeTest.java - JTS version of test for JUnit.
I hope this small example will give some impression about how Boost UTF
can be incorporated in GEOS.

NOTE: I tested it with VC++ 8.0, so I don't have any makefiles for now, 
only VC++ project files. If anyone is interested I can send VC++ 8.0 
project files.

INSTRUCTIONS
1. Boost

I use current CVS - 1.34 but it should work well with current stable 
1.33.1 release.
The *only* library used (that envelope_class_test is linked with) is 
Unit Test Framework. It is only one binary file. In my case with VC++ 
8.0 I linked this example with
libboost_unit_test_framework-vc80-mt-gd-1_34.lib

So, on Linux yo have to link with file named as something like:
libboost_unit_test_framework-gcc-mt-gd-1_34.a

2.
Next, save the code included below as envelope_class_test.cpp file.

NOTE: there is no main function in the example test, so don't worry
Boost will provide appropriate one :-)

Check if gcc can find header used by the example:
#include <boost/test/unit_test.hpp>

Compile and link with library above.

For instructions about how to build Boost I'd suggest to refere to:
http://boost.org/more/getting_started.html

3. After it builds without any errors, just run it as a common executable.

4. You can change a bit checks in this exmaple to catch
some errors, e.g.: change
BOOST_CHECK( e1.isNull() );
to read as
BOOST_CHECK( !e1.isNull() );

Please note, this exmaple is not going to present all features of Boost 
UTF. Simply, it's not possible in such a small piece of code :-)
After I've read whole Boost.Test documentation I only analyzed Unit Test 
Framework (one of Boost.Test component) according to usage in GEOS,
so this example presents only basic idea of:
- how test cases set in Boost UTF look like
- how test suites look like
- what output you can get
- what are basic checks (macros)

There are many many more features which can be used to develop 
sophisticated Unit Tests, cases and suits but I think we can explore 
them later, after Boost.Test will be incorporated in GEOS.

So, I'm interested in your comments and suggestions.
Do you like it or not, should I procede with implementation of
the rest of tests?


Here is the file:

///////////////////////////////////////////////////////////////////////////////
// envelope_class_test.cpp

// BOOST
#define BOOST_TEST_MODULE envelope_class_test
#include <boost/test/unit_test.hpp>

// GEOS
#include <geos/geom.h>

// Test Suite
BOOST_AUTO_TEST_SUITE( envelope_class_test );

BOOST_AUTO_TEST_CASE( envelope_constructors_test )
{
     // 1 - default constructor
     geos::Envelope e1;

     BOOST_CHECK( e1.isNull() );
     BOOST_CHECK_EQUAL( e1.getWidth(), 0 );
     BOOST_CHECK_EQUAL( e1.getHeight(), 0 );

     // 2
     geos::Envelope e2(100, 200, 100, 200);

     BOOST_CHECK( !e2.isNull() );
     BOOST_CHECK_EQUAL( e2.getMinX(), 100 );
     BOOST_CHECK_EQUAL( e2.getMaxX(), 200 );
     BOOST_CHECK_EQUAL( e2.getMinY(), 100 );
     BOOST_CHECK_EQUAL( e2.getMaxY(), 200 );
     BOOST_CHECK_EQUAL( e2.getWidth(), 100 );
     BOOST_CHECK_EQUAL( e2.getHeight(), 100 );

     // 3 - copy constructor
     geos::Envelope e3(e2);

     BOOST_CHECK( !e3.isNull() );
     BOOST_CHECK_EQUAL( e3.getMinX(), 100 );
     BOOST_CHECK_EQUAL( e3.getMaxX(), 200 );
     BOOST_CHECK_EQUAL( e3.getMinY(), 100 );
     BOOST_CHECK_EQUAL( e3.getMaxY(), 200 );
     BOOST_CHECK_EQUAL( e3.getWidth(), 100 );
     BOOST_CHECK_EQUAL( e3.getHeight(), 100 );
     BOOST_CHECK( e3 == e2 );
     BOOST_CHECK( e3.equals( &e2 ) );

} // envelope_constructors_test

BOOST_AUTO_TEST_CASE( envelope_null_test )
{
     // 1 - Test isNull() and setToNull() functions
     geos::Envelope e1(100, 200, 100, 200);

     BOOST_CHECK( !e1.isNull() );
     e1.setToNull();
     BOOST_CHECK( e1.isNull() );

} // envelope_null_test

BOOST_AUTO_TEST_CASE( envelope_equals_test )
{
     // 1 - Test equals() function
     geos::Envelope e1(100, 200, 100, 200);
     geos::Envelope e2(100, 200, 100, 200);
     geos::Envelope e3(1, 2, 1, 2);

     BOOST_CHECK( !e1.isNull() );
     BOOST_CHECK( !e2.isNull() );
     BOOST_CHECK( !e3.isNull() );

     BOOST_CHECK( e1.equals( &e2 ) );
     BOOST_CHECK( !e1.equals( &e3 ) );
     BOOST_CHECK( !e2.equals( &e3 ) );

} // envelope_equals_test

BOOST_AUTO_TEST_CASE( envelope_contains_test )
{
     // Test contains() predicates
     geos::Envelope e1;
     geos::Envelope e2(-1, 1, -1, 1);
     geos::Envelope e3(-5, 5, -5, 5);

     BOOST_CHECK( !e2.isNull() );
     BOOST_CHECK( !e3.isNull() );

     // 1 - Test empty envelope by reference
     BOOST_CHECK_MESSAGE( !e1.contains( e2 ), "e1 envelope is not empty!" );
     BOOST_CHECK_MESSAGE( !e2.contains( e1 ), "e1 envelope is not empty!");

     // 2 - Test empty envelope by pointer
     BOOST_CHECK_MESSAGE( !e2.contains( &e1 ), "e1 envelope is not empty!");
     BOOST_CHECK_MESSAGE( !e1.contains( &e2 ), "e1 envelope is not 
empty!" );

     // 3 - Test non-empty envelope by reference
     BOOST_CHECK( !e2.contains( e3 ) );
     BOOST_CHECK( e3.contains( e2 ) );

     // 3 - Test raw point
     BOOST_CHECK( e2.contains( 0, 0 ) );
     BOOST_CHECK( e2.contains( -1, -1 ) );
     BOOST_CHECK( !e2.contains( 5, 5 ) );

     // 4 - Test coordinate
     geos::Coordinate c1(0, 0, 0);
     BOOST_REQUIRE_EQUAL( c1.x, 0 );
     BOOST_REQUIRE_EQUAL( c1.y, 0 );
     BOOST_REQUIRE_EQUAL( c1.z, 0 );
     BOOST_CHECK( e2.contains( c1 ) );

} // envelope_contains_test

BOOST_AUTO_TEST_CASE( envelope_intersects_test )
{
     // Test intersects() predicates
     geos::Envelope e1;
     geos::Envelope e2(-100, 100, -100, 100);
     geos::Envelope e3(50, 150, 50, 150);

     BOOST_CHECK( !e2.isNull() );
     BOOST_CHECK( !e3.isNull() );

     // 1 - Test empty envelope by pointer
     BOOST_CHECK_MESSAGE( !e1.intersects( &e2 ), "e1 envelope is not 
empty!" );
     BOOST_CHECK_MESSAGE( !e2.intersects( &e1 ), "e1 envelope is not 
empty!");

     // 2 - Test empty envelope by reference
     BOOST_CHECK_MESSAGE( !e1.intersects( e2 ), "e1 envelope is not 
empty!" );
     BOOST_CHECK_MESSAGE( !e2.intersects( e1 ), "e1 envelope is not 
empty!");

     // 3 - Test empty envelope by reference
     BOOST_CHECK( e2.intersects( e3 ) );
     BOOST_CHECK( e3.intersects( e2 ) );

     // 3 - Test point
     BOOST_CHECK( e2.intersects( 0, 0 ) );
     BOOST_CHECK( e2.intersects( -100, 100 ) );
     BOOST_CHECK( !e2.intersects( -200, 200 ) );

     // XXX - add test for Coordinate

} // envelope_intersects_test

BOOST_AUTO_TEST_CASE( envelope_expand_test )
{
     // TODO

     BOOST_CHECK_MESSAGE( false, "TEST CASE NOT IMPLEMENTED" );

} //envelope_expand_test

BOOST_AUTO_TEST_SUITE_END(); // envelope_class_test

// EOF
///////////////////////////////////////////////////////////////////////////////



-- 
Mateusz Łoskot
http://mateusz.loskot.net



More information about the geos-devel mailing list