|  |  |  | License Codehaus OpenEJB OpenJMS OpenORB Tyrex

Old releases
General
Release 1.3
Release 1.3rc1
Release 1.2

Main
Home
About
Features
Download
Dependencies
Reference guide
Publications
JavaDoc
Maven 2 support
Maven 2 archetypes
DTD & Schemas
Recent HTML changes
News Archive
RSS news feed
Project Wiki

Development/Support
Mailing Lists
SVN/JIRA
Contributing
Support
Continuous builds
Prof. services

Related projects
Spring ORM support
Spring XML factories
WS frameworks

XML
XML

XML Code Generator
XML Code Generator

JDO
Introduction
First steps
Using JDO
JDO Config
Types
JDO Mapping
JDO FAQ
JDO Examples
JDO HOW-TOs
Tips & Tricks
Other Features
JDO sample JAR

Tools
Schema generator

Advanced JDO
Caching
OQL
Trans. & Locks
Design
KeyGen
Long Trans.
Nested Attrs.
Pooling Examples
LOBs
Best practice

DDL Generator
Using DDL Generator
Properties
Ant task
Type Mapping

More
The Examples
3rd Party Tools
JDO Tests
XML Tests
Configuration

About
License
User stories
Contributors
Marketplace
Status, Todo
Changelog
Library
Contact
Project Name

## The Castor Testing Framework: Test Suite Execution and Test Creation

Documentation Author(s):
Arnaud Blandin
Sebastien Gignoux
Edward Kuns

This document describes the Castor Testing Framework, how to execute it, what test suites exist, and how, when, and where to add a test.

Abstract
Introduction
Overview of the CTF
Creating a JUnit test case
Repository architecture
CTF Test Patterns
CTF Test Types
Schema Test Patterns
Marshaling Test Patterns
Only Source Generation Test Patterns
Source Generation Test Patterns
Life Cycle of a CTF Test
Building the CTF
Running the CTF
Command Line options
The Test Description: TestDescriptor.xml
Header
The Test (Following the Header)
SchemaTest
MarshallingTest
OnlySourceGenerationTest
SourceGeneratorTest
UnitTestCase
Listener
Configuration
Call-Method
Implementing CastorTestable
dumpFields
randomizeFields
Sample Java Class for a Root_Object
Implementing ObjectModelBuilder
buildInstance
Sample Java Class for an Object Builder
Reporting a bug in Castor
Full Sample of a Source Generation Test
TestDescriptor.xml
The gold file
PrimitivesBuilder.java
Launching the Test
Launching the Test from a JAR
Launching the Test from a directory tree
Full Sample of a Marshaling Framework Test
Checklist for creating a CTF test
Status of the CTF
XML Schema for TestDescriptor.xsl
References

## Abstract

Test Automation is often seen as very useful but tedious task. However the limited number of test templates for Castor makes it easy to implement. The aim of this document is to describe the Castor Testing Framework by giving an overview of its functionalities and by providing detailed example test cases.

## Introduction

One of the main processes in the life cycle of software is the 'validation and verification' process. It is a central process that checks that the requisite functions exist and that there are no faults. It is also known as the unpopular 'testing' process. The reliability and integrity of a software project are based on tests. Being 'open-source' does not mean that one can avoiding writing tests.

However, software testing in general consumes 30 to 70 percent of software development resources, does not find all the faults, and can be just as much work as writing the original code itself. Moreover when involved in an open-source project which includes several developers and contributors, a developer needs to write tests that can be understood by the other developers without requring a great investment of time. Ideally, these tests will highlight and test a specific feature, so if they fail the current developers can quickly understand what is broken, where the problem was introduced, and how to fix it.

One solution is to choose to automated tests: as described in Seven Steps to Automation Steps by Bret Pettichord, there are several reasons to choose to automate tests:

- | Allow testing to happen more frequently,
- | Improve test coverage,
- | Ensure consistency, and
- | Improve the reliability of testing,

For all of these reasons, we have chosen to give to Castor an automated Testing Framework called the "Castor Testing Framework" (and referered to as the CTF). This framework is built with JUnit and will help Castor developers. It also helps users in several ways by:

- | Improving Castor reliability,
- | Easing the monitoring of bugs, as writing bug reports will be straightforward,
- | Building an archive of fixed bugs,
- | Easing the creation of a test.

## Overview of the CTF

In this section you will be given a quick overview of the CTF: What is the main idea behind it? Where are the tests located? What test suites exist? What are the test patterns? How do you run the tests?

Note: currently the CTF is written to test only Castor XML. A future version could test more or all of Castor functionality.

### Creating a JUnit test case

Built on top of JUnit, the CTF simply creates test cases to be run under the JUnit Framework. The main idea is to provide to the CTF the minimal information needed to build test cases (such as XML Schemas, Castor mapping files, XML documents or some initialization codes for the java object model used). With this information, the CTF can then build the tests as much as possible. This means that the developer does not need to know anything about JUnit to develop a JUnit test for the CTF.

The information necessary for a test case can be located in a JAR file or in a directory structure. A directory tree will contain all the directories and jars, and the CTF will create a global test case with these individual test cases. The CTF will dynamically build the test cases located in the different jar files and pass them to JUnit.

### Repository architecture

The code of Castor Testing Framework is located in the following Java packages:

              org.exolab.castor.tests.framework
              org.exolab.castor.tests.framework.testDescriptor
              org.exolab.castor.tests.framework.testDescriptor.types

which can be found under `xmlctf/src/main/java`.

The tests for testing the behavior of Castor and its main features are located in the directory tree starting at `xmlctf/tests/MasterTestSuite`. The tests needed to keep tracks of current reported, unfixed bugs are located in the directory tree starting at `xmlctf/tests/RegressionTestSuite`. The hierarchy of these test suites follows the main modules of Castor:

              MasterTestSuite     / xml / introspection
                                        / mapping
                                        / marshalling
                                        / schema
                                        / sourcegenerator
              RegressionTestSuite / xml / introspection
                                        / mapping
                                        / marshalling
                                        / schema
                                        / sourcegenerator

### CTF Test Patterns

"Testing Castor XML" means not only testing the Marshalling Framework but also the mapping framework and the Source Generator. Thus tests fall into one of these three categories and follow several patterns defined in this section. From now on, we will use the term "gold file" to designate a file that represents an expected result. For most tests, a gold file will be an XML file.

#### CTF Test Types

There are four kinds of tests available for use in the CTF:

- | Schema: Test schema parsing and I/O.
- | Marshaling: Test XML document marshaling and unmarshaling to and from Java classes that you provide for the object model.
- | Only Source Generation: Test source generation (only).
- | Source Generation: Test XML document marshaling and unmarshaling to and from Java classes that are created by the Castor source generator.

