XUnit Testing Guide
XML/Service Unit Testing Guide
Index > Books > Declarative Development Guide > Reference Library > Developer Guides > XUnit Testing Guide

Rate this page:
Really useful
Satisfactory
Not helpful
Confusing
Incorrect
Unsure
Extra comments:


WARNING: XUnit has security implications. Please carefully read the security section (below) on the security implications of using the XUnit test framework.

License

Unlike the other NetKernel modules, which are distributed under the 1060 Public License, the XUnit suite is licensed under a non-commercial use license. You are free to evaluate xunit and free to use it for non-commercial use. XUnit is not restricted in any way and includes full documentation - rather than restrict the product, we prefer to trust you and hope that you will respect that trust by purchasing a license. Please visit 1060 Research for a license if you intend to use XUnit for development of commercial applications.

Unit Testing

Unit testing is a valuable part of the development process. XML applications and services are no different and multiple small test cases help illustrate a service's interfaces, ensure robustness and provide quality assurance. Unit testing is valuable to ensure long term maintainability of an application or service.

XUnit

XUnit is an application for executing arbitrary tests on the NetKernel Standard Edition platform. It provides an extensible framework and test harness for executing groups of unit tests. It provides both XML output and GUI (HTML) visualisation of test results.

The XUnit test engine can be treated as a black-box which is accessed through the xunit accessor. The xunit engine will recursively execute a test list which has the following form...

<testlist iterate="1" output="html" title="My Tests">
  <desc>
    <div>Optional XHTML description of this test</div>
  </desc> . Multiple Individual Tests...
  <test>
    <uri>active:dpml+operand@ffcpl:/some/test.idoc</uri>
    <assert> ..Assertions can be one or more of the following..
      <xpath>An xpath to assert on the result</xpath>
      <uri>URI to an assertion service</uri> ...
    </assert>
  </test> . And/Or Multiple Groups..
  <group title="My Test Group">
    <uri>URI to a secondary test list</uri>
  </group>
</testlist>

TestList Structure

The RelaxNG schema for the test list is available here.

A testlist consists of one or more tests or groups of tests. The testlist has root element <testlist>

TestList Attributes

  • @title - the name of the test
  • @output - indicate whether the results should be HTML formatted (html) or XML (xml)

TestList components

  • <desc> - An optional block of XHTML description for the tests.
  • <test> - A single test, consisting of.
    • <uri> - the URI to be invoked as the test.
    • <assert> - optional assertion tests on the result (see below)
    • <module> - optional uri of module against which public URI address space the test URI will be invoked
    • <moduleVersion> - optional version number of module
  • <group> - A test group to recursively invoked [may have optional @title attribute]
    • <uri> - the URI of the testlist to be recursed
  • <module> - optional uri of module against which public URI address space the test URI will be invoked [may be overridden by invidual tests]. If not specified the test URI will be issued into the current URI address space (generally the typical mode of operation).
  • <moduleVersion> - optional version number of module [may be overridden by individual tests]

Assertion Tests

When a test URI request has completed the XUnit engine will test the result against any/all specified assertions. Assertions may be of the following types

  • <xpath> - An XPath expression
  • <uri> - The URI of an assertion service which the XUnit engine will invoke with the test result as the param argument of the request. The assertion service must return a boolean result (either canonical boolean document or an IAspectBoolean).
  • <minTime> - minimum time the test should take (milliseconds)
  • <maxTime> - maximum time the test should take (milliseconds)
  • <mimetype> - mimetype of result
  • <expired/> - result should be expired
  • <intermediate/> - result should be intermediate
  • <contextSensitive/> - result should be context sensitive, ie the result may not be same if called from a different context (super stack)

URI Requests

XUnit is really just a sophisticated mapper which invokes sub-requests and tests the results. By default, the test URI will be issued as a request to the internal URI address space from wherever the xunit accessor is invoked. It is recommended that all test URIs should be absolute URIs - no guarantees are made which current working URI will be used to resolve relative URIs.

Using a Module URI

If an optional <module> URI is specified for a test, the test URI will be requested against the public URI interface of that module. If the testlist document specifies a module URI then all tests will be requested against the public URI interface of that module. An individual test may specify it's own module URI which will override the testlist module URI.

Example URIs

The URI of a test may be any NetKernel resolvable URI, here are some examples

  • To test a resource exists: ffcpl:/path/to/my/resource.xml
  • To start a DPML test harness use: active:dpml+operand@ffcpl:/path/to/my/process.idoc

Test Order and Execution State

The test engine will execute all tests specified in a testlist, including recursively included tests from groups. The tests are not guaranteed to be executed in order - no assumptions should be made about the order of execution of a series of tests. If necessary each test should be written to create any necessary state for the test - you must not assume address space state will be preserved from another test higher up the testlist.

Creating a Test Harness for XUnit

The XHTML formatted result of the xunit accessor is written to provide an interactive test application. All href links in the result are relative to the root path ie they come back to the same page with different parameters. Below is a test harness DPML process which will act as front-end to the XUnit engine - you should set the initial test list URI which will act as the starting point from which unit tests can be recursively explored.

[Note: If you don't want a GUI interactive application you can specify XML output in the testlist - this will produce an XML list of tests and groups with their test result status.]

<idoc>
  <comment> ******************************* Example XUnit Test Harness ******************************* </comment>
  <seq>
    <instr>
      <type>copy</type>
      <operand>this:param</operand>
      <target>var:param</target>
    </instr>
    <exception>
      <comment> *********We received no param so we must boot the system*********** </comment>
      <instr>
        <type>copy</type>
        <operand>
          <nvp>
            <uri>...IMPORTANT: This should be the URI of your highest level TestList...</uri>
          </nvp>
        </operand>
        <target>var:param</target>
      </instr>
    </exception>
    <comment> ***********Execute the Tests************** </comment>
    <instr>
      <type>xunit</type>
      <param>var:param</param>
      <target>this:response</target>
    </instr>
    <instr>
      <type>expire</type>
      <operand>this:response</operand>
      <target>this:response</target>
    </instr>
  </seq>
</idoc>

Security

XUnit has security implications!. XUnit necessarily must be able to execute any test URI's, equally it is capable of serving any resource from the address space in which it is deployed. It is essential that access to your front-end test harness be controlled - take great care how you export your application's test harness.

For guaranteed security do not deploy your test harness with your application. However with some basic precautions there is no reason that a deployed application and test suite cannot safely co-exist. The easiest way to achieve this is to put your unit test harness in an isolated fulcrum with a dedicated access controlled transport which is used only for testing.

XUnit Self Test

To see XUnit in action try the XUnit self test suite. Simply import the urn:org:ten60:netkernel:ext:xunit module into a fulcrum with an HTTP transport and point your browser at /org/ten60/netkernel/xunit/selftest.

© 2003-2005, 1060 Research Limited. 1060 registered trademark, NetKernel trademark of 1060 Research Limited.