A few months ago Larry proposed to add some testing facilites to the language itself, because we want to culturally encourage testing, and because the test suite defines the language, so we need to specify the behaviour of our testing facilities anyway.
We also discussed some possible changes to the current testing syntax, please read the IRC discussion starting from here: http://irclog.perlgeek.de/perl6/2008-10-09#i_613827 There are some problems with the current approach, especially if we make it built-in: * the word 'is' is overloaded in Perl 6, it is used for traits (class A is rw { ... }), implementation types (my @a is TiedArray) and inheritance (class A { is B; ... }). Especially the the last one can appear in the same position as an is() test, and means something completely different * if we export subs is() and ok(), we clutter the namespace with subs with short names - not very nice * is() is rather imprecise; it doesn't say *how* things are compared. Currently two options seem to be open for the comparison semantics: either string based, or deep structural equality (with infix:<eqv>). Both are very problematic: The stringification of some structures can be implementation specific (for example for Ranges), and it often looses lot of information. Also pugs used to stringify hashes in insertion order, but that's not forced by the spec, so many tests relied on that behaviour, ie they were wrong. Comparison by infix:<eqv> is dangerous, because it is very strict, and things that were identical in the early stages of the compiler become distinct later on. Consider 'sub f { return 1, 2, 3}; say f() eqv (1, 2, 3)'. Pugs says this is true, because it doesn't implement return() as returning a capture (or in turn thinks that lists are eqv to captures), and testers would rely on this. Future versions of a compiler would contradict the previous results, and thus put an additional burden on the test suite maintainers (ie mostly me). There are other subtle distinctions (like between List and Array) that make it hard to write tests with infix:<eqv> correctly. So we want to get rid if the is() test function. The current workaround is to use ok() and an explicit comparison operator like this: ok $x == 1e5, 'with explicit numeric comparison'; However this just tells us if a test fails, not how it fails - it would be nice to have something like Test::More's output "Expected 1e5, got 1e4". The only way that ok() could produce such diagnostics would be to declare it a macro that peeks into the AST of its first argument and tries to find the two values. But that's very advanced magic, and might not even be possible in a DWIMmy way in the general case. So Larry and Patrick developed the idea of creating an adverb on the test operator instead: $x == 1e5 :ok('the :ok makes this is a test'); This is an adverb on the infix:<==> operator, and might desugar to something like this: multi sub infix:<==>($left, $right, :$ok) { $*TEST_BACKEND.proclaim($left == $right, $ok) or $*TEST_BACKEND.diag( "Got: «$left.perl()»; Expected: «$right.perl»"); } (Daniel Ruoso also proposed to call the adverb :test instead of :ok, making it easier to read but a bit longer; my happiness doesn't depend on the exact name, but of course we can discuss it once we have settled on this scheme, if we do so). So every operator that returns a boolean would get a multi with the named argument :ok, which could be autogenerated for most operators, but hand-written for others that need more verbose diagnostics (for example the smart match operator could tell you which of its hundred possible comparisons it used). That's not just limited to infix operators, ok($x, '$x is true') could be written as ?$x :ok('$x is true'), where the :ok is an adverb on prefix:<?>; This approach gives us * good and easy diagnostics * exactness by forcing the explicit choice of comparison semantics * nice integration into the Perl 6 syntax * no cluttering of the namespace with short subs However nothing in life is free, we pay for it with a few disadvantages: * We nearly double the number of built-in operators by adding an :ok multi * We force implementors to handle operator adverbs and named arguments very early in their progress (don't know how easy or hard that is) * Testing of operators becomes somewhat clumsy. If you * want to test infix:<==>, you won't write '2 == 2 :ok("== works")', because you test a different multi there. Instead you'd have to write something like '?(2 == 2) :ok("== works")', where :ok is an adverb on prefix:<?>. So I'd like to hear your opinions: do you think adverb-based testing is a good idea? If you don't like it, do you see any other good way to tackle the problems I mentioned above? I'll send another mail on the subject of pluggable testing backends in order to allow different emitters (TAP output, storage into databases, whatever) Cheers, Moritz