如何在Test :: More中避免“你试图计划两次”

时间:2014-02-07 11:32:17

标签: perl unit-testing tdd

我是单位测试的新手。 我假装加载内部使用Test :: More的N个类,用自己的封装进行不同的测试。

但是我接受了这个错误:“你试图在Tests / Bar.pm第9行计划两次。”

这种“多个测试”的方法是正确的,我的意思是它是在perl中进行单元测试的标准方法吗?如何使用Test :: More?

获得此级别的封装

感谢您的建议!

main.pl:

use strict;
use warnings;
use utf8;


use Tests::Foo;
use Tests::Bar;

my $ret1 = Tests::Foo->run();
my $ret2 = Tests::Bar->run();

测试:: Foo:

package Tests::Foo;
use strict;
use warnings;


sub run
{
    my $ret;
    use Test::More qw(no_plan);
    my $test = Test::More->builder;
    is(1,1,'correct()');
    is(1,2,'fails()');
    return $test;#return all test object
}
1;

测试::酒吧

package Tests::Bar;
use strict;
use warnings;


sub run
{
    my $ret;
    use Test::More qw(no_plan);
    my $test = Test::More->builder;
    is(2,1,'fail()');
    is(2,2,'correct()');
    return $test;#return all test object
}
1;

1 个答案:

答案 0 :(得分:9)

Test::More模块围绕TAP格式(Test Anything Protocol)构建。测试输出的第一行可以包含一行声明测试次数:1..12。这对于输出成功或失败测试部分的工具非常有用:3/12 tests failed。但是,此行是可选的,您不能使用任何计划。在这种情况下,说出你done_testing的时候是有道理的:

use Test::More;

is 1, "1", "stringification";

done_testing;

请注意,use Test::More 'no_plan'被Test :: More视为一个计划,尽管它没有在TAP输出中声明任何内容。

您应该在每个流程中仅声明一个计划(或声明您已完成)。这不是问题,因为通常测试是这样的:

  1. 在项目目录中,文件夹lib/和模块t/Foo::Bar。这是./ lib/ Foo/ Bar.pm Bar/ Helper.pm t/ 00_first_test.t 01_second_test.t 模块的示例:

    #!/usr/bin/env perl
    use strict;
    use warnings;
    use Test::More tests => 1;
    
    # some test here
    BEGIN {
      use_ok 'Foo::Bar';
    }
    
  2. 测试如下:

    prove

    也就是说,它最好有一个shebang并声明测试次数。包名称不是必需的。

  3. 使用Perl附带的$ prove -lr t/ 工具运行测试。在目录中:

    -l

    lib包含-r目录, use Test::More tests => 2; ok some_test; subtest "Nice Name" => sub { plan tests => 1; ok other_test; }; 也会查看子文件夹。然后,您可以指定包含测试的测试或目录列表。目录中的测试通常按字母顺序处理,但有一些选项可以激起它。

    这将为每个测试执行单独的过程。这是强大的,易于实现和并行化,虽然不是非常高效。这意味着每个测试都负责创建它自己的夹具。

  4. 因此无需从中央测试脚本或makefile调用测试。

    如果要在同一个TAP会话中执行多个测试,可以使用子测试:

    plan

    在子测试中,计划使用use Test::More函数声明,使用package Tests::Something; use Test::More; sub run { my $self = shift; plan tests => 2; ok some_test; ok other_test; } (在编译时执行子测试之前执行)!您可以将测试对象构造为子测试执行:

    subtest "Tests::Something" => sub {
      Tests::Something->new->run;
    }
    

    然后:

    {{1}}