#### Schema Test Patterns

There is only one test pattern for a Schema test. For each schema provided:

- | The schema is read from disk and parsed.
- | The parsed schema is optionally written to disk.
- | The parsed schema is written to a new schema object in memory.
- | The new schema object is compared to the original schema object read from disk.

#### Marshaling Test Patterns

There are three patterns used for a Marshaling test. All patterns marshal and unmarshal XML using Java classes that you provide for the object model. A Marshaling test does not use the Source Generator. A given marshaling test may use any pattern in isolation or all three patterns.

The pattern "Marshal/Unmarshal with randomized reference object" is used in isolation and is enabled/disabled separately from the other marshaling test patterns. If both other patterns ("Marshal/Unmarshal with custom instantiated reference object" and "Unmarshal/Marshal with reference XML document") are used in the same test, then the object generated by the custom class must be the same as that provided by the input XML document.

How you choose which combination of test patterns will be used is described below. When testing marshaling, you can optionally also test mapping. Thus, mapping is tested using a Marshaling test.

1. Marshal/Unmarshal with custom instantiated reference object

   - | Instantiate an object model. You provide a Java class that will instantiate and initialize an object of the correct type for the test.
   - | Marshal this object to disk.
   - | Compared the marshaled object to a gold file.
   - | Unmarshal the document from disk.
   - | Compare the unmarshaled object to the original reference object.

2. Marshal/Unmarshal with randomized reference object

   - | Instantiate an object model. The CTF will instantiate an object that is populated with random data.
   - | Marshal this object to disk.
   - | Compared the marshaled object to a gold file.
   - | Unmarshal the document from disk.
   - | Compare the unmarshaled object to the original random object.

3. Unmarshal/Marshal with reference XML document

   - | Unmarshal an XML document from disk, from an input document.
   - | Optionally compare this object to one that is instantiated and initialized by a custom class that you write.
   - | Marshal this object to disk.
   - | Compare the newly-marshaled disk file to the input document on disk.

#### Only Source Generation Test Patterns

There is only one test pattern for a test of only the source generation framework. For source generation, you can optionally provide a binding file, but one is not required unless your test requires binding.

For each schema provided:

- | The source generator is configured and executed against the schema.
- | The generated source is compiled.
- | A class loader is used to load the generated code.

#### Source Generation Test Patterns

There is only one test pattern for a Source Generation test. For source generation, you can optionally provide a binding file, but one is not required unless your test requires binding.

For each schema provided:

- | The source generator is configured and executed against the schema.
- | The generated source is compiled.
- | A class loader is used to load the generated code.

-

Use the generated code to execute a marshaling test. The marshaling test may use any combination of the following marshaling test patterns as described in the section "Marshaling Test Patterns":

- | Marshal/Unmarshal with custom instantiated reference object
- | Marshal/Unmarshal with randomized reference object
- | Unmarshal/Marshal with reference XML document

### Life Cycle of a CTF Test

The most basic test available in the CTF is the Schema Test. This is just the first step in the life cycle of a CTF test! Depending on whether the source generator is to be used or not, the final step is either the Marshaling test or the Source Generation test, both of which test marshaling and unmarshaling. Source generation can be also tested without marshaling -- as an intermediate step; ideally a source-generation-only test case will later become a full-fledged Castor test case by having a reference document provided so marshaling and unmarshaling can be tested.

## Building the CTF

Before trying to launch the test cases, first make sure that the CTF is compiled. You can either use Subversion to check out the current trunk or you can use a source distribution from a release. Castor (and the CTF) is known to build and run under Windows and under Linux -- and Castor developers regularly test using Java JDK's between 1.3 and 5, inclusive.

Generally speaking, you build and run the CTF from within the "`bin`" directory of Castor's source tree. Relative to the top of the Castor source, this is the directory `bin`. (Pretty simple!) Just `cd` to that directory and you're ready to go.

Under Windows, you can use a `CMD.EXE` "shell" window or you can use CygWin. Which shell you use is your preference. Under UNIX, any shell will do. Change directory so the current directory is the Castor bin directory, as described above. Finally, to build the CTF, just run `build.bat tests` or `./build.sh tests`, depending on your operating system. To be thorough, you can run `build.bat clean tests` or `./build.sh clean tests`, which will remove previous build results and start fresh.

Note: While you can build the CTF jar -- `build.bat CTFjar` or `./build.sh CTFjar` -- this JAR by default contains only the test framework code and no tests. The JAR is a convenient way of distributing the CTF so that someone can run it without needing access to the full Castor source. However, this document is oriented toward developers who have access to the Castor source tree. Instructions in this document don't refer to and don't use this JAR file.

## Running the CTF

You can run the tests by using the script `CTFRun.bat` under Windows or `./CTFRun.sh` under Linux/UNIX. If you want to run a specific test or small subset of tests, then you need to provide the path to that Castor Testing Framework test or test tree -- either the full path to a JAR file or a path to the root directory of a tree of tests. If you want to run the Master Test Suite, you can run the tests without providing any arguments.

The CTF currently requires the Sun JDK (or SDK) to execute, although it may be possible to execute fine with GNU gcj or with JRockit. The CTF will not work if you are using only a JRE. This is because the CTF uses the Sun Java compiler API to compile code as needed for Source Generator and Marshaling Framework tests. The CTF code is written to allow easy extension for additional compiler frameworks, so if you use a compiler or runtime that is not supported, you should be able to easily add support for a new framework. If you want to do this, contact Castor committors for assistance and direction and they'll set you on the right course.

### Command Line options

Option | Args | Description | Optional?
--- | --- | --- | ---
-verbose |  | Flag: Give detailed information on the progress of and execution of each test. | Optional
-text |  | Flag: Run the tests without using the JUnit GUI. | Optional
-printStack |  | Flag: If any Exception occurs, dumps its stack. | Optional
-seed | int | Specifies the use of a specific seed for the pseudo-random generator. | Optional

You can get information about additional command-line options provided by the shell script or batch script by executing (depending on your operating system):

    CTFRun.bat help

    ./CTFRun.sh help

Note: The CTF scripts are current written expecting to be executed from the `bin` directory of Castor's source tree. The CTF may not function properly if you run these scripts from another directory.

For instance, to run all the tests from the MasterTestSuite:

    CTFRun.bat -verbose ../xmlctf/tests/MasterTestSuite/sourcegenerator

This command will execute in GUI mode (the default mode) all the test cases written in the master test suite for the source generator, and will print detailed messages about the execution of the tests.

## The Test Description: TestDescriptor.xml

