测试
测试代码是软件开发不可或缺的一部分。测试提供代码行为的自动,可重复的验证,并确保您的代码按预期工作。
在 Raku 中,Test 模块提供了一个测试框架,也被 Raku 的官方 spectest 套件使用。
测试函数发出符合 Test Anything Protocol 的输出。通常,它们用于 sink 上下文中:
ok check-name($meta, :$relaxed-name), "name has a hyphen rather than '::'"
但是不论测试成功与否,所有函数都会返回布尔值,如果测试失败,可以使用它来打印消息:
ok check-name($meta, :$relaxed-name), "name has a hyphen rather than '::'" \
or diag "\nTo use hyphen in name, pass :relaxed-name to meta-ok\n";
写测试
与任何 Perl 项目一样,测试位于项目基本目录的 t
目录下。
典型的测试文件看起来像这样:
use v6.c;
use Test; # a Standard module included with Rakudo
use lib 'lib';
plan $num-tests;
#.... tests
done-testing; # optional with 'plan'
我们确保通过 use v6.c
编译指令使用 Raku,然后加载 Test
模块并指定库的位置。然后我们指定我们*计划*运行多少个测试(这样测试框架可以告诉我们运行的测试是否比我们预期的要多),并且在完成测试后,我们使用*完成测试*来告诉框架我们已经完成。
线程安全
请注意,Test
模块中的例程*不是*线程安全的。这意味着您不应该同时尝试在多个线程中使用测试例程,因为 TAP 输出可能会出现乱序并且会使解释它的程序迷惑。
目前没有计划使其线程安全。如果线程测试对您至关重要,您可能会发现一些合适的生态系统模块,代替 Test
来满足您的测试需求。
运行测试
可以通过在命令行上指定测试文件名来单独运行测试:
$ raku t/test-filename.t
或者通过 Perl 5 中的 prove 命令,其中 --exec
用于指定运行测试的可执行文件:
$ prove --exec raku -r t
要在第一次失败时中止测试套件,请设置 PERL6_TEST_DIE_ON_FAIL
环境变量:
$ PERL6_TEST_DIE_ON_FAIL=1 raku t/test-filename.t
可以在测试文件中使用相同的变量。在加载 Test
模块之前设置它:
BEGIN %*ENV<PERL6_TEST_DIE_ON_FAIL> = 1;
use Test;
...
测试计划
测试计划用 plan 声明将要完成的计划数量,或者可能会跳过的计划数量。如果没有声明计划,done-testing 则用于声明测试结束。
测试返回值
Test
模块导出各种函数,用于检查给定表达式的返回值并生成标准化测试输出。
在实践中,表达式通常是对要进行单元测试的函数或方法的调用。ok 和 nok 将匹配 True
和 False
。但是,在可能的情况下,最好使用下面的一个专门的比较测试函数,因为它们可以在比较失败时打印更有用的诊断输出。
通过字符串比较
is 和 nok 使用适当的运算符测试相等性,具体取决于它所处理的对象(或类)。
通过近似数字比较
is-approx 比较具有一定精度的数字,可以是绝对的或相对的。它对于精度取决于内部表示的数值非常有用。
通过结构比较
也可以使用 is-deeply 比较结构,这将检查所比较的对象的内部结构是否相同。
任意比较
您可以使用 cmp-ok 进行任何类型的比较,它将您想要用于比较的函数或运算符作为参数。
通过对象类型比较
isa-ok 测试对象是否属于某种类型。
通过方法名比较
can-ok 用于对象以检查它们是否具有该特定方法。
通过角色比较
- does-ok($variable, $role, $description?)
通过正则表达式比较
like 和 unlike 使用正则表达式检查; 在第一种情况下,如果存在匹配则通过,在第二种情况下则不通过。
测试模块
用 use-ok 实验性地加载模块,如果加载失败则会失败。
测试异常
dies-ok 和 lives-ok 是相反的测试代码的方法; 第一个检查是它抛出异常,第二个检查它不抛出异常; throws-like 检查代码是否抛出了作为参数传递的特定异常; fails-like 同样,检查代码是否返回特定类型的 Failure。eval-dies-ok 和 eval-lives-ok 在测试之前计算的字符串上工作类似。
Grouping tests
只有在所有子测试都是 ok
的时候, 这组子测试的结果才是 ok
的; 他们按使用 subtest 分组。
跳过测试
有时测试还没准备好运行,例如某个功能可能尚未实现,在这种情况下,测试可以标记为 todo。或者可能是某个特定功能仅适用于特定平台的情况 - 在这种情况下,可以在其他平台上 skip 这个测试; skip-rest 将跳过剩余的测试,而不是跳过作为参数给出的特定数字的测试; bail-out 将简单地带着一条消息退出测试。
手动控制
如果上面记录的便利功能不符合您的需要,您可以使用以下函数手动指导测试套输出; pass 将打印测试已经通过,diag 将打印(可能)信息性消息。