Re: [Perlunit-users] Comparing deeply nested data structures.
Status: Beta
Brought to you by:
mca1001
|
From: Adrian H. <ad...@qu...> - 2007-05-16 23:26:53
|
On 16 May 2007, at 18:17, Desilets, Alain wrote:
[snip]
> I want to easily compare the output of that method to expected
> output, and if the two differ, get a good diagnostic message that
> describes exactly how the two differ.
[snip]
> Is there something in Perl that would allow me to do this?
In Test::Unit there's assert_deep_equals() - for example:
sub test_using_assert_deep_equals {
my $self = shift;
$self->assert_deep_equals(
[ { hello =>1}, { world => 1 } ],
[ { hello =>1}, { earth => 1 } ]
);
}
that gives you a diagnostic like
1) /Users/adrianh/Desktop/test.pl:53 - test_using_assert_deep_equals
(Comparison::Test)
Structures begin differing at:
$a->[1]{earth} = Does not exist
$b->[1]{earth} = '1'
> I stumbled across cmp_deeply(), but I can't figure out how to use
> it. It's part of a testing framework different from PerlUnit, and I
> can't seem to be able to use it without running it inside that
> other testing framework (which I don't have time to learn).
It's not that hard to shim the more popular Test::Builder based
"assertion" modules into Test::Unit. The off-the-top-of-my-head
greasy hack of:
{ package Test::Unit::MyTestCase;
use base qw( Test::Unit::TestCase );
use Test::Builder '0.7';
use Carp qw( confess );
sub assert_using {
my ( $self, $test_coderef ) = @_;
my $builder = Test::Builder->new;
$builder->reset;
$builder->plan( 'no_plan' );
my $output = '';
open my $output_fh, '>', \$output or die;
$builder->output( $output_fh );
$builder->failure_output( $output_fh );
$builder->todo_output( $output_fh );
$self->assert( $test_coderef->(), $output );
}
}
would allow you to do things like:
{ package Comparison::Test;
use base qw( Test::Unit::MyTestCase );
use Test::More; # provides is_deeply
sub test_using_is_deeply {
my $self = shift;
$self->assert_using( sub {
is_deeply [ { hello =>1}, { world => 1 } ],
[ { hello =>1}, { earth => 1 } ];
} );
}
use Test::Deep; # provides cmp_deeply
sub test_using_cmp_deeply {
my $self = shift;
$self->assert_using( sub {
cmp_deeply( [ { hello =>1}, { world => 1 } ],
[ { hello =>1}, { earth => 1 } ]
);
} );
}
}
giving you diagnostics like
2) /private/var/tmp/folders.502/Cleanup At Startup/
test-201050484.793.pl:21 - test_using_cmp_deeply(Comparison::Test)
not ok 1
# Failed test at /private/var/tmp/folders.502/Cleanup At Startup/
test-201050484.793.pl line 43.
# Comparing hash keys of $data->[1]
# Missing: 'earth'
# Extra: 'world'
3) /private/var/tmp/folders.502/Cleanup At Startup/
test-201050484.793.pl:21 - test_using_is_deeply(Comparison::Test)
not ok 1
# Failed test at /private/var/tmp/folders.502/Cleanup At Startup/
test-201050484.793.pl line 33.
# Structures begin differing at:
# $got->[1]{earth} = Does not exist
# $expected->[1]{earth} = '1'
However if you're going to be using a bunch of Test::Builder based
assertions it might be easier to use Test::Group or <bias
class="author"> Test::Class </bias> instead.
Cheers,
Adrian
|