Getting Testy With Perl6

42
Getting Testy with Perl6: Things you wish you'd known. Steven Lembark Workhorse Computing [email protected]

Transcript of Getting Testy With Perl6

Page 1: Getting Testy With Perl6

Getting Testy with Perl6:Things you wish you'd known.

Steven LembarkWorkhorse [email protected]

Page 2: Getting Testy With Perl6

Helpful items

$ panda install p6doc;

http://doc.perl6.org/

# doc for testing:

/language/testing

Page 3: Getting Testy With Perl6

Helpful items

$ panda install p6doc;

http://doc.perl6.org/

# doc for testing:

/language/testing

Page 4: Getting Testy With Perl6

Core module

Core modules are documented in:./share/perl6/doc/Language/*

Which includes "testing.pod".

Page 5: Getting Testy With Perl6

Viewing source

To see the source of a module:

panda look <module name>;

This will fetch the module (even if it is installed).

Page 6: Getting Testy With Perl6

Basic of Perl6 Testing

Pretty much what you are used to:

  “Test” module for testing.

  ok(), is() & friends.

Main differences are in Perl6 itself.

Page 7: Getting Testy With Perl6

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;

Page 8: Getting Testy With Perl6

What you are used to

Zero            equals         zero.

$ prove -v Perl5.t;Perl5 ..ok 1 - 0 == asdf1..1okAll tests successful.Files=1, Tests=1, ...Result: PASS

Page 9: Getting Testy With Perl6

Doing it in Perl6

Module is “Test”

use v6;use Test;

my $x = '0';my $y = 'asdf';

ok $x == $y, "$x == $y";

done-testing;

Page 10: Getting Testy With Perl6

Doing it in Perl6

Notice        the dash!

use v6;use Test;

my $x = '0';my $y = 'asdf';

ok $x == $y, "$x == $y";

done-testing;

Page 11: Getting Testy With Perl6

Prove is still proveExecute    “perl6”.

$ prove -v --exec perl6;

$ prove -v -e perl6 t/Perl6.t;

$ prove -v -e /opt/bin/perl6;

Page 12: Getting Testy With 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

Page 13: Getting Testy With Perl6

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;

Page 14: Getting Testy With Perl6

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 1Dubious, test returned 1 (wstat 256, 0x100)Failed 1/1 subtests

Page 15: Getting Testy With Perl6

Comparing types

WHAT returns a type.

use v6;use Test;

my $x = 0;

is $x.WHAT, Int, "$x is Int";

done-testing;

Page 16: Getting Testy With Perl6

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;

Page 17: Getting Testy With Perl6

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;

Page 18: Getting Testy With Perl6

Comparing types

WHAT returns           a type.

$ prove -v -e perl6 t/Perl6.tt/Perl6.t ..ok 1 - 0 is Int1..1okAll tests successful.

Page 19: Getting Testy With Perl6

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;

Page 20: Getting Testy With Perl6

Comparing objects

No '#' before notes.

$ prove -v -e perl6 t/Perl6.tt/Perl6.t ..ok 1 - 0 is Int1..1$x is Int|0ok

Page 21: Getting Testy With Perl6

REPL

Worth using to view results, contents.

$ perl6To exit type 'exit' or '^D'You may want to `panda install Readline` or `panda install Linenoise` or use rlwrap for a line editor

Page 22: Getting Testy With Perl6

Aside: Using the bear

Fairly simple.

Annoying side effect: ~/.perl6/*

$ panda install Readline;

Page 23: Getting Testy With Perl6

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")}

Page 24: Getting Testy With Perl6

Testing Manually

Nil is a

Good Thing.

> use Test;Nil

Page 25: Getting Testy With Perl6

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 -

Page 26: Getting Testy With Perl6

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)

Page 27: Getting Testy With Perl6

Two types of tests

“Value” and “Non­value” types.

Values are compared by contents.

Non­values use WHICH.

Page 28: Getting Testy With Perl6

Value comparison

Compare the contents:

   my $a = 42;

   my $b = 42;

  # compares as 42 == 42

  $a === $b

Page 29: Getting Testy With Perl6

Non­value comparison

my %a = ( 'a' .. 'e' );

my @b = ( 'a' .. 'e' );

# compare %a.WHICH eq @b.WHICH.

%a === @b

Page 30: Getting Testy With Perl6

Hashes don't flattenmy %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”]

Page 31: Getting Testy With Perl6

Hashes don't flattenmy %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”]

Page 32: Getting Testy With Perl6

Constant objects 

Some things like “Bag” are immutable.

These will share a WHICH value.

True with '===' (identity)

False with '=:=' (object id)

Page 33: Getting Testy With Perl6

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))

Page 34: Getting Testy With Perl6

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)

Page 35: Getting Testy With Perl6

Equal identity, different address

> $b === $c # matching contentsTrue

> $b =:= $c # different objectsFalse

Page 36: Getting Testy With Perl6

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. 

Page 37: Getting Testy With Perl6

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” }

Page 38: Getting Testy With Perl6

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;

Page 39: Getting Testy With Perl6

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.

Page 40: Getting Testy With Perl6

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;

Page 41: Getting Testy With Perl6

Summary

Mostly the same: Test, ok(), is().

Testing objects requires more care:

  identity vs. address.

  value vs. WHAT.

Test module is readable.

Page 42: Getting Testy With Perl6

See also

Liz deserves a hug for making this work...