View on
Randy J Ray > Test-Formats > Test::Formats



Annotate this POD

View/Report Bugs
Module Version: 0.10   Source  


Test::Formats - An umbrella class for test classes that target formatted data


Version 0.10


    use Test::Formats XML => tests => 5;

    our $schema = "structure.xsd";

    for (qw(file1.xml file2.xml file3.xml reference.xml minimal.xml))
        is_valid_against_xmlschema($schema, $_, "$_ validation");


The Test::Formats module provides unit tests of the Test::More variety, that work with any TAP-driven test-harness system. The tests are oriented towards testing textual data that follows defined formats, such as XML or YAML. Rather than using regular expressions or string-equality comparisons, the classes provided with this distribution use existing validators. For example, the XML tests (see Test::Formats::XML) use the XML::LibXML module from CPAN which provides validation for XML Schema, RelaxNG and DTDs (SGML or XML style DTDs).

The tests accessible through Test::Formats are broken into groups called specializations, each represented by a class that inherits from the Test::Builder::Module class. Each of these can operate as a stand-alone test module, as their inheritance from Test::Builder::Module also provides access to the basic testing functionality (plan, skip, etc.). This module, Test::Formats, acts as an umbrella that makes it easier to load several of these groups at once.

This class does not actually provide any functionality of its own, except for an import method that removes arguments that identify specializations, loads them into the namespace of the caller, and passes the remaining arguments on to Test::Builder::Module which registers them with the current test-session being set up.

Defining Specialization Classes

A specialization class can stand alone, and does not need to be loaded through the Test::Formats container. It should be a subclass of Test::Builder::Module, or if it isn't it should provide the full functionality of Test::Builder through its own means.

If a specialization class is loaded through the Test::Formats umbrella, it will not receive any arguments in the use command that loads it. Any test-suite control arguments are passed on to the superclass. Therefore, the specialization class should not override the import method it inherits from Test::Builder::Module unless the local version ends with a call to SUPER::import(@_) (passing @_ ensures that the class does work when loaded directly, by passing any arguments it received to the parent class). The specialization class should instead rely only on the @EXPORT list to define the functions it provides.

See Test::Formats::XML for an example of a specialization class.

Loading Specializations from Test::Formats

One or more specialization classes can be loaded through a single call to Test::Formats by passing their names in the import-list to the load of this class. As an example:

    use Test::Formats XML => tests => 5;

This invocation loads the Test::Formats::XML specialization class, then passes the arguments tests and 5 on to the construction of the test suite.

Such classes do not need to be named Test::Formats::<Something>. The Test::Formats import method scans the list of arguments for any value that is not a reference and whose first character is an upper-case letter. Anything else is presumed to be intended for Test::Builder. If the argument string does not start with Test::, then the value of __PACKAGE__ is prepended to it. Thus, Test::Formats can itself be used as a base class in which the derived class' name is used in creating the full class name. If the argument's first six characters are Test::, then it is used without modification. The final name, modified or not, is then used in an eval block that tries to load the module via use, in the namespace that initally loaded Test::Formats (or the class derived from it).

To illustrate the modification of arguments to class names, consider this table:

    Main class name     Argument text     Name of class that get loaded
    ===============     =============     =============================
    Test::Formats       XML               Test::Formats::XML
    Test::Formats       XML::Simple       Test::Formats::XML::Simple
    Test::Formats       Test::Hooks       Test::Hooks
    My::Test::Formats   MyFormat          My::Test::Formats::MyFormat

Note that in the third case, no change is made to the argument. And in the fourth case (assuming that My::Test::Formats is a subclass of Test::Formats) the modified argument has the derived class prepended to it, not Test::Formats.


Test::Formats does not export any functions of its own. It only facilitates the loading of specialization classes and the export of their functionality into the namespace of the package that uses Test::Formats. However, since it is a sub-class of Test::Builder::Module, it is fully usable as a test framework (provided at least one specialization is loaded) and provides all the functionality described in Test::More (in addition to any functions provided by specialization classes). See Test::More for documentation on those functions provided.


Please report any bugs or feature requests to bug-test-formats at, or through the web interface at I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.



The original idea for this stemmed from a blog post on by Curtis "Ovid" Poe. He proferred some sample code based on recent work he'd done, that validated against a RelaxNG schema. I generalized it for all the validation types that XML::LibXML offers, and expanded the idea to cover more general cases of structured, formatted text.


Copyright (c) 2008 Randy J. Ray, all rights reserved.

This module and the code within are released under the terms of the Artistic License 2.0 ( This code may be redistributed under either the Artistic License or the GNU Lesser General Public License (LGPL) version 2.1 (



Randy J. Ray, <rjray at>

syntax highlighting: