Chapter 13. Testing and Debugging

Frequently, crashes are followed with a message like “ID 02.” “ID” is an abbreviation for idiosyncrasy and the number that follows indicates how many more months of testing the product should have had.

Guy Kawasaki

Many XSLT scripts you write will be so-called one-offs that transform well-defined input. Here testing does little more than execute the transformation against the input and inspect the output. However, even in this simple case, how do you best deal with a stylesheet that does not do what you expect? Usually, simple inspection of the code reveals the offending lines. However, debugging by code inspection is often not effective for developers new to XSLT—including those who are seasoned in manipulating XML in more procedural languages. This chapter demonstrates basic debugging techniques that offer quicker solutions to common coding mistakes and enhance your understanding of XSLT.

Many examples in this book emphasize the creation of reusable XSLT. Authors of reusable code must subject that code to more rigorous testing. By definition, reusable code is often deployed in contexts of which the author cannot have full knowledge. You should ensure that the code performs as advertised for typical inputs and boundary conditions. Reusable code should also behave predictably in the face of illegal inputs.

Developers are more likely to test when it is easy. Interpreted languages such as XSLT are typically easier to test because there is no compile and link cycle. XSLT has a further advantage in that it is homoiconic—the syntax of the language and its data are identical. This feature allows easy embedding of test data into the stylesheet, thus creating completely self-contained tests.

All recipes in this chapter are based purely on facilities in XSLT. However, nothing beats a native debugger. The following is a list of commercial products in this space. I have not tried all the products, so do not interpret the list as an endorsement. Many products do much more than debug XSLT.

Treebeard (http://treebeard.sourceforge.net/) is an open source project that is written in Java and works with Xalan, Saxon, jd, and Oracle XSLT processors. It is more of a visual XSLT development environment than a full-fledged debugger, but it can help debug XPath expressions.

Using xsl:message Effectively

Problem

You want to inspect your stylesheet to determine why it does not do what you expect.

Solution

The simplest tool in your debugging arsenal is xsl:message, which is often used to figure out if you are executing a particular template:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   
<!-- ... -->
   
<xsl:template match="someElement[someChild = 'someValue']">
  <xsl:message>Matched someElement[someChild = 'someValue']</xsl:message>
   
  <!-- ... -->
   
</xsl:template>
   
</xsl:stylesheet>

The technique is even more useful when you display relevant data. Be sure to surround the output with known, descriptive text so you can disambiguate the output from other occurrences of xsl:message and detect when a message was executed (but the results were empty):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   
<xsl:template match="someElement[someChild = 'someValue']">
  <xsl:param name="myParam"/>
  <!-- This is not an effective debugging technique. If you run a test and see
       nothing it might be because the template was never matched or it might be
       because it was matched with $myParam empty -->
  <xsl:message><xsl:value-of select="$myParam"/></xsl:message>
</xsl:template>
   
<xsl:template match="someElement[someChild = 'someOtherValue']">
  <xsl:param name="myParam"/>
  <!-- This is better -->
  <xsl:message>Matched someElement[someChild = 'someOtherValue']</xsl:message>
  <xsl:message>$myParam=[<xsl:value-of select="$myParam"/>]</xsl:message>
</xsl:template>
   
</xsl:stylesheet>

Use a debugging parameter to preserve xsl:message-based instrumentation in your stylesheet. Place the parameter in your own namespace if you want to distribute the code to others without interfering with their own debug instrumentation:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                         xmlns:dbg="http:www.ora.com/
XSLTCookbook/ns/debug">
   
<xsl:param name="dbg:debugOn" select="false(  )"/>
   
<xsl:template match="someElement[someChild = 'someValue']">
  <xsl:param name="myParam"/>
  <xsl:if test="$dbg:debugOn">
    <xsl:message>Matched someElement[someChild = 'someValue']</xsl:message>
    <xsl:message>$myParam=[<xsl:value-of select="$myParam"/>]</xsl:message>
  </xsl:if>
</xsl:template>
   
</xsl:stylesheet>

Discussion

Before debuggers, there were print statements. Although some interactive XSLT debuggers are now available, none that I know of are free.

In addition to the previous usage of xsl:message, you might consider using assertions to test preconditions, postconditions, or invariants that must be true at some point in the stylesheet:

<xsl:if test="debugOn>
  <xsl:if test="insert some invariant test">
    <xsl:message terminate="yes">
               Message describing the violation or failure.
    </xsl:message>
  </xsl:if>
</xsl:if>

Assertion style tests typically use terminate="yes" because they are fatal errors by definition.

An important consideration when debugging with xsl:message is that the output’s destination varies, depending on the environment in which the XSLT script is executed. For example, you may not be able to see the output at all if the transformation runs in a browser client. It is usually advisable to test stylesheets using a command-line processor before moving to the target environment.

When the output is XML or HTML, an alternative to xsl:message is to emit debugging comments into the result document using xsl:comment. In particular, you can begin each template in your stylesheet with an xsl:comment to trace back from the output to the templates that generated it:

<xsl:template match="*">
     <xsl:comment>Generated by the wild card match</xsl:comment> 
 ...
</xsl:template>
   
...
   
<xsl:template match="*" mode="foo">
     <xsl:comment>Generated by the mode=foo wild card match</xsl:comment> 
 ...
</xsl:template>
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.82.23