Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

TDML stands for "Test Data Markup Language". It is a way of specifying a DFDL schema, the test data, the expected result or expected error/diagnostic messages, and it is all in a single self-contained XML file. IBM started TDML to capture tests for their own DFDL implementation. Daffodil latched onto this and has since extended it a bit, though there is an effort to reconcile TDML dialects so that all implementations can run the same tests.

By convention, a TDML file uses file extension ".tdml".

...

Code Block
<?xml version="1.0" encoding="ASCII"?>
<!-- 
Example of a self-contained test described in a TDML file
 -->

 <tdml:testSuite 
  suiteName="Suspected Bugs
A TDML file is actually a test suite of tests, but this example
includes only 1 test.
 -->

 <tdml:testSuite 
  suiteName="My suspected bugs" 
  description="Illustrates issues found 2013-04-01. No fooling."
  xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:ex="http://example.com">

  <!--
    Use defineSchema to include a DFDL schema directly inside the TDML file.
    You can alternatively put the DFDL schema in a separate file if you prefer.

    Each defineSchema has a name, so that one TDML file can contain tests which reference
    different DFDL schemas. 

    To embed a schema inside the TDML you don't include the <xs:schema...> element from
    the schema file, nor do you need to wrap the top-level DFDL annotation objects with
    xs:annotation and xs:appinfo.

    In other words, inside a defineSchema you can directly put: 
    dfdl:defineFormat, dfdl:defineEscapeSchema,
    dfdl:format (for the default format), xs:element, xs:simpleType, xs:complexType, xs:group.
   -->

  <tdml:defineSchema name="s1">

    <dfdl:defineFormat <!-- a named format definition - notice no surrounding xs:annotation nor xs:appinfo -->

    <dfdl:defineFormat name="myDefaults">
      <dfdl:format lengthKind="implicit" representation="text"
        lengthUnits="bytes" encoding="US-ASCII" initiator="" terminator=""
        separator="" ignoreCase="no" textNumberRep="standard" />
    </dfdl:defineFormat>

    <dfdl:<!-- default format ref="myDefaults" /declaration -->

     <dfdl:format ref="myDefaults" />

    <!-- 
      Now imagine we are reporting a bug with date/time functionality, and
      this element exercises the feature of concern.
     -->
     
  <xs:element name="dateTimeText" type="xs:dateTime" 
      dfdl:calendarPattern="MM.dd.yyyy 'at' HH:mm:ss ZZZZ" 
      dfdl:calendarPatternKind="explicit"
	  dfdl:lengthKind="explicit" dfdl:length="{ 35 }" />

    <!-- That's it for the schema for this small example -->
  </tdml:defineSchema>

<!-- 
   Here is a test case that exercises the above schema.

   A single TDML file can contain many test cases like the one below. This
   example has only one.

   You must give the name of the model (aka the schema), that can be the name of a
   schema defined immediately in this file like above, or a file name.

   You must also give the name of the root element that the test will use.
 -->

<tdml:parserTestCase name="dateTimeText" root="dateTimeText"
    model="s1" description="date time issue"> <!-- description is optional --> 

  <!--
   The data for your test is given by the tdml:document element.

   Notice specifically the use of the CDATA bracketing of the data. This
   insures that no unintended whitespace gets inserted around your data.
  -->
    <tdml:document><![CDATA[04.02.2013 at 14:00:56 GMT-05:00]]></tdml:document>

  <!--
   The infoset element gives the expected infoset, expressed as an XML fragment.
  -->

  <tdml:infoset>
  <!--
     Always need this extra tdml:dfdlInfoset element as well
    -->
       <tdml:dfdlInfoset>

    <!--
      Here is our actual expected result, where the date and time
      is now in XML's cannonical representation for these.
      -->
       <dateTimeText>2013-04-02T14:00:56-05:00</dateTimeText>
      </tdml:dfdlInfoset>
    </tdml:infoset>

<!-- end of the test case -->
 </tdml:parserTestCase>
<!-- end of the whole TDML file --> 
</tdml:testSuite>

Suppose you save the above out as a file "myDateTimeBug.tdml". You can then run it using the Daffodil command line tool: Command Line Interface.

Code Block
daffodil test myDateTimeBug.tdml

The Infoset element that contains the expected result may need to contain characters that are not legal in XML documents. Daffodil remaps these characters into legal XML characters in the Unicode Private-use-area. See Daffodil and the DFDL Infoset for details.

Specifying Data in Text, Hex, Bits, or External File

When specifying the test data, there are other ways to When specifying the test data, there are other ways to do this than using just text.

...

Code Block
    <tdml:document>

        <!--
          A document part with type="text" is text. Use CDATA to avoid whitespace changes.

          So in the example below, the line ending after '250;' and after '967;' are intentional
          parts of the data.
 so as to illustrate that the whitespace -->

