Test Driven Development of Excel::Writer::XLSX Part II

Test Driven Development of Excel::Writer::XLSX Part II

In the first part of this post we looked at how I used auto-generated code and tests to speed up the re-write of Spreadsheet::WriteExcel into Excel::Writer::XLSX.

This dealt with tests at the unit or method level. At the class level I was able to use tests that compared module results against actual XML from an Excel XLSX file. The following is an extract from an example test case. The XML in the DATA section is from an Excel file, pretty printed via xmllint.

###########################################################################
#
# Test the _assemble_xml_file() method.
#
$caption = " \tWorksheet: _assemble_xml_file()";

$worksheet = _new_worksheet(\$got);

$worksheet->select();
$worksheet->_assemble_xml_file();

$expected = _expected_to_aref();
$got      = _got_to_aref( $got );

_is_deep_diff( $got, $expected, $caption );

__DATA__
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"">
  <dimension ref="A1"/>
  <sheetViews>
    <sheetView tabSelected="1" workbookViewId="0"/>
  </sheetViews>
  <sheetFormatPr defaultRowHeight="15"/>
  <sheetData/>
  <pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75"/>
</worksheet>

The _is_deep_diff() test function used in the test above is a wrapper for the Test::Differences eq_or_diff() test method.

I prefer not to impose Test module dependencies on the end user unless they are necessary. In this case the _is_deep_diff() test function uses Test::Differences if it is available and falls back to the core Test::More is_deeply() function if it is not.

The Test::Differences output for a failing test case might look like the following:

$ prove -l t/worksheet/worksheet_01.t 
t/worksheet/worksheet_01.t .. 1/1 
#   Failed test '   Worksheet: _assemble_xml_file()'
#   at t/lib/TestFunctions.pm line 268.
# +----+----------------------------------+--------------------------------+
# | Elt|Got                               |Expected                        |
# +----+----------------------------------+--------------------------------+
# |   5|</sheetViews>                     |</sheetViews>                   |
# *   6|<sheetFormatPr default="12.5" />  |<sheetFormatPr default="15" />  *
# |   7|<sheetData />                     |<sheetData />                   |
# +----+----------------------------------+--------------------------------+
# Looks like you failed 1 test of 1.

If you are going to invest time in Test Driven Development then in practice you are going to spend a lot of time looking at the output of failing test cases. As such I find the the diff style context of Test::Difference to be invaluable, particularly when there is more than one difference in the failing test case.

In the next part of this blog I'll demonstrate the final component of the test framework where I test complete Excel files against the output of Excel::Writer::XLSX.

1 Comment

A long time ago Randal and I had looked at making a Test::Differences-style module that could work with trees. It's implementation was more complicated than we cared to work with, especially for showing diffs.

Maybe someone will still make one.

Leave a comment

About John McNamara

user-pic Just another Perl hacker