Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Test::Differences(3)  User Contributed Perl Documentation Test::Differences(3)

       Test::Differences - Test	strings	and data structures and	show
       differences if not ok

	  use Test;    ## Or use Test::More
	  use Test::Differences;

	  eq_or_diff $got,  "a\nb\nc\n",   "testing strings";
	  eq_or_diff \@got, [qw( a b c )], "testing arrays";

	  ## Passing options:
	  eq_or_diff $got, $expected, $name, { context => 300 };  ## options

	  ## Using with	DBI-like data structures

	  use DBI;

	  ... open connection &	prepare	statement and @expected_... here...

	  eq_or_diff $sth->fetchall_arrayref, \@expected_arrays	 "testing DBI arrays";
	  eq_or_diff $sth->fetchall_hashref,  \@expected_hashes, "testing DBI hashes";

	  ## To	force textual or data line numbering (text lines are numbered 1..):
	  eq_or_diff_text ...;
	  eq_or_diff_data ...;

       This module exports three test functions	and four diff-style functions:

       o   Test	functions

	   o   "eq_or_diff"

	   o   "eq_or_diff_data"

	   o   "eq_or_diff_text"

       o   Diff	style functions

	   o   "table_diff" (the default)

	   o   "unified_diff"

	   o   "oldstyle_diff"

	   o   "context_diff"

       When the	code you're testing returns multiple lines, records or data
       structures and they're just plain wrong,	an equivalent to the Unix
       "diff" utility may be just what's needed.  Here's output	from an
       example test script that	checks two text	documents and then two
       (trivial) data structures:

	not ok 1 - differences in text
	#     Failed test ((eval 2) at line 14)
	#     +---+----------------+----------------+
	#     |	Ln|Got		   |Expected	    |
	#     +---+----------------+----------------+
	#     |	 1|this	is line	1  |this is line 1  |
	#     *	 2|this	is line	2  |this is line b  *
	#     |	 3|this	is line	3  |this is line 3  |
	#     +---+----------------+----------------+
	not ok 2 - differences in whitespace
	#     Failed test ((eval 2) at line 20)
	#     +---+------------------+------------------+
	#     |	Ln|Got		     |Expected		|
	#     +---+------------------+------------------+
	#     |	 1|	   indented  |	      indented	|
	#     *	 2|	   indented  |\tindented	*
	#     |	 3|	   indented  |	      indented	|
	#     +---+------------------+------------------+
	not ok 3
	#     Failed test ((eval 2) at line 22)
	#     +----+-------------------------------------+----------------------------+
	#     |	Elt|Got					 |Expected		      |
	#     +----+-------------------------------------+----------------------------+
	#     *	  0|bless( [				 |[			      *
	#     *	  1|  'Move along, nothing to see here'	 |  'Dry, humorless message'  *
	#     *	  2|], 'Test::Builder' )		 |]			      *
	#     +----+-------------------------------------+----------------------------+
	# Looks	like you failed	3 tests	of 3.

       eq_or_diff_...()	compares two strings or	(limited) data structures and
       either emits an ok indication or	a side-by-side diff.
       Test::Differences is designed to	be used	with and with
       Test::Simple, Test::More, and other Test::Builder based testing
       modules.	 As the	SYNOPSIS shows,	another	testing	module must be used as
       the basis for your test suite.

       The options to "eq_or_diff" give	some fine-grained control over the

       o   "context"

	   This	allows you to control the amount of context shown:

	      eq_or_diff $got, $expected, $name, { context => 50000 };

	   will	show you lots and lots of context.  Normally, eq_or_diff()
	   uses	some heuristics	to determine whether to	show 3 lines of
	   context (like a normal unified diff)	or 25 lines.

       o   "data_type"

	   "text" or "data". See "eq_or_diff_text" and "eq_or_diff_data" to
	   understand this. You	can usually ignore this.

       o   "Sortkeys"

	   If passed, whatever value is	added is used as the argument for
	   Data::Dumper	Sortkeys option. See the Data::Dumper docs to
	   understand how you can control the Sortkeys behavior.

       o   "filename_a"	and "filename_b"

	   The column headers to use in	the output. They default to 'Got' and

       For extremely long strings, a table diff	can wrap on your screen	and be
       hard to read.  If you are comfortable with different diff formats, you
       can switch to a format more suitable for	your data.  These are the four
       formats supported by the	Text::Diff module and are set with the
       following functions:

       o   "table_diff"	(the default)

       o   "unified_diff"

       o   "oldstyle_diff"

       o   "context_diff"

       You can run the following to understand the different diff output

	use Test::More 'no_plan';
	use Test::Differences;

	my $long_string	= join '' => 1..40;

	TODO: {
	    local $TODO	= 'Testing diff	styles';

	    # this is the default and does not need to explicitly set unless you need
	    # to reset it back from another diff type
	    eq_or_diff $long_string, "-$long_string", 'table diff';

	    eq_or_diff $long_string, "-$long_string", 'unified diff';

	    eq_or_diff $long_string, "-$long_string", 'context diff';

	    eq_or_diff $long_string, "-$long_string", 'oldstyle	diff';

       Generally you'll	find that the following	test output is disappointing.

	   use Test::Differences;

	   my $want = {	'Traditional Chinese' => 'a,a' };
	   my $have = {	'Traditional Chinese' => 'a,a1/2' };

	   eq_or_diff $have, $want, 'Unicode, baby';

       The output looks	like this:

	   #   Failed test 'Unicode, baby'
	   #   at t/unicode.t line 12.
	   # +----+----------------------------+----------------------------+
	   # | Elt|Got			       |Expected		    |
	   # +----+----------------------------+----------------------------+
	   # |	 0|'Traditional	Chinese'       |'Traditional Chinese'	    |
	   # *	 1|'\xe4\xb8\xad\xe5\x9b\xbd'  |'\xe4\xb8\xad\xe5\x9c\x8b'  *
	   # +----+----------------------------+----------------------------+
	   # Looks like	you failed 1 test of 1.
	   Dubious, test returned 1 (wstat 256,	0x100)

       This is generally not helpful and someone points	out that you didn't
       declare your test program as being utf8,	so you do that:

	   use Test::Differences;
	   use utf8;

	   my $want = {	'Traditional Chinese' => 'a,a' };
	   my $have = {	'Traditional Chinese' => 'a,a1/2' };

	   eq_or_diff $have, $want, 'Unicode, baby';

       Here's what you get:

	   #   Failed test 'Unicode, baby'
	   #   at t/unicode.t line 12.
	   # +----+-----------------------+-----------------------+
	   # | Elt|Got			  |Expected		  |
	   # +----+-----------------------+-----------------------+
	   # |	 0|'Traditional	Chinese'  |'Traditional	Chinese'  |
	   # *	 1|'\x{4e2d}\x{56fd}'	  |'\x{4e2d}\x{570b}'	  *
	   # +----+-----------------------+-----------------------+
	   # Looks like	you failed 1 test of 1.
	   Dubious, test returned 1 (wstat 256,	0x100)
	   Failed 1/1 subtests

       That's better, but still	awful. However,	if you have "Text::Diff" 0.40
       or higher installed, you	can add	this to	your code:


       Make sure you do	this before you	load Text::Diff. Then this is the

	   # +----+-----------------------+-----------------------+
	   # | Elt|Got			  |Expected		  |
	   # +----+-----------------------+-----------------------+
	   # |	 0|'Traditional	Chinese'  |'Traditional	Chinese'  |
	   # *	 1|'a,a1/2'		    |'a,a'		   *
	   # +----+-----------------------+-----------------------+

       There are several basic ways of deploying Test::Differences requiring
       more or less labor by you or your users.

       o   Fallback to "is_deeply".

	   This	is your	best option if you want	this module to be optional.

	    use	Test::More;
	    BEGIN {
		if (!eval q{ use Test::Differences; 1 }) {
		    *eq_or_diff	= \&is_deeply;


	    eval "use Test::Differences";

	   If you want to detect the presence of Test::Differences on the fly,
	   something like the following	code might do the trick	for you:

	       use Test	qw( !ok	);   ##	get all	syms *except* ok

	       eval "use Test::Differences";
	       use Data::Dumper;

	       sub ok {
		   goto	&eq_or_diff if defined &eq_or_diff && @_ > 1;
		   @_ =	map ref	$_ ? Dumper( @_	) : $_,	@_;
		   goto	Test::&ok;

	       plan tests => 1;

	       ok "a", "b";

       o   PREREQ_PM =>	{ .... "Test::Differences" => 0, ... }

	   This	method will let	CPAN and CPANPLUS users	download it
	   automatically.  It will discomfit those users who choose/have to
	   download all	packages manually.

       o   t/lib/Test/, t/lib/Text/, ...

	   By placing Test::Differences	and its	prerequisites in the t/lib
	   directory, you avoid	forcing	your users to download the
	   Test::Differences manually if they aren't using CPAN	or CPANPLUS.

	   If you put a	"use lib "t/lib";" in the top of each test suite
	   before the "use Test::Differences;",	"make test" should work	well.

	   You might want to check once	in a while for new Test::Differences
	   releases if you do this.

   "Test" or "Test::More"
       This module "mixes in" with or any of the test libraries	based
       on Test::Builder	(Test::Simple, Test::More, etc).  It does this by
       peeking to see whether or Test/ is in %INC, so	if you
       are not using one of those, it will print a warning and play dumb by
       not emitting test numbers (or incrementing them).  If you are using one
       of these, it should interoperate	nicely.

       Exports all 3 functions by default (and by design).  Use

	   use Test::Differences ();

       to suppress this	behavior if you	don't like the namespace pollution.

       This module will	not override functions like ok(), is(),	is_deeply(),
       etc.  If	it did,	then you could "eval "use Test::Differences qw(
       is_deeply );"" to get automatic upgrading to diffing behaviors without
       the "sub	my_ok" shown above.  Test::Differences intentionally does not
       provide this behavior because this would	mean that Test::Differences
       would need to emulate every popular test	module out there, which	would
       require far more	coding and maintenance that I'm	willing	to do.	Use
       the eval	and my_ok deployment shown above if you	want some level	of

       Perls before 5.6.0 don't	support	characters > 255 at all, and 5.6.0
       seems broken.  This means that you might	get odd	results	using
       perl5.6.0 with unicode strings.

   "Data::Dumper" and older Perls.
       Relies on Data::Dumper (for now), which,	prior to perl5.8, will not
       always report hashes in the same	order.	 $Data::Dumper::Sortkeys  is
       set to 1, so on more recent versions of Data::Dumper, this should not
       occur.  Check CPAN to see if it's been peeled out of the	main perl
       distribution and	backported.  Reported by Ilya Martynov
       <>, although the Sortkeys "future perfect" workaround
       has been	set in anticipation of a new Data::Dumper for a	while.	Note
       that the	two hashes should report the same here:

	   not ok 5
	   #	 Failed	test (t/ctrl/05-home.t at line 51)
	   # +----+------------------------+----+------------------------+
	   # | Elt|Got			   | Elt|Expected		 |
	   # +----+------------------------+----+------------------------+
	   # |	 0|{			   |   0|{			 |
	   # |	 1|  'password'	=> '',	   |   1|  'password' => '',	 |
	   # *	 2|  'method' => 'login',  *	|			 |
	   # |	 3|  'ctrl' => 'home',	   |   2|  'ctrl' => 'home',	 |
	   # |	  |			   *   3|  'method' => 'login',	 *
	   # |	 4|  'email' =>	'test'	   |   4|  'email' => 'test'	 |
	   # |	 5|}			   |   5|}			 |
	   # +----+------------------------+----+------------------------+

       Data::Dumper also overlooks the difference between

	   $a[0] = \$a[1];
	   $a[1] = \$a[0];   # $a[0] = \$a[1]


	   $x =	\$y;
	   $y =	\$x;
	   @a =	( $x, $y );  # $a[0] = \$y, not	\$a[1]

       The former involves two scalars,	the latter 4: $x, $y, and @a[0,1].
       This was	carefully explained to me in words of two syllables or less by
       Yves Orton <>.  The plan to address this is to
       allow you to select Data::Denter	or some	other module of	your choice as
       an option.

	   Barrie Slaymaker <> - original author

	   Curtis "Ovid" Poe <>

	   David Cantrell <>

       Copyright Barrie	Slaymaker, Curtis "Ovid" Poe, and David	Cantrell.

       All Rights Reserved.

       You may use, distribute and modify this software	under the terms	of the
       GNU public license, any version,	or the Artistic	license.

perl v5.32.1			  2019-02-19		  Test::Differences(3)


Want to link to this manual page? Use this URL:

home | help