Each CTF test case can be stored in a directory or in a jar and must contain a single `TestDescriptor.xml` file. This file is located under the META-INF directory when using a jar file or directly in the directory that contains the test case files when running the CTF from a directory tree. This file is a summary of the test cases contained in the directory or in the jar file.

Note: the whole XML Schema used to write TestDescriptor.xml is provided in the appendix.

The contents of the Test Descriptor are described and defined below.

### Header

Every test descriptor file begins with a common header.

Tag | Description | Optional?
--- | --- | ---
Name | The name of the test | Required
Author | The author of the test | Required
Comment | Some comment on the test. This element may occur more than once. | Required

Category

The category in which this test falls:

- | basic capability
- | special case

Required

BugFix

Used to report a bug and keep track of it. It is defined as follows:

- | Name of the reporter
- | Date of the report
- | Date of the fix (if known) or of the creation of the testcase (otherwise)
- | Comment on the fix (may occur more than once)

Optional

For instance, this example test descriptor header

    <?xml version='1.0'?>
    <TestDescriptor>
        <Name>Bug in the support of foo</Name>
        <Author>Comprehensive Contributor</Author>
        <Comment>
            This test case illustrates the bad handling of the foo element in the
            Marshaling Framework
        </Comment>
        <Comment>Adding this test will prevent further regression in this area.</Comment>
        <Category>basic capability</Category>

        <BugFix>
            <Reporter>Desperate User</Reporter>
            <Date_Report>2001-03-11T12:00:00</Date_Report>
            <Fixer>Comprehensive Contributor</Fixer>
            <Date_Fix>2053-12-12T15:03:00</Date_Fix>
        </BugFix>

         ...

    </TestDescriptor>

is a valid header for a TestDescriptor file. You may wonder why CTF needs so much information. Actually, this information can be used to generate acceptance documents and is also used to archive and track different resolved bugs. The comment fields especially are present for developers and interested users and are not directly used during the testing process.

### The Test (Following the Header)

The content of TestDescriptor.xml following the header differs depending on the test type:

Tag | Description | Optional?
--- | --- | ---
Name | The name of the test | Required
Author | The author of the test | Required
Comment | Some comment on the test. This element may occur more than once. | Required
The test itself | Exactly one of a SchemaTest, MarshallingTest, OnlySourceGenerationTest, or SourceGeneratorTest. | Required

#### SchemaTest

A SchemaTest tests only that the provided schema(s) can be successfully read and parsed, and then written to disk. No marshaling or unmarshaling or source generation is performed.

Tag | Attributes | Description | Optional?
--- | --- | --- | ---
UnitTestCase |  | One or more unit test cases (see below) | Required

#### MarshallingTest

A MarshallingTest will unmarshal the source document, then marshal it to a new file, then unmarshal the new document and compare to the original. No source generation is performed. The Castor marshaling framework is used.

If the root object has the attribute `random`, then additionally a randomized object will be created, marshaled, then unmarshaled, and the unmarshaled object will be compared to the original random object.

Tag | Attributes | Description | Optional?
--- | --- | --- | ---

Root_Object

- | dump: a boolean indicating that dumpFields() method has been implemented in Root_Object and that the unmarshaled objects should be dumped.
- | random: a boolean indicating that randomizeFields() method has been implemented in Root_Object and that a randomized object should be created, marshaled, and unmarshaled for comparison.

The qualified name of the Root object in the generated object model

Required

Configuration |  | Marshal/Unmarshal configuration (see below) | Optional
UnitTestCase |  | One or more unit test cases (see below) | Required

#### OnlySourceGenerationTest

An OnlySourceGenerationTest will run the Castor source generator on the schema(s) provided, will compile the generated source, and will load (via a class loader) the compiled source. No marshaling or unmarshaling will be done.

Tag | Attributes | Description | Optional?
--- | --- | --- | ---
Schema | None | The name of the schema from which we generate sources, may occur more than once | Required
Property_File | None | The name of the Source Generator property file (often named castorbuilder.properties) to use | Optional
Collection | None | The collection type to use (usually 'vector' or 'arraylist' or 'odmg'); if absent, defaults to 'vector' | Optional
Binding_File | None | The name of the binding file (if any) | Optional
UnitTestCase |  | One or more unit test cases (see below) | Required

#### SourceGeneratorTest

A SourceGeneratorTest will run the Castor source generator on the schema(s) provided, will compile the generated source, and will load (via a class loader) the compiled source. Once this has been done successfully, the generated source will be used to unmarshal an XML document. The document will then be marshaled to a new file, and then unmarshaled from that file. The newly unmarshaled document will be compared to the original.

If the root object has the attribute `random`, then additionally a randomized object will be created, marshaled, then unmarshaled, and the unmarshaled object will be compared to the original random object.

Tag | Attributes | Description | Optional?
--- | --- | --- | ---
Schema | None | The name of the schema from which we generate sources, may occur more than once | Required
Property_File | None | The name of the Source Generator property file (often named castorbuilder.properties) to use | Optional
Collection | None | The collection type to use (usually 'vector' or 'arraylist' or 'odmg'). if absent, defaults to 'vector' | Optional
Binding_File | None | The name of the binding file (if any) | Optional

Root_Object

- | dump: a boolean indicating that dumpFields() method has been implemented in Root_Object and that the unmarshaled objects should be dumped.
- | random: a boolean indicating that randomizeFields() method has been implemented in Root_Object and that a randomized object should be created, marshaled, and unmarshaled for comparison.

The qualified name of the Root object in the generated object model

Required

UnitTestCase |  | One or more unit test cases (see below) | Required

### UnitTestCase

This is the core of the test, this element provides the input file and output file used for a specific test and the name of the class used to instantiate the Object Model. Once again remember that a TestDescriptor.xml describes a test for a general behavior of Castor which may imply several test cases.

Tag | Attributes | Description | Optional?
--- | --- | --- | ---
Name | None | The name of this test. | Required
Mapping_File | None | The mapping file for this test, if any. This element is used only for a MarshallingTest, and should be absent for other test types. | Optional
Schema | None | The schema to be used for this test. This element is used only for a SchemaTest, and should be absent for other test types. You can specify only one schema. Alternately, if the value of this element is "`*`" then all schemas (identified by the extension `.xsd`) in the directory or JAR containing the TestDescriptor.xml will be included. | Optional
Configuration |  | Configuration for Marshaling or Unmarshaling (see below) | Optional
Input | None | The name of the input file used to create a specific Object Model by unmarshaling this file, used in the "test with reference document" test. You need to provide this element for the MarshallingTest and the SourceGeneratorTest. It is not used for the other test types. | Optional, depending on test type
GoldFile | None | The name of the file which can be seen as a "gold file." This element is used only in a MarshallingTest in the "test with reference document" test and is ignored for other test types. This element is optional for a MarshallingTest. If it is present, then the marshaled reference document is compared to the gold file. | Optional

