package TAP::Formatter::JUnit; use strict; use warnings; use XML::Generator; use TAP::Formatter::JUnit::Session; use base qw(TAP::Formatter::Console); use Class::Field qw(field); our $VERSION = '0.01'; field 'testsuites' => []; ############################################################################### # Subroutine: open_test($test, $parser) ############################################################################### # Over-ridden 'open_test()' method. # # Creates a 'TAP::Formatter::JUnit::Session' session, instead of a console # formatter session. sub open_test { my ($self, $test, $parser) = @_; my $session = TAP::Formatter::JUnit::Session->new( { name => $test, formatter => $self, parser => $parser, } ); return $session; } ############################################################################### # Subroutine: summary($aggregate) ############################################################################### # Prints the summary report (in JUnit) after all tests are run. sub summary { my ($self, $aggregate) = @_; return if $self->silent(); my @suites = @{$self->testsuites}; print { $self->stdout } $self->xml->testsuites( @suites ); } ############################################################################### # Subroutine: xml() ############################################################################### # Returns a new 'XML::Generator', to generate XML output. sub xml { my $self = shift; unless ($self->{xml}) { $self->{xml} = XML::Generator->new(':pretty', ':std', 'encoding'=>'UTF-8'); } return $self->{xml}; } ############################################################################### # Subroutine: xml_unescape() ############################################################################### # Returns a new 'XML::Generator', to generate unescaped XML output. sub xml_unescape { my $self = shift; unless ($self->{xml_unescape}) { $self->{xml_unescape} = XML::Generator->new(':pretty', ':std', 'escape'=>'unescaped', 'encoding'=>'UTF-8'); } return $self->{xml_unescape}; } ############################################################################### # Subroutine: add_testsuite($suite) ############################################################################### # Adds the given XML test '$suite' to the list of test suites that we've # executed and need to summarize. sub add_testsuite { my ($self, $suite) = @_; push @{$self->testsuites}, $suite; } 1; =head1 NAME TAP::Formatter::JUnit - Harness output delegate for JUnit output =head1 SYNOPSIS On the command line, with F: prove --formatter TAP::Formatter::JUnit ... Or, in your own scripts: use TAP::Harness; my $harness = TAP::Harness->new( { formatter_class => 'TAP::Formatter::JUnit', merge => 1, } ); $harness->runtests(@tests); =head1 DESCRIPTION B C provides JUnit output formatting for C. By default (e.g. when run with F), the I test suite is gathered together into a single JUnit XML document, which is then displayed on C. You can, however, have individual JUnit XML files dumped for each individual test, by setting c to a directory that you would like the JUnit XML dumped to. Note, that this will B cause C to dump the original TAP output into that directory as well (but IMHO that's ok as you've now got the data in two parsable formats). Timing information is included in the JUnit XML, I you specified C<--timer> when you ran F. The JUnit output generated is partial to being grokked by L. That's the build tool I'm using at the moment and needed to be able to generate JUnit output for. =head1 METHODS =over =item B Over-ridden C method. Creates a C session, instead of a console formatter session. =item B Prints the summary report (in JUnit) after all tests are run. =item B Returns a new C, to generate XML output. =item B Returns a new C, to generate unescaped XML output. =item B Adds the given XML test C<$suite> to the list of test suites that we've executed and need to summarize. =back =head1 AUTHOR Graham TerMarsch Many thanks to Andy Armstrong et al. for the B set of tests in C; they became the basis for the unit tests here. =head1 COPYRIGHT Copyright 2008-2009, Graham TerMarsch. All Rights Reserved. This is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 SEE ALSO L, L, L, L, L. =cut