Another example with is_deeply checking the returned hash from a bug tracking system.

examples/perl/t/is_deeply_bugs.t
#!/usr/bin/perl 
use strict;
use warnings;

use lib 'lib';
use MyBugs;
use Test::More tests => 3;

my %expected = (
    bugs     => 3,
    errors   => 6,
    failures => 8,
    warnings => 1,
);


my %a = fetch_data_from_bug_tracking_system(0);
is_deeply( \%a, \%expected, "Query 0" );

my %b = fetch_data_from_bug_tracking_system(1);
is_deeply( \%b, \%expected, "Query 1" );

my %c = fetch_data_from_bug_tracking_system(2);
is_deeply( \%c, \%expected, "Query 2" );


1..3
ok 1 - Query 0
not ok 2 - Query 1
#   Failed test 'Query 1'
#   at t/is_deeply_bugs.t line 21.
#     Structures begin differing at:
#          $got->{errors} = '9'
#     $expected->{errors} = '6'
not ok 3 - Query 2
#   Failed test 'Query 2'
#   at t/is_deeply_bugs.t line 24.
#     Structures begin differing at:
#          $got->{errors} = Does not exist
#     $expected->{errors} = '6'
# Looks like you failed 2 tests of 3.

What if we are testing a live system and so not interested in the exact values, just in the keys and the fact that the values are numbers?

Look at the code that generates the bug reports you'll see that testing the 4th return value - which is quite complex already - is hard. We cannot test against a fixed hash as some of the values are totally dynamic (e.g. a timestamp).

examples/perl/lib/MyBugs.pm
package MyBugs;
use strict;
use warnings FATAL => 'all';

our $VERSION = '0.01';

use base 'Exporter';
our @EXPORT = qw(fetch_data_from_bug_tracking_system);

=head2 fetch_data_from_bug_tracking_system

fake the behavior of a bug tracking system by returning various constructs

=cut
sub fetch_data_from_bug_tracking_system {
    my @sets = (
        {   bugs     => 3,
            errors   => 6,
            failures => 8,
            warnings => 1,
        },
        {   bugs     => 3,
            errors   => 9,
            failures => 8,
            warnings => 1,
        },
        {   bogs     => 3,
            erors    => 9,
            failures => 8,
            warnings => 1,
        },
        {   bugs     => 'many',
            errors   => 6,
            failures => 8,
            warnings => 1,
        },
        {
            bugs => [
                {
                    ts   => time,
                    name => "System bug",
                    severity => 3,
                },
                {
                    ts    => time - int rand(100),
                    name  => "Incorrect severity bug",
                    severity => "extreme",
                },
                {
                    ts    => time - int rand(200),
                    name  => "Missing severity bug",
                },
            ],
        },    
    );
    my $h = $sets[shift];
    return %$h;
}


1;