为什么我需要知道我将使用Test :: More运行多少次测试?

时间:2009-03-27 15:59:26

标签: perl unit-testing testing

如果我使用use Test::More qw(no_plan),我是个坏人吗?

测试::更多POD

  

在其他任何事情之前,您需要一个测试计划。这基本上声明了您的脚本将运行多少次测试以防止过早失败......

     

use Test::More tests => 23;

     

在极少数情况下,您事先不知道脚本将运行多少测试。在这种情况下,您可以声明您没有计划。 (尽量避免使用它,因为它会削弱您的测试。)

     

use Test::More qw(no_plan);

但是,如果在测试运行结束时没有打印结果,则可以很容易地看到过早失效。它似乎没有帮助。

所以我有3个问题:

  1. 默认情况下要求测试计划背后的原因是什么?
  2. 从长远来看,有没有人发现这是一个有用且节省时间的功能?
  3. 其他语言的其他测试套件是否支持此类事情?

9 个答案:

答案 0 :(得分:32)

默认情况下要求测试计划的原因是什么?

ysth的answer链接到此问题的一个很好的discussion,其中包括分别是Test::MoreTest::Most维护者的Michael Schwern和Ovid的评论。显然,这会偶尔在perl-qa列表中出现,这是一个有争议的问题。以下是重点:

不使用测试计划的原因

  1. 很讨厌,需要时间。
  2. 它不值得花时间,因为测试脚本不会在没有测试线束注意的情况下死亡,除非在极少数情况下。
  3. Test::More可以在测试发生时对其进行计数
  4. 如果您使用测试计划并且需要跳过测试,那么您还需要SKIP{}阻止。
  5. 使用测试计划的原因

    1. 只需几秒钟即可完成。如果需要更长时间,那么您的测试逻辑就太复杂了。
    2. 如果代码中有某个出口(0),则测试将成功完成,而不会运行其余的测试用例。细心观察的人可能会注意到屏幕输出看起来不正确,但在自动测试套件中,它可能会被忽视。
    3. 开发人员可能会意外地编写测试逻辑,以便某些测试永远不会运行。
    4. 如果不提前知道要运行多少次测试,就无法拥有进度条。仅通过内省就可以difficult
    5. 替代

      Test::SimpleTest::MoreTest::Most都有一个done_testing()方法,应该在测试脚本的末尾调用。这是我目前采用的方法。

      这解决了代码中包含exit(0)的问题。它并没有解决无意中跳过测试的逻辑问题。

      简而言之,使用计划更安全,但除非您的测试套件复杂(并且它们不应该复杂),否则实际节省一天的机会很低。

      所以使用done_testing()是一个中间立场。无论你喜欢什么,这可能都不是什么大不了的事。

      此功能对现​​实世界中的任何人都有用吗?

      有些人提到这个功能在真实的单词中对他们有用。这包括拉里沃尔。迈克尔施威恩says这个特征起源于20多年前的拉里。

      其他语言是否有此功能?

      xUnit类型测试套件都没有测试计划功能。我没有遇到任何其他编程语言中使用此功能的任何示例。

答案 1 :(得分:10)

我不确定你真正在问什么,因为文档摘录似乎回答了它。我想知道我的所有测试是否都运行了。但是,在测试套件稳定之前,我认为没有用。

在开发过程中,我使用no_plan因为我不断添加到测试套件中。随着事情的稳定,我会验证应该运行的测试数量并更新计划。有些人已经提到了“测试工具”,但没有“测试工具”这样的东西。默认情况下,大多数模块都使用这个模块,因为这是MakeMaker或Module :: Build指定的,但TAP输出独立于任何特定的TAP使用者。

有几个人提到了测试次数可能不同的情况。我找出了测试但是我需要计算数字,然后在计划中使用它。它还有助于拥有针对特定功能的小型测试文件,因此测试次数很少。

use vars qw( $tests );

BEGIN {
  $tests = ...; # figure it out

  use Test::More tests => $tests;
  }

您还可以将计数与加载分开:

use Test::More;

plan tests => $tests;

最新的TAP也允许您将计划放在最后。

答案 2 :(得分:7)

在一条评论中,您似乎认为过早退出将被视为失败,因为该计划最终不会输出,但事实并非如此 - 计划将会输出除非 你终止POSIX :: _退出或致命信号等。特别是,将导致die()和exit() 在计划中输出(尽管测试工具应该检测除了退出(0)以外的任何东西作为过早终止的测试)。

您可能希望查看Test :: Most的延迟计划选项,很快就会出现在Test :: More中(如果还没有)。

最近在perl-qa列表上也讨论过这个问题。一个帖子:http://www.nntp.perl.org/group/perl.qa/2009/03/msg12121.html

答案 3 :(得分:5)

进行任何测试都比不进行测试更好,但测试是关于故意的。说明预期的数量测试使您能够查看测试脚本中是否存在阻止测试执行(或执行太多次)的错误。如果您未在特定条件下运行测试,则可以使用skip函数声明:

  SKIP: {
      skip $why, $how_many if $condition;

      ...normal testing code goes here...
  }

答案 4 :(得分:3)

我认为,当计算出计划的人力成本太高时,可以弯曲规则并使用no_plan,但这个成本很好地表明测试套件设计得不好。

另一种情况是,明确定义test_plan是有用的,当你进行这种测试时:

$coderef = sub { my $arg = shift; isa_ok $arg, 'MyClass' };
do(@args, $coderef);

## hijack our interface to test it's called.
local *MyClass::do = $coderef;

如果您没有指定计划,很容易错过您的测试失败,并且某些断言没有按预期运行。

答案 5 :(得分:2)

我觉得它也很烦人,我通常会在开始时忽略这个数字,直到测试套件稳定下来。然后我只是手动保持它是最新的。我就像知道有多少总测试作为秒数一样,作为一种进度指示器。

为了使计数更容易,我在每次测试前加上以下内容:

#----- load non-existant record -----
....
#----- add a new record -----
....
#----- load the new record (by name) -----
....
#----- verify the name -----
etc.  

然后我可以快速扫描文件并轻松计算测试数,只需查找#-----行。我想我甚至可以在Emacs中写一些东西为我做这件事,但老实说,这并不是一件苦差事。

答案 6 :(得分:2)

明确计划中的测试次数是个好主意,除非检索此编号太昂贵。这个问题已经得到了适当的回答,但我想强调两点:

  • 优于no_plan使用done_testing()

    use Test::More;
    ... run your tests ...;
    done_testing( $number_of_tests_run );
    # or done_testing() if not number of test is known

  • 这个Matt Trout博客文章很有意思,并且有关于添加计划与cvs冲突以及其他导致计划有问题的问题:Why numeric test plans are bad, wrong, and don't actually help anyway

答案 7 :(得分:1)

做TDD时很痛苦,因为你正在机会性地写新测试。当我在教授TDD并且商店使用Perl时,我们决定使用我们的测试套件。我想我们可以从no_plan改为锁定测试次数。当时我认为它更多的是障碍而不是帮助。

答案 8 :(得分:1)

Eric Johnson的回答是完全正确的。我只是想补充一点done_testing,这是no_plan的更好替代品,最近在Test-Simple 0.87_1发布了。这是一个实验性版本,但您可以直接从上一个链接下载它。

done_testing允许您声明您认为在测试脚本结束时运行的测试数,而不是在脚本启动之前尝试猜测它。你可以read the documentation here