Changing test results formatter with Test::Builder2(Currently beta)
http://d.hatena.ne.jp/gfx/20110810/1312933806
http://subtech.g.hatena.ne.jp/cho45/20110613/1307947167
Some of the people trying to change test results formatter with Test::Builder. But it's very painful and silly since Test::Builder doesn't support extending formatter.
Test::Builder2 supports to modify test results format. You can write your own formatter class.
use strict; use warnings; use utf8; package Test::Builder2::Formatter::TAP::WithLineNumber; use parent qw(Test::Builder2::Formatter::TAP::v13); sub accept_result { my $self = shift; my $result = shift; # FIXME: there is a lot more detail in the # result object that I ought to do deal with. my $out = ""; $out .= "not " if !$result->literal_pass; $out .= "ok"; my $num = $result->test_number || $self->counter->increment; $out .= " ".$num if $self->use_numbers; # XXX HACKING BEGIN HERE my $line = sub { for (1..20) { my @caller = caller($_); return unless @caller; return $caller[2] unless $caller[0] =~ /^Test::/; } }->(); my $name = "L$line: " . ($result->description || ''); # XXX HACKING END HERE $self->_escape(\$name); $out .= " - $name" if defined $name and length $name; my $reason = $result->reason; $self->_escape(\$reason); my @directives; push @directives, "TODO" if $result->is_todo; push @directives, "SKIP" if $result->is_skip; $out .= " # @{[ join ' ', @directives ]} $reason" if @directives; $out .= "\n"; $self->out($out); if(!$result->literal_pass and !$result->is_skip) { # XXX This should also emit structured diagnostics $self->_comment_diagnostics($result); } $self->seen_results(1); return; } 1;
The code too long but most part is copy&pasted.
And you can use the formatter like following code:
use strict; use warnings; use utf8; use lib './test-more/lib/'; use Test::More; use Test::Builder2::Formatter::TAP::WithLineNumber; Test::More->builder->event_coordinator->formatters( [ Test::Builder2::Formatter::TAP::WithLineNumber->new() ] ); ok 'heh' for 1..2; fail 'heh' for 1..3; ok 'heh' for 1..3; fail 'heh' for 1..4; done_testing;
And sample output is here:
TAP version 13 ok 1 - L11: ok 2 - L11: not ok 3 - L12: heh # Failed test 'heh' # at hoge.t line 12. not ok 4 - L12: heh # Failed test 'heh' # at hoge.t line 12. not ok 5 - L12: heh # Failed test 'heh' # at hoge.t line 12. ok 6 - L13: ok 7 - L13: ok 8 - L13: not ok 9 - L14: heh # Failed test 'heh' # at hoge.t line 14. not ok 10 - L14: heh # Failed test 'heh' # at hoge.t line 14. not ok 11 - L14: heh # Failed test 'heh' # at hoge.t line 14. not ok 12 - L14: heh # Failed test 'heh' # at hoge.t line 14. 1..12 # 7 tests of 12 failed.
Conclusion
- You can write your own test results formatter with Test::Builder2
- Test::Builder2 is currently β version.
- I'm waiting to release Test::Builder2!