For me Test driven programming in XSLT is a challenge. I tried to follow Thomas' hint in the discussion of my first TDD-blog and create test cases first but when writing XSLT programs I got into trouble:
- How do I write test cases for XSLT? Should I store them into the database or insert them into an existing transformation?
- How do I perform regression tests?
There are good and news: I found solutions for those problems and I think we can code XSLT by creating test cases first. So enrich our XSLT programs by test code as well as test data. And this is how it works.
Finding the right Modularization
An XSLT program consists of templates and in case of XSLT 2.0 functions. So I suggest to code each named templates and functions within an own XSLT program. Those XSLT programs are imported into the transformation that uses the functions and named templates with the command xsl:include.
Here is an example: I want to create a named template add. Therefore I create an own XSLT program - containing the testcase (and testdata). Afterwards I will code that template add.
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:test="http:ttrapp.gmxhome.de/test/xslt">
<xsl:with-param name="a" select="1"/>
<xsl:with-param name="b" select="1"/>
<xsl:when test="number($result) and $result = 2"/>
<xsl:value-of select="concat('Fehler: 1 + 1 = ', $result)"/>
Now I apply run this transformation with itself as an input. The template test:main is active because there is an element <test:main/> within this transformation.As we expected we get an error because the template with name add is not implemented yet.
So we implement it quickly. It has two parameters and the result is an addition:
Nor our XSLT-program is running but we get an error: "Fehler: 1 + 1 = NaN". Ok. The correction is simple:
With this Unit test I described the program behaviour and can perform regression tests. I know that people work this way so above programming style is XSLT-foklore.
The problem is that it makes the transformations longer and harder to understand. And with the number of named templates they get slower but I did not make any perfomance checks. Another possibility would be creating own XSLT-programs which include the XSLT-programs conatining templates. This would solve any performance problems, but I think keeping testcases together with templatesis better because of missing use accesses for XSLT programs and Simple Transformations.
In ABAP I can read in TADIR the XSL-Transformations. For each transformation I check whether it contains an element in the namespace http://ttrapp.gmxhome.de/test/xslt and run the transformation with itself as input. I could define that the result of a testcase in namespace like http://ttrapp.gmxhome.de/test/xslt is a set of BAL-messages in asXML and could automize this behaviour by writing an SCI-test.
In my Open Source XML-libary I implemented a a small framework you can use for test automatization in ABAP. In fact I chose a namespace urn:axl-project/test for that purpose.