Alster Developers' Handbook


Overview

Alster is an XSLT unit testing framework. It allows the creation and "execution" (i.e. transformation) of XSLT stylesheets containing specially marked "test templates".

The Alster test runner may be invoked either on the command line (via a shell script), directly from within a Java application or through the use of the <alster> task for the Apache Ant build tool.

Usage

In order to use the Alster framework for unit testing one or more XSLT stylesheets, you need to set up a test stylesheet for the stylesheet to be tested and invoke the Alster test runner.

The test stylesheet

Note that the Alster test runner will "execute" the test stylesheet by using it for a transformation of an internally constructed XML file and will not know any other external XML structure. Therefore, all XML structures used by the test templates needs to be set up either by the XSLT document() function or by explicit construction of a result tree fragment which may be turned into a node set by the node-set() function of the EXSLT extension library.

Example

The following is an example of an Alster test stylesheet.

Consider the following simple XSLT stylesheet, "add.xsl". It contains one named template which calculates the sum of two numbers (passed as parameters) as well as one template which calculates the sum of an arbitrary number of numbers (contained as text nodes inside <number> subnodes of the current <numbers> node.


<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template name="add">
    <xsl:param name="first"/>
    <xsl:param name="second"/>
    <xsl:value-of select="$first + $second"/>
  </xsl:template>

  <xsl:template match="numbers">
    <xsl:value-of select="sum(number)"/>
  </xsl:template>

</xsl:stylesheet>

      
When applying this stylesheet to the following XML source file ("numbers.xml"),

<numbers>
  <number>1</number>
  <number>3</number>
  <number>5</number>
  <number>7</number>
</numbers>

      
the result produced will be "16".

Now, the functionality of the add.xsl stylesheet can be tested with the following Alster test stylesheet, "addTest.xsl" (recall that Alster XSLT test stylesheets must have names ending with "Test.xsl").

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:alster="http://alster.sourceforge.net"
1

                xmlns:exsl="http://exslt.org/common"
2

                extension-element-prefixes="exsl">

  <xsl:include href="add.xsl"/>
3

  <xsl:include href="classpath:/net/sf/alster/xsl/alster.xsl"/>
4


  <xsl:template name="alster:testAdd">
5

    <xsl:call-template name="alster:assertEqualsAsNumber">
6

      <xsl:with-param name="actual">
        <xsl:call-template name="add">
          <xsl:with-param name="first">11</xsl:with-param>
          <xsl:with-param name="second">23</xsl:with-param>
        </xsl:call-template>
      </xsl:with-param>
      <xsl:with-param name="expected">34</xsl:with-param>
      <xsl:with-param name="message">11 + 23 should add up to 34.</xsl:with-param>
7

    </xsl:call-template>
  </xsl:template>


  <xsl:template name="alster:testRoot1">

    <!-- set up node using the document() function -->
    <xsl:variable name="numbers">
      <xsl:value-of select="document('numbers.xml')"/>
8

        </xsl:variable>

    <!-- then call the alster assertion template -->
    <xsl:call-template name="alster:assertEqualsAsNumber">
      <xsl:with-param name="actual">
        <xsl:apply-templates select="$numbers"/>
      </xsl:with-param>
      <xsl:with-param name="expected">16</xsl:with-param>
      <xsl:with-param name="message">Odd numbers up to 7 should add up to 16.</xsl:with-param>
    </xsl:call-template>

  </xsl:template>


  <xsl:template name="alster:testRoot2">

    <!-- set up result tree fragment -->
    <xsl:variable name="numbers">
      <numbers>
9

        <number>2</number>
        <number>4</number>
        <number>6</number>
        <number>8</number>
      </numbers>
    </xsl:variable>

    <!-- then call the alster assertion template, turning the
         result tree fragment into a node set -->
    <xsl:call-template name="alster:assertEqualsAsNumber">
      <xsl:with-param name="actual">
        <xsl:apply-templates select="exsl:node-set($numbers)"/>
10

      </xsl:with-param>
      <xsl:with-param name="expected">20</xsl:with-param>
      <xsl:with-param name="message">Odd numbers up to 8 should add up to 20.</xsl:with-param>
    </xsl:call-template>

  </xsl:template>

</xsl:stylesheet>

1 The test stylesheet needs to define an "alster" namespace.

2 The namespace of the EXSLT extension library is "http://exslt.org/common".

3 The test stylesheet must first include the stylesheet to be tested.

4 Secondly, the main Alster stylesheet must be included.
     The classpath protocol may (and should) be used to access resources available in the classpath.

5 The names of test templates need to start with "alster:test".

6 The Alster XSLT unit testing framework includes a number of "assertion" templates each having the namespace "alster" and a name starting with "assert".
     A complete list of all such named templates can be found in the Alster XSL API documentation.

7 Aside from the - always required - XSLT template parameter named actual and the - in most cases required - parameter named expected, each of the assertion templates recognizes an optional XSLT template parameter named message.

8 XML nodes used by the tested templates may be constructed by the XSLT document() function.

9 Alternatively, XML data may be directly constructed as a result tree fragment.

10 In order to use the XML data constructed as a result tree fragment, use the node-set() function of the EXSLT extension library.

Alster Invocation

To invoke the above Alster test, simply open a shell and change the current directory to the root directory of the Alster installation. (Assuming that the files listed above are contained in the directory test\src\net\sf\alster\test). Then, enter

c:> alster
1
 -R
2
 test\src
3

1 The command line version of the Alster test runner is a shell script named alster.bat resp. alster.sh.

2 The Alster command line tool recognizes one optional option, -R. If it is specified, the test runner recurses into all subdirectories of the specified directory.

3 This (required) argument is used to specify the directory where the Alster test runner is to search for (and execute) Alster unit tests.

This will run the above test stylesheet, producing output similar to the following.
Running addTest.xsl
Tests run: 3, Failures: 0

Testsuite: /net/sf/alster/test/addTest.xsl
Tests run: 3, Failures: 0, Time elapsed: 0 sec

Testcase: alster:testRoot2 took 0.4 sec
Testcase: alster:testRoot1 took 0 sec
Testcase: alster:testAdd took 0 sec

Alternatively, the Alster testing framework may be invoked using an Apache Ant task (named <alster>).

An example for this type of invocation can be found in the main Ant build file for the Alster project:

<target name="alster" description="Run all Alster tests">
  <taskdef name="alster" classname="net.sf.alster.AlsterTextTask">
1

    <classpath>
      <pathelement location="${builddir}"/>
    </classpath>
  </taskdef>
  <alster dir="${testsrcdir}" failonerror="yes"
          recurse="yes" resultdir="${testresultdir}">
2

    <classpath>
      <path refid="cp"/>
      <pathelement location="${builddir}"/>
    </classpath>
  </alster>
</target>

1 The <alster> task needs to be defined in the Ant build file using the <taskdef> task. The Ant task class of the <alster> task is net.sf.alster.AlsterTextTask.

2 Similar to the command line version of the Alster test runner, the <alster> Ant task recognizes two attributes (named dir and recurse) for defining the test source directory and the recursion behavior.
     Additionally, the failonerror attribute can be set to "yes" if any failure of the testing should lead to the build process to be stopped.
     Unlike the command line version, the <alster> task writes the detailed output into individual files in a directory which may be specified via the resultdir attribute.

This will create a file named TEST-net.sf.alster.test.addTest.txt in the directory specified by the ${testresultdir} property with the following content:

Testsuite: net.sf.alster.test.addTest
Tests run: 3, Failures: 0, Time elapsed: 0.04 sec

Testcase: alster:testRoot2 took 0.03 sec
Testcase: alster:testRoot1 took 0.01 sec
Testcase: alster:testAdd took 0 sec

Licensing

Alster is licensed under the Apache Software License 2.0.

The application uses the following APIs which are included in the distribution:
Archive(s) Description Version Use License Remarks/Resource URL
xercesImpl.jar, xml-apis.jar Xerces XML parser 2.7.1 compile,runtime Apache Software License 2.0 http://xerces.apache.org/xerces2-j/
ant.jar Apache Ant build framework 1.6.5 compile,runtime Apache Software License 2.0 http://ant.apache.org/
xalan.jar Xalan XSLT transformer 2.7.1 runtime Apache Software License 2.0 http://xml.apache.org/xalan-j/
nalax.jar XSLT extension package 0.9.3 runtime Apache Software License 2.0 http://nalax.sourceforge.net
junit.jar Java unit testing framework 3.8.1 compiling (just unit tests), testing Common Public License 1.0 http://junit.sourceforge.net/
xdc.jar XML documentation tool 0.5.2-b2 documentation Lesser Gnu Public License 2.1 http://xdc.sourceforge.net
log4j-1.2.9.jar Logging library 1.2.9 documentation Apache Software License 2.0 used by xdc http://logging.apache.org/log4j/docs/index.html
commons-cli-1.0.jar Commons CLI (Command line interface) 1.0 documentation Apache Software License 2.0 used by xdc http://jakarta.apache.org/commons/cli/

Installation

Installation from Source

If you have downloaded the Alster sources, follow these steps to install the software:

  1. Extract the source archive into a new directory and open a shell in that directory.

  2. Run the build.sh resp. build.bat script. This will invoke the Ant build utility and execute a number of build steps such as cleaning the directories, compiling the Alster and the unit test sources, running the tests, generating the documentation and packaging the generated classes into a JAR file.

Binary Installation

If you have downloaded the binaries of the Alster application, install Alster by following these steps:

  1. Extract the XDC binary archive into a new directory.