ObjectBuilder

None

The fully-qualified class name of the class used to instantiate the Object Model used. This can be used in addition to an input document, as a way of generating an additional document to compare against. This element is optional for the MarshallingTest or SourceGeneratorTest (if present, used for the "test with reference document" test) and is not used for other test types. If it is present, then the named class is instantiated. Once instantiated, the method `buildInstance()` is invoked. The object returned is compared against the unmarshaled input file. That is, the ObjectBuilder is used to create a reference document.

Optional

Failure

- | exception: The class name of an exception. If `Failure` is false, this attribute is ignored. If `Failure` is true and this optional attribute is present, then the test will succeed only if the named Exception is thrown and the test will fail otherwise. If `Failure` is true and this attribute is absent, then the test will succeed if any Exception is thrown.

A boolean. If true, the test will pass if an exception is thrown. Otherwise, the test will fail if an exception is thrown.

Optional

Skip | None | A boolean. If true, this test will be skipped. | Optional
Listener |  | A listener for this test (see below). A Listener is used only for a MarshallingTest (it might also work for a SourceGeneratorTest but it has not been tested). A Listener should be absent for other test types. | Optional

### Listener

Tag | Description | Optional?
--- | --- | ---
ClassName | The name of the class to use for MarshalListener and/or UnmarshalListener | Required
Type | Marshal, Unmarshal or Both. Indicate how to use the provided ClassName. | Optional, defaults to "Both".
GoldFile | The name of the file which can be seen as a 'gold file' | Optional

### Configuration

Tag | Description | Optional?
--- | --- | ---
Marshal | If present, the Marshaler will be configured | Optional
Unmarshal | If present, the Unmarshaler will be configured | Optional

### Call-Method

Tag | Attributes | Description | Optional?
--- | --- | --- | ---

Call-Method

- | name: the name of the method to call on the Marshaler or Unmarshaler.

Root tag for defining a method call

Required

Value

- | type: the fully qualified name of the java type representing an argument of the method. For a primitive type, use the name of the primitive type.

The value to be passed in to the method called (this element can occur more than once).

Optional

The following code excerpt illustrates how to configure the Marshaler by suppressing all the XSITypes.

    <Configuration>
        <Marshal>
            <Call-method name="setSuppressXSIType">
                <Value type="boolean">true</Value>
             </Call-method>
        </Marshal>
    </Configuration>

Please note that the Configuration element can be present at the MarshallingTestCase level and at the UnitTestCase level. If it is found in both places, the only the UnitTestCase configuration is used.

## Implementing CastorTestable

As you may have noticed, while testing the SourceGenerator or the Marshaling Framework you have to provide the name of the 'Root Object' of your Object Model. The Root Object represents the mapping of the root element of the XML document.

For instance, given the following XML document:

    <?xml version='1.0'?>
    <Invoice>
        <Customer>
            ...
        </Customer>
        <Items>
            ...
        </Items>
          ...
    </Invoice>

the class that represents the Root Object is `Invoice`.

You provide your own implementation of a Root Object only for a test of the Marshaling framework. For a Source Generation framework test, the appropriate interface is automatically implemented in the generated source. Thus, the discussion below really only applies to a MarshallingTest type of CTF test.

The CTF needs your Root Object to override the equals() method of the `java.lang.Object` class. This is required, not optional, and is used when comparing object models.

While not strictly required, it is highly recommended that the Root Object implement the interface `org.exolab.castor.tests.framework.CastorTestable`. Implementing this interface is simple: implement two methods: `dumpFields()` and `randomizeFields()`. These methods are described below.

### dumpFields

Here is the JavaDoc of the method as defined in the interface:

        /**
         * Return a recursive dump of the content of the
         * object fields in a user readable format.
         * This is used to retrieve the state of the object if
         * castor fail to marshal the object for any reason.
         *
         * We don't rely on the toString() function as it could have
         * been already implemented with another semantic.
         */

### randomizeFields

Here is the JavaDoc of the method as defined in the interface:

        /**
         * The instance of the object will randomize the content
         * of its field. This is used to create an instance
         * of the object model without having to
         * unmarshal anything.
         */

In order to tell the CTF that one (or both) of these methods is implemented you have to set the attributes "dump" and "random" to true in the Root_Object element of the test descriptor:

`<Root_Object dump='true' random='true'>Root</Root_Object>`

Note: When using the Source Generator outside the CTF, you can automatically generate classes that implements CastorTestable by using the command line option "`-testable`". Within the CTF and the source generator-based tests, this option is automatically provided to the source generation framework.

### Sample Java Class for a Root_Object

The following is an example of a Root Object suitable for use in a MarshallingTest Marshaling framework test.

    import java.util.Vector;
    import java.util.Enumeration;

    // CTF specific
    import org.exolab.castor.tests.framework.CastorTestable;

    // Provide the necessary methods to randomly create object fields
    import org.exolab.castor.tests.framework.RandomHelper;

    public class Root implements CastorTestable {
        private String _name;
        private Vector _data;
        public void setName(String name) {
            _name = name;
        }
        public String getName() {
            return _name;
        }
        public void setData(Vector data) {
            _data = data;
        }
        public Vector getData() {
            return _data;
        }

        // --- CastorTestable ------------------------
        public String dumpFields() {
            StringBuffer fields = new StringBuffer();
            fields.append("name=" + _name + "; data=\n");
            for (Enumeration e = _data.elements(); e.hasMoreElements(); ) {
                CastorTestable element = (CastorTestable)e.nextElement()
                fields.append("[" + element.dumpFields() + "]\n");
            }
            return fields.toString();
        }

        public void randomizeFields() throws InstantiationException,
                                             IllegalAccessException {
            _name = RandomHelper.rndString();
            _data = RandomHelper.rndVector(_data, Data.class);
        }

        /**
         * Note: We should override hashCode() but have not.
         * @param obj
         */
        public boolean equals(java.lang.Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof Root) {
                Root temp = (Root)obj;
                if (!(this._name.equals(temp._name))) {
                    return false;
                }
                if (!(this._data.equals(temp._data))) {
                    return false;
                }
                return true;
            }
            return false;
        } //-- boolean equals(java.lang.Object)

    } //Root

## Implementing ObjectModelBuilder

For a MarshallingTest or a SourceGeneratorTest, in addition to an input document (for unmarshaling), you can also provide an object that will directly and programmatically (not from a file) construct your desired test document. This is a class that will instantiate and correctly populate your test object. This class must implement `equals()`! It will be compared against your unmarshaled input document.

