Getting Testy with Perl6:
Things you wish you'd known.
Steven Lembark
Workhorse Computing
lemark@wrkhors.com
Helpful items
$ panda install p6doc;
http://doc.perl6.org/
# doc for testing:
/language/testing
Helpful items
$ panda install p6doc;
http://doc.perl6.org/
# doc for testing:
/language/testing
Core module
Core modules are documented in:
./share/perl6/doc/Language/*
Which includes "testing.pod".
Viewing source
To see the source of a module:
panda look <module name>;
This will fetch the module (even if it is 
installed).
Basic of Perl6 Testing
Pretty much what you are used to:
  “Test” module for testing.
  ok(), is() & friends.
Main differences are in Perl6 itself.
What you are used to
Test::More
ok()
use v5.22;
use Test::More;
my $x = '0';
my $y = 'asdf';
ok $x == $y, "$x == $y";
done_testing;
What you are used to
Zero            
equals         
zero.
$ prove -v Perl5.t;
Perl5 ..
ok 1 - 0 == asdf
1..1
ok
All tests successful.
Files=1, Tests=1, ...
Result: PASS
Doing it in Perl6
Module 
is 
“Test”
use v6;
use Test;
my $x = '0';
my $y = 'asdf';
ok $x == $y, "$x == $y";
done-testing;
Doing it in Perl6
Notice        
the dash!
use v6;
use Test;
my $x = '0';
my $y = 'asdf';
ok $x == $y, "$x == $y";
done-testing;
Prove is still prove
Execute    
“perl6”.
$ prove -v --exec perl6;
$ prove -v -e perl6 t/Perl6.t;
$ prove -v -e /opt/bin/perl6;
Not quite zero:
t/Perl6.t .. Cannot convert string to number:
base-10 number must begin with valid digits or
'.' in 'âasdf' (indicated by â)
in block <unit> at t/Perl6.t line 7
Actually thrown at:
in block <unit> at t/Perl6.t line 7
Lesson 1: Typing matters in Perl6
is()    
handles 
strings, 
types.
use v6;
use Test;
my $x = '0';
my $y = 'asdf';
is $x, $y, "$x eq $y";
done-testing;
Lesson 1: Typing matters in Perl6
Nice 
messages. 
t/Perl6.t ..
not ok 1 - 0 == asdf
# Failed test '0 eq asdf'
# at t/Perl6.t line 7
# expected: 'asdf'
# got: '0'
1..1
# Looks like you failed 1 test
of 1
Dubious, test returned 1 (wstat
256, 0x100)
Failed 1/1 subtests
Comparing types
WHAT 
returns a 
type.
use v6;
use Test;
my $x = 0;
is $x.WHAT, Int, "$x is Int";
done-testing;
Comparing types
WHAT 
returns a 
type.
Int is an 
object, not a 
string.
use v6;
use Test;
my $x = 0;
is $x.WHAT, Int, "$x is Int";
done-testing;
Comparing types
WHAT 
returns a 
type.
Int is an 
object, not a 
string.
use v6;
use Test;
my $x = 0;
is $x.WHAT, Int, "$x is Int";
done-testing;
Comparing types
WHAT 
returns          
 a type.
$ prove -v -e perl6 t/Perl6.t
t/Perl6.t ..
ok 1 - 0 is Int
1..1
ok
All tests successful.
Comparing objects
WHICH 
identifies an 
object.
use v6;
use Test;
my $x = 0;
is $x.WHAT, Int, "$x is Int";
note '$x is ' ~ $x.WHICH;
done-testing;
Comparing objects
No '#' 
before 
notes.
$ prove -v -e perl6 t/Perl6.t
t/Perl6.t ..
ok 1 - 0 is Int
1..1
$x is Int|0
ok
REPL
Worth using to view results, contents.
$ perl6
To exit type 'exit' or '^D'
You may want to `panda install Readline` or
`panda install Linenoise` or use rlwrap for a
line editor
Aside: Using the bear
Fairly simple.
Annoying side effect: ~/.perl6/*
$ panda install Readline;
Viewing contents
> %a = ( 'a' .. 'e' );
Odd number of elements found where hash
initializer expected in block <unit> at
<unknown file> line 1
> %a.gist;
{a => b, c => d} # human-readable, no 'e'!
> %a.perl;
{:a("b"), :c("d")} # round-trip form
> dd %a;
Hash %a = {:a("b"), :c("d")}
Testing Manually
Nil is a
Good Thing.
> use Test;
Nil
Assigning objects: new copy
Identical 
contents 
match as 
strings & 
numbers.
+> my %a = ( 'a' .. 'd' );
{a => b, c => d}
+> my %b = %a;
{a => b, c => d}
+> ok %a == %b;
ok 1 -
+> ok %a eq %b;
ok 2 -
+> is %a, %b;
ok 3 -
Assigning objects: new copy
They are 
different 
objects.
“===” is  
identity 
comparison
+> ok %a === %b;
not ok 4 -
# Failed test at <unknown
file> line 1
+> %a.WHICH, %b.WHICH;
(Hash|88201392 Hash|88204032)
Two types of tests
“Value” and “Non­value” types.
Values are compared by contents.
Non­values use WHICH.
Value comparison
Compare the contents:
   my $a = 42;
   my $b = 42;
  # compares as 42 == 42
  $a === $b
Non­value comparison
my %a = ( 'a' .. 'e' );
my @b = ( 'a' .. 'e' );
# compare %a.WHICH eq @b.WHICH.
%a === @b
Hashes don't flatten
my %a = ( 'a' .. 'e' );
my @b = %a;
my @c = ( 'a' .. 'e' );
+> dd %a, @b, @c
Hash %a = {:a("b"), :c("d")}
Array @b = [:a("b"), :c("d")]
Array @c = ["a", "b", "c", "d", “e”]
Hashes don't flatten
my %a = ( 'a' .. 'e' );
my @b = %a;
my @c = ( 'a' .. 'e' );
+> dd %a, @b, @c
Hash %a = {:a("b"), :c("d")}
Array @b = [:a("b"), :c("d")]
Array @c = ["a", "b", "c", "d", “e”]
Constant objects 
Some things like “Bag” are immutable.
These will share a WHICH value.
True with '===' (identity)
False with '=:=' (object id)
Bags are immutable
> my @a = ( 'a', 'b', 'b', 'c', 'c', 'c' );
[a b b c c c]
> my $b = @a.Bag;
bag(a, c(3), b(2))
> my $c = @a.Bag;
bag(a, c(3), b(2))
They have a common WHICH
> @a.WHICH;
Array|162386224
> $b.WHICH;
Bag|Str|a(1) Str|b(2) Str|c(3)
> $c.WHICH;
Bag|Str|a(1) Str|b(2) Str|c(3)
Equal identity, different address
> $b === $c # matching contents
True
> $b =:= $c # different objects
False
Have it your way
“eqv” used to compare objects.
This is an operator:
multi infix: <eqv> ( Foo $x, Bar $y )
Classes can supply their own.
Tests can override them. 
Multi­methods allow various comparisions
Compare to an Int:
multi infix: <eqv>
( MyClass $a, Int $b ) { ... }
Compare undefined value:
multi infix: <eqv>
(MyClass:U $a, Mu $b)
{ fail “Undefined MyClass Object” }
cmp­ok tests eqv implementation 
Is­deeply uses its own eqv.
cmp­ok uses yours:
cmp-ok $found, 'eqv', $expect;
cmp-ok $found, 'oneshot', $expect;
eqv can test whatever it wants to.
Similar control as Test2's DSL.
Compare only some of the keys...
Limit range for any values.
Multi­method simplifies tests.
is­approx
Absolute, relative tolerance to expect.
Uses eqv, requires same types.
Really nice for geo­coding, physical data:
my $abs-tol = 0.0005;
is-approx $lat, $exp, :$abs-tol;
Summary
Mostly the same: Test, ok(), is().
Testing objects requires more care:
  identity vs. address.
  value vs. WHAT.
Test module is readable.
See also
Liz deserves a hug for making this work...

Getting Testy With Perl6