is preserved if immportant when
  <tdml:documentPart type="text"><![CDATA[quantity:250;
hardnessRating:967;
]]></tdml:documentPart>

      <!-- 
you use CDATA bracketing.

         In 'text'If bothyou XMLcare characterexactly entities,which andkind DFDL'sof ownline characterending entitiesis are interpreted.

  used, then you 
        So here iscan ause NULDFDL terminatedcharacter stringentities thatto containsinsert a date with some Japanese Kanji characters.%CR; %LF; or both. In this example,
          Thebecause Japanesethe characterswhitespace areis expressed usingas XMLwhitespace, numericit characterdepends entities.on Thethe NULplatform terminationwhere
          isyou expressededit usingthis afile DFDLwhether character entity.

          In this example one has no choice but to use a DFDL character entity. The NUL character (which has character
   the line ending is a LF (Unix convention), or a 
          CRLF (MS Windows convention) 
         -->

       code zero), is not allowed in XML documents, not even using an XML character entity. So you 
          have to write '%NUL;' or '%#x00;' to express it using DFDL character entities.
        -->

      <tdml:documentPart type="text"><![CDATA[1987&#x5E74;10&#x6708;&#x65e5; BCE%NUL;]]></tdml:documentPart>
<tdml:documentPart type="text"><![CDATA[quantity:250;
hardnessRating:967;
]]></tdml:documentPart>

      <!-- 
          In 'text' both XML character entities, and DFDL's own character entities are interpreted.

          So here is a NUL terminated string that contains a date with some Japanese Kanji characters.
      <!--
    The Japanese characters are expressed using TypeXML 'byte'numeric meanscharacter useentities. hexadecimalThe toNUL specifytermination
  the data. Freeform whitespace is allowed. 
  is expressed using a DFDL character entity.

  Actually, any character that is not a-zA-Z0-9 is ignored.In Sothis youexample canone usehas "."no orchoice "-"but to separate
use a DFDL character entity. The NUL character (which has groupscharacter
 of hex digits if you like.
    code zero), is -->
 
      <tdml:documentPart type="byte">
      not allowed in XML documents, not even using an XML character entity. So you 
      9Abf e4c3
   have to write '%NUL;' or '%#x00;' to express  A5-E9-FF-00
      </tdml:documentPart>it using DFDL character entities.
      
       <!-->

          Type 'bits' allows you to specify individual 0 and 1. Any character other than 0 or 1 is ignored.
          <tdml:documentPart type="text"><![CDATA[1987&#x5E74;10&#x6708;&#x65e5; BCE%NUL;]]></tdml:documentPart>

      <!--
          Type 'byte' means use hexadecimal to specify the data. Freeform whitespace is allowed. 
          TheActually, numberany ofcharacter bitsthat doesis not have to be a multiple of 8. That is, whole bytes are not requireda-zA-Z0-9 is ignored. So you can use "." or "-" to separate
          groups of hex digits if you like.
         -->
 
       <tdml:documentPart type="bitsbyte">
            1.110 0.011 1 First 5 bit fields.
9Abf e4c3
            </tdml:documentPart>
A5-E9-FF-00
      </tdml:documentPart>
      
       <!--
          Type 'filebits' meansallows theyou contentto isspecify aindividual file0 nameand where1. toAny getcharacter theother data
than 0 or 1 is ignored.
    -->
  
       <tdml:documentPart type="file">/some/directory/testData.in.dat</tdml:documentPart>

    </tdml:document>

 

Further details on TDML will go in a more detailed guide/page about writing TDML.


          The number of bits does not have to be a multiple of 8. That is, whole bytes are not required.
         -->

       <tdml:documentPart type="bits">
            1.110 0.011 1 First 5 bit fields.
       </tdml:documentPart>

       <!--
          Type 'file' means the content is a file name where to get the data
         -->
  
       <tdml:documentPart type="file">/some/directory/testData.in.dat</tdml:documentPart>

    </tdml:document>

Further details on TDML will go in a more detailed guide/page about writing TDML.

If you use the external schema file or external data file capabilities, then of course you need to send those files along with your TDML.

Expecting Errors: Negative Tests

A poor or missing diagnostic message is a bug just as much as a broken feature. So one can also create negative tests, i.e., tests that expect errors.

To do this replace the tdml:infoset element with a tdml:errors element:

Code Block
<tdml:errors>
   <tdml:error>Schema Definition Error</tdml:error>
   <tdml:error>testElementName</tdml:error>
</tdml:errors>

Each tdml:error child element contains a sub-string which must be found somewhere in the set of diagnostic messages that come out of the test. The comparison is case-insensitive.

Final detail: In order for a positive test with an Infoset to pass, it must consume all the data. Otherwise the test will not pass, and will fail with a message about 'left over data'If you use the external schema file or external data file capabilities, then of course you need to send those files along with your TDML.