It's recommended that your Object Model Builder also implement the interface CastorTestable, but this is not required.

### buildInstance

Here is the JavaDoc of the method declaration in the interface:

        /**
         * Generates and returns a new instance from the hard-coded data.
         *
         * @return a new instance from the hard-coded data
         * @throws Exception if anything goes wrong creating the instance
         */

### Sample Java Class for an Object Builder

The following is an example of an Object Builder suitable for use in a MarshallingTest or SourceGeneratorTest. The class `Root` used here would be generated for you if you are creating a SourceGeneratorTest, but would be provided by you for a MarshallingTest. This is the Root Object of the test.

    import java.util.Vector;

    // CTF specific
    import org.exolab.castor.tests.framework.ObjectBuilder;

    public class Builder implements ObjectBuilder {
        /**
         * Build the expected object model.
         */
        public Object buildInstance() {
            Root r = new Root();
            r.setName("object name");
            Vector v = new Vector(3);
            v.add(new Data("CASTOR-XML", "good"));
            v.add(new Data("CASTOR-JDO", "good"));
            v.add(new Data("CASTOR-DAX", "to be improved"));
            r.setData(v);
            return r;
        }
    } //Builder

## Reporting a bug in Castor

With the CTF, reporting a bug should be easier. You should no longer need to find yourself in endless discussion in describing the bug you encounter. All you have to do is:

- | Write a simple test case as described previously.
- | Create a jar or a directory tree (which you can ZIP up).
- | Send it to the Exolab JIRA or to a contributor: Exolab JIRA: http://jira.codehaus.org/browse/CASTOR Committer list: http://www.castor.org/contributors.html

## Full Sample of a Source Generation Test

In this section, we demonstrate a complete test case for the Source Generator. The sample test tests the handling of primitives W3C XML Schema type in the Source Generator using the default properties of the Source Generator. This test just illustrates that the Source Generator supports primitives types.

First we have to create the TestDescriptor xml file:

### TestDescriptor.xml

The test descriptor just describes the test case:

    <?xml version='1.0'?>
    <TestDescriptor>
        <Name>Test primitive types with default properties</Name>
        <Comment>
            Test W3C XML Schema primitives type handling in the Source Generator
        </Comment>
        <Comment>The supported types are:
                                -string
                                -boolean
                                -decimal
                                -float
                                -double
                                -duration
                                -dateTime
                                -time
                                -gYearMonth
                                -gYear
                                -gMonthDay
                                -gDay
                                -gMonth
                                -hexBinary
                                -base64Binary
                                -anyURI
                                -QName
        </Comment>
        <Comment>
            The facets are not tested in this case and Java primitives are used.
        </Comment>
        <Comment>hexBinary and base64Binary are not tested.</Comment>

        <Category>basic capability</Category>

        <SourceGeneratorTest>
            <Schema>primitives.xsd</Schema>
            <Root_Object random="true" dump="true">TestPrimitives</Root_Object>
            <UnitTestCase>
                <Name>Test Generation</Name>
                <Input>input1.xml</Input>
            </UnitTestCase>
            <UnitTestCase>
                <Name>Test Marshalling with the generated Descriptors</Name>
                <Input>input1.xml</Input>
                <ObjectBuilder>PrimitivesBuilder</ObjectBuilder>
            </UnitTestCase>
            <UnitTestCase>
                <Name>Test the validation</Name>
                <Input>badinput.xml</Input>
                <Failure>true</Failure>
            </UnitTestCase>
        </SourceGeneratorTest>
    </TestDescriptor>

Once we have the Test Descriptor, we have to provide the `primitives.xsd` and `input1.xml` and `badinput.xml` files as referenced in the Test Descriptor. We don't need to worry about implementing `CastorTestable` since the SourceGenerator will do so for us: it automatically generates the `dumpFields()` and `randomizeFields()` methods.

Because we want to provide a thorough example, we also want to provide an instance builder, i.e., implementing the ObjectBuilder interface, as referenced in the Test Descriptor.

### The gold file

    <?xml version="1.0"?>
    <TestPrimitives StringTestAtt="StringAttribute" booleanTestAtt="false"
                    floatTestAtt="3.141526" doubleTestAtt="1.171077"
                    decimalTestAtt="123456789.987654321"
                    uriReferenceTestAtt="http://www.castor.org"
                    IDTestAtt="Castor0.91" QNameTestAtt="xsd:type">
        <StringTestEle>StringElement</StringTestEle>
        <booleanTestEle>true</booleanTestEle>
        <floatTestEle>1234567899876543210</floatTestEle>
        <doubleTestEle>0.6385682166079459</doubleTestEle>
        <decimalTestEle>0.2693678757526658529286578414030373096466064453125</decimalTestEle>
        <timeDurationTestEle>P1Y2M3DT4H5M6S</timeDurationTestEle>
        <uriReferenceTestEle>http://castor.exolab.org</uriReferenceTestEle>
        <IDTestEle>ID9</IDTestEle>
        <QNameTestEle>Test:test</QNameTestEle>
    </TestPrimitives>

### PrimitivesBuilder.java

`PrimitivesBuilder.java` is a simple implementation of ObjectBuilder. It contains the hard-coded values of the input xml file, it is used to create a "gold" Object Model we can use to compare the Object Model created from the unmarshalling of "`input1.xml`."

    import java.util.Vector;

    //the interface we implement
    import org.exolab.castor.tests.framework.ObjectBuilder;

    public class PrimitivesBuilder implements ObjectBuilder {
        /**
         * Build the object expected when unmarshalling 'input1.xml'.
         */
        public Object buildInstance() {
            TestPrimitives test = new TestPrimitives();
            test.setStringTestAtt("StringAttribute");
            test.setBooleanTestAtt(false);
            test.setFloatTestAtt(3.141526f);
            test.setDoubleTestAtt(1.171077);
            ...
            return test;
        }
    }

### Launching the Test

The last step consists of packaging up the collection of files that make up the test case. You have two choices. You can either create a JAR file containing the test, or you can create a directory structure containing the test. You can use whichever option is easier.

#### Launching the Test from a JAR

Create a JAR from your test's source files:

       jar cvf ../PrimitivesWithoutFacets.jar *.*

You can now execute this test by running the CTF with the path to this JAR file:

       CTFRun -verbose PrimitivesWithoutFacets.jar

#### Launching the Test from a directory tree

Create a new directory under the appropriate test suite directory tree. For this test, an appropriate directory would be: `xmlctf/tests/MasterTestSuite/sourcegenerator/PrimitivesWithoutFacets`. Copy all of the files that comprise your test into that directory.

You can now execute this test by running the CTF with the path to this directory:

    CTFRun -verbose ../xmlctf/tests/MasterTestSuite/sourcegenerator/PrimitivesWithoutFacets

## Full Sample of a Marshaling Framework Test

To be written....

## Checklist for creating a CTF test

- | Create a directory (the test directory) to put the files needed for the test case.
- | Create the META-INF directory in this directory.
- | Create your TestDescriptor.xml.
- | Write the XML schema, mapping file or XML documents needed and put them under your test directory.
- | If you provide an Object Model don't forget to override the equals() method
- | If necessary, implement the dumpFields() and randomizeFields() methods.
- | Compile the provided object model
- | Create a jar representing the test directory
- | Run the test

## Status of the CTF

The current version of the CTF is not perfect and could use some improvements. However, it provides a solid base upon which to test the behavior of Castor. And its presence will help developers to avoid regression while fixing bugs and adding new features.

Future versions of the CTF may include:

- | A tool to generate test acceptance documents,
- | An updated architecture for RandomHelper,
- | A way to launch the test from the web site, and
- | Better exception handling and failure tests.

## XML Schema for TestDescriptor.xsl

The full source of the W3C XML schema for the TestDescriptor object is included below. It is found in the source file `TestDescriptor.xml`. Note that this schema is a work in progress and is subject to change.

    <?xml version='1.0' encoding="UTF-8"?>
    <!--
        Castor Testing Framework Test Descriptor XML Schema
        Namespace: http://castor.exolab.org/Test

        This schema is used to generate the
        org.exolab.castor.tests.framework.testdescriptor package
        *Note*: This schema is under evolution and subject to change.
         This schema is under the Exolab license
     -->
    <!-- $Id: ctf.xml 6782 2007-01-29 01:56:19Z ekuns $ -->
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                targetNamespace="http://castor.exolab.org/Test"
                xmlns:test="http://castor.exolab.org/Test"
                elementFormDefault="qualified">

        <!-- The root element which contains an header and a test element-->
        <xsd:element name="TestDescriptor">
            <xsd:annotation>
                <xsd:documentation>
                    Castor Testing Framework Test Descriptor XML Schema
                    &lt;p>
                    Namespace: http://castor.exolab.org/Test
                    &lt;p>
                    This schema is used to generate the
                    org.exolab.castor.tests.framework.testdescriptor package
                    *Note*: This schema is under evolution and subject to change.
                     This schema is under the Exolab license.
                </xsd:documentation>
            </xsd:annotation>
            <xsd:complexType>
                <xsd:sequence>
                    <!-- The name of the test -->
                    <xsd:element name="Name" type="xsd:string" minOccurs="1" maxOccurs="1"/>
                    <!-- The author of the tests -->
                    <xsd:element name="Author" type="xsd:string" minOccurs="1" maxOccurs="1"/>
                    <!-- Some comments for describing the test -->
                    <xsd:element name="Comment" type="xsd:string" minOccurs="1" maxOccurs="unbounded"/>
                    <!-- Define the category of the test -->
                    <xsd:element name="Category" type="test:CategoryType" minOccurs="1" maxOccurs="1"/>
                    <!-- Is it a bug fix?-->
                    <xsd:element ref="test:BugFix" minOccurs="0" maxOccurs="1"/>
                    <!-- Test for the SourceGenerator OR the Marshaling Framework-->
                    <xsd:choice>
                        <!-- Test case for the SourceGenerator -->
                        <xsd:element ref="test:SourceGeneratorTest" minOccurs="0" maxOccurs="1"/>
                        <!-- Test case for the Marshaling Framework -->
                        <xsd:element ref="test:MarshallingTest" minOccurs="0" maxOccurs="1"/>
                        <!-- Test case for the Schema Object Model -->
                        <xsd:element ref="test:SchemaTest" minOccurs="0" maxOccurs="1"/>
                        <!-- Test case for Source Generation ONLY (no marshaling or unmarshaling) -->
                        <xsd:element ref="test:OnlySourceGenerationTest" minOccurs="0" maxOccurs="1"/>
                    </xsd:choice>
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>

        <xsd:element name="BugFix">
            <xsd:annotation>
                <xsd:documentation>
                    Encapsulates information about a bug fix, including the reporter's
                    name (or Email address), the date of the report and of the fix,
                    and one or more comments about the bug.
                </xsd:documentation>
            </xsd:annotation>
            <xsd:complexType>
                <xsd:sequence>
                    <!-- the reporter name or EMail address-->
                    <xsd:element name="Reporter" type="xsd:string" minOccurs="1" maxOccurs="1"/>
                    <!-- date of the report-->
                    <xsd:element name="Date_Report" type="xsd:date" minOccurs="1" maxOccurs="1"/>
                    <!-- date of the fix-->
                    <xsd:element name="Date_Fix" type="xsd:date" minOccurs="1" maxOccurs="1"/>
                    <!-- Some comments on the fix or the bug -->
                    <xsd:element name="Comment" type="xsd:string" minOccurs="1" maxOccurs="unbounded"/>
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>

        <xsd:element name="SourceGeneratorTest">
            <xsd:annotation>
                <xsd:documentation>
                    Tests source generation and then tests the generated source, testing
                    both marshaling and unmarshaling.
                </xsd:documentation>
            </xsd:annotation>
            <xsd:complexType>
                <xsd:sequence>
                    <!-- the names of the schema files to generate sources from-->
                    <!-- assume that the Testing Framework will try to match the name -->
                    <!-- by looking in all the JARs - directories -->
                    <xsd:element name="Schema" type="xsd:string" minOccurs="1" maxOccurs="unbounded"/>
                    <!-- The name of the properties file used with this SourceGenerator test case-->
                    <xsd:element name="Property_File" type="xsd:string" minOccurs="0" maxOccurs="1"/>
                    <!-- The name of the collection type used with this SourceGenerator test case-->
                    <xsd:element ref="test:Collection" minOccurs="0" maxOccurs="1"/>
                    <!-- the binding file name -->
                    <xsd:element name="BindingFile" type="xsd:string" minOccurs="0" maxOccurs="1"/>
                    <!-- the qualified name of the root Object -->
                    <!-- later: define a pattern to describe a Java quailified name-->
                    <xsd:element ref="test:Root_Object" minOccurs="1" maxOccurs="1"/>
                    <!-- individual test cases -->
                    <xsd:element ref="test:UnitTestCase" minOccurs="1" maxOccurs="unbounded"/>
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>

        <xsd:element name="MarshallingTest">
            <xsd:annotation>
                <xsd:documentation>
                    Test marshaling.
                </xsd:documentation>
            </xsd:annotation>
            <xsd:complexType>
                <xsd:sequence>
                    <!-- the qualified name of the root Object -->
                    <!-- later: define a pattern to describe a Java quailified name-->
                    <xsd:element ref="test:Root_Object" minOccurs="0" maxOccurs="1"/>
                    <!-- the configuration for the marshaling framework -->
                    <xsd:element ref="test:Configuration" minOccurs="0" maxOccurs="1"/>
                    <!-- individual test cases -->
                    <xsd:element ref="test:UnitTestCase" minOccurs="1" maxOccurs="unbounded"/>
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>

        <xsd:element name="SchemaTest">
            <xsd:annotation>
                <xsd:documentation>
                    Tests a schema.
                </xsd:documentation>
            </xsd:annotation>
            <xsd:complexType>
                <xsd:sequence>
                    <!-- individual test cases -->
                    <xsd:element ref="test:UnitTestCase" minOccurs="1" maxOccurs="unbounded"/>
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>

        <xsd:element name="OnlySourceGenerationTest">
            <xsd:annotation>
                <xsd:documentation>
                    Tests source generation only, and does not attempt to use the generated code.  While
                    a <code>SourceGeneratorTest</code> is better because it is more thorough, sometimes
                    the only thing that requires testing is the code generation.
                </xsd:documentation>
            </xsd:annotation>
            <xsd:complexType>
                <xsd:sequence>
                    <!-- the names of the schema files to generate sources from-->
                    <!-- assume that the Testing Framework will try to match the name -->
                    <!-- by looking in all the JARs - directories -->
                    <xsd:element name="Schema" type="xsd:string" minOccurs="1" maxOccurs="unbounded"/>
                    <!-- The name of the properties file used with this SourceGenerator test case-->
                    <xsd:element name="Property_File" type="xsd:string" minOccurs="0" maxOccurs="1"/>
                    <!-- The name of the collection type used with this SourceGenerator test case-->
                    <xsd:element ref="test:Collection" minOccurs="0" maxOccurs="1"/>
                    <!-- the binding file name -->
                    <xsd:element name="BindingFile" type="xsd:string" minOccurs="0" maxOccurs="1"/>
                    <!-- individual test cases -->
                    <xsd:element ref="test:UnitTestCase" minOccurs="1" maxOccurs="unbounded"/>
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>

        <xsd:element name="Root_Object" type="test:RootType">
            <xsd:annotation>
                <xsd:documentation>
                    The qualified name of the root Object.
                    TODO: define a pattern to describe a Java quailified name.
                </xsd:documentation>
            </xsd:annotation>
        </xsd:element>

        <xsd:element name="Collection" default="vector">
            <xsd:annotation>
                <xsd:documentation>
                    The data type to use in collections.
                </xsd:documentation>
            </xsd:annotation>
               <xsd:simpleType>
                <xsd:restriction base="xsd:string">
                    <xsd:enumeration value="vector"/>
                    <xsd:enumeration value="arraylist"/>
                      <xsd:enumeration value="odmg"/>
                </xsd:restriction>
            </xsd:simpleType>
        </xsd:element>

        <xsd:element name="UnitTestCase">
            <xsd:annotation>
                <xsd:documentation>
                    A definition of a single Unit Test testcase.
                </xsd:documentation>
            </xsd:annotation>
            <xsd:complexType>
                <xsd:sequence>
                    <!-- The name of the test -->
                    <xsd:element name="Name" type="xsd:string" minOccurs="0" maxOccurs="1"/>
                    <xsd:choice minOccurs="0">
                        <!-- the mapping file used (if any) -->
                        <xsd:element name="Mapping_File" type="xsd:string" minOccurs="0" maxOccurs="1"/>
                        <!-- the name of the schema to read/write -->
                        <!-- a '*' will indicate that the CTF will try to read/write -->
                        <!-- all the schemas present in the directory or jar -->
                        <xsd:element name="Schema" type="xsd:string" minOccurs="0" maxOccurs="1"/>
                    </xsd:choice>
                    <!-- the configuration for the marshalling framework -->
                    <xsd:element ref="test:Configuration" minOccurs="0" maxOccurs="1"/>
                    <!-- the input XML file for unmarshaling -->
                    <xsd:element name="Input" type="xsd:string" minOccurs="0" maxOccurs="1"/>
                    <!-- the file to compared a marshaled document to -->
                    <xsd:element name="GoldFile" type="xsd:string" minOccurs="0" maxOccurs="1"/>
                    <!-- the ObjectBuilder class used for this test case -->
                    <xsd:element name="ObjectBuilder" type="xsd:string" minOccurs="0" maxOccurs="1"/>
                    <!-- a boolean that indicates if the test case intents to fail (Exception thrown)-->
                    <xsd:element name="Failure" type="test:FailureType" minOccurs="0" maxOccurs="1"/>
                    <!-- will cause the test to be ignored -->
                    <xsd:element name="Skip"   type="xsd:boolean" minOccurs="0" maxOccurs="1"/>
                    <!-- the listener to use for unmarshaling, marshaling or both -->
                    <xsd:element name="Listener" type="test:ListenerType" minOccurs="0" maxOccurs="1"/>
                    <!-- for a schema test, the number of differences expected -->
                    <xsd:element name="SchemaDifferences" type="test:SchemaDifferencesType"
                                 minOccurs="0" maxOccurs="2"/>
                    <!-- Some comments for describing the test -->
                    <xsd:element name="Comment" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>

        <xsd:element name="Configuration">
            <xsd:annotation>
                <xsd:documentation>
                </xsd:documentation>
            </xsd:annotation>
            <xsd:complexType>
               <xsd:choice>
                  <xsd:element name="Marshal" type="test:ConfigurationType"/>
                  <xsd:element name="Unmarshal" type="test:ConfigurationType"/>
               </xsd:choice>
            </xsd:complexType>
        </xsd:element>

        <xsd:complexType name="ConfigurationType">
            <xsd:annotation>
                <xsd:documentation>
                    Configuration for marshaling or unmarshaling or source generation.  Contains
                    a list of methods to be called on the marshaler or unmarshaler or source
                    generator with the parameters to be provided for each method.
                </xsd:documentation>
            </xsd:annotation>
            <xsd:sequence>
               <xsd:element ref="test:Call-method" maxOccurs="unbounded"/>
            </xsd:sequence>
        </xsd:complexType>

        <xsd:element name="Call-method">
            <xsd:annotation>
                <xsd:documentation>
                    A single method to call on a marshaler or unmarshaler or source generator
                </xsd:documentation>
            </xsd:annotation>
            <xsd:complexType>
                <xsd:sequence>
                    <xsd:element ref="test:Value" maxOccurs="unbounded"/>
                </xsd:sequence>
                <!-- the name of the method to call -->
                <xsd:attribute name="name" type="xsd:string"/>
            </xsd:complexType>
        </xsd:element>

        <xsd:element name="Value">
            <xsd:annotation>
                <xsd:documentation>
                    A parameter to be provided to a method.
                </xsd:documentation>
            </xsd:annotation>
            <xsd:complexType>
                <xsd:simpleContent>
                    <xsd:extension base="xsd:string">
                        <!-- java type -->
                        <xsd:attribute name="type" type="xsd:string" required="true"/>
                    </xsd:extension>
                </xsd:simpleContent>
            </xsd:complexType>
        </xsd:element>

        <xsd:simpleType name="CategoryType">
            <xsd:annotation>
                <xsd:documentation>
                    The type of test case, either basic capability or a special case.
                </xsd:documentation>
            </xsd:annotation>
            <xsd:restriction base="xsd:string">
                <xsd:enumeration value="basic capability"/>
                <xsd:enumeration value="special case"/>
                <!-- Extensible-->
            </xsd:restriction>
        </xsd:simpleType>

        <!--A root object in an object model-->
        <xsd:complexType name="RootType">
            <xsd:annotation>
                <xsd:documentation>
                    The definition of the Root Type in the object model.  Contains two
                    boolean attributes:  <code>random</code> and <code>dump</code>.
                    If random is set to true, a test using randomized objects will
                    be executed.  If dump is set to true, the object will be dumped
                    to specific files.
                </xsd:documentation>
            </xsd:annotation>
            <xsd:complexContent>
                <xsd:extension base="test:StringType">
                    <!--set to true to randomly generate the given Object Model-->
                    <xsd:attribute name="random" type="xsd:boolean" default="false"/>
                    <!--set to true to dump the given Object Model states in specific files-->
                    <xsd:attribute name="dump"   type="xsd:boolean" default="false"/>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>

        <xsd:complexType name="StringType">
            <xsd:annotation>
                <xsd:documentation>
                    A Java String.
                </xsd:documentation>
            </xsd:annotation>
            <xsd:simpleContent>
                <xsd:extension base="xsd:string"/>
            </xsd:simpleContent>
        </xsd:complexType>

        <!-- The failure type -->
        <xsd:complexType name="FailureType">
            <xsd:annotation>
                <xsd:documentation>
                    True if this test is expected to throw an Exception and if it would thus
                    be an error if the test does not throw an Exception.  False otherwise.
                    &lt;p>
                    If FailureType is true, then this element optionally contains the attribute
                    <code>exception</code> that contains the class of the Exception that is
                    expected.  If this attribute is not provided, then the presence of any
                    exception causes the test to pass.  Otherwise, the specific exception
                    has to be thrown for the test to pass.
                </xsd:documentation>
            </xsd:annotation>
            <xsd:simpleContent>
                <xsd:extension base="xsd:boolean">
                    <!-- if you expect a specific exception, you can specify it here -->
                    <xsd:attribute name="exception" type="xsd:string" use="optional"/>
                    <!-- if you expect the failure at a specific step, specify which step -->
                    <xsd:attribute name="FailureStep" type="test:FailureStepType" use="optional"/>
                </xsd:extension>
            </xsd:simpleContent>
        </xsd:complexType>

        <!-- The failure type -->
        <xsd:complexType name="SchemaDifferencesType">
            <xsd:annotation>
                <xsd:documentation>
                    If you expect a non-zero number of differences when comparing schemas,
                    add one of these elements and provide the FailureStep attribute
                    to say which step this difference applies to.
                </xsd:documentation>
            </xsd:annotation>
            <xsd:simpleContent>
                <xsd:extension base="xsd:int">
                    <xsd:attribute name="FailureStep" type="test:FailureStepType" use="required"/>
                </xsd:extension>
            </xsd:simpleContent>
        </xsd:complexType>

        <xsd:simpleType name="FailureStepType">
           <xsd:restriction base="xsd:string">
               <xsd:enumeration value="parse-schema"/>
               <xsd:enumeration value="write-schema"/>
               <xsd:enumeration value="compare-schema"/>
               <xsd:enumeration value="source-generation"/>
               <xsd:enumeration value="source-compilation"/>
               <xsd:enumeration value="load-generated-classes"/>
               <xsd:enumeration value="unmarshal-reference"/>
               <xsd:enumeration value="marshal-to-disk"/>
               <xsd:enumeration value="compare-to-reference"/>
               <xsd:enumeration value="second-compare"/>
               <xsd:enumeration value="listener-comparison"/>
               <xsd:enumeration value="second-unmarshal"/>
           </xsd:restriction>
        </xsd:simpleType>

        <!-- Marshal/Unmarshal Listener type -->
        <xsd:complexType name="ListenerType">
            <xsd:annotation>
                <xsd:documentation>
                </xsd:documentation>
            </xsd:annotation>
            <xsd:sequence>
                <xsd:element name="GoldFile" type="xsd:string" maxOccurs="1"/>
                <!-- the fully qualified name for the listener -->
                <xsd:element name="ClassName" type="xsd:string" minOccurs="1" maxOccurs="1"/>
                <!-- The type of listener: Marshal, Unmarshal or Both -->
                <xsd:element name="Type" maxOccurs="1" default="Both">
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:string">
                            <xsd:enumeration value="Marshal"/>
                            <xsd:enumeration value="Unmarshal"/>
                            <xsd:enumeration value="Both"/>
                        </xsd:restriction>
                    </xsd:simpleType>
                </xsd:element>
            </xsd:sequence>
        </xsd:complexType>

    </xsd:schema>

## References

1. Seven Steps to Test Automation Success
   Version from June 2001
   Bret Pettichord
   See http://www.io.com/~wazmo/papers/seven_steps.html
2. JUnit Framework
   See http://www.junit.org/ and http://junit.sourceforge.net/junit3.8.1/index.html
3. Castor XML
   Exolab Castor XML Team
   See http://www.castor.org/
4. Source Generator User Documentation
   Exolab Castor XML Team
   See http://www.castor.org/SourceGeneratorUser.pdf

<notice> Copyright © 1999-2005 ExoLab Group, Intalio Inc., and Contributors. All rights reserved. </notice>
<notice> Java, EJB, JDBC, JNDI, JTA, Sun, Sun Microsystems are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and in other countries. XML, XML Schema, XSLT and related standards are trademarks or registered trademarks of MIT, INRIA, Keio or others, and a product of the World Wide Web Consortium. All other product names mentioned herein are trademarks of their respective owners. </notice>