【问题标题】:Why do I need to know how many tests I will be running with Test::More?为什么我需要知道我将使用 Test::More 运行多少测试?
【发布时间】:2009-03-27 15:59:25
【问题描述】:

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

测试::More POD

首先,您需要一个测试计划。这基本上声明了您的脚本将运行多少测试以防止过早失败...

use Test::More tests => 23;

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

use Test::More qw(no_plan);

但是,如果在测试运行结束时未打印任何结果,则很容易看到过早的故障。它似乎没有那么有帮助。

所以我有 3 个问题:

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

【问题讨论】:

    标签: perl unit-testing testing


    【解决方案1】:

    默认需要测试计划的原因是什么?

    ysth 的 answer 链接到本期的精彩 discussion,其中包括 Michael Schwern 和 Ovid 的 cmets,他们分别是 Test::MoreTest::Most 维护者。显然,这在perl-qa 列表中每隔一段时间就会出现一次,这是一个有争议的问题。以下是重点:

    不使用测试计划的原因

    1. 这很烦人并且需要时间。
    2. 这不值得花时间,因为测试脚本不会在没有测试工具注意到的情况下死掉,除非在极少数情况下。
    3. Test::More 可以在测试发生时对测试进行计数
    4. 如果您使用测试计划并需要跳过测试,那么您需要一个SKIP{} 块的额外痛苦。

    使用测试计划的原因

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

    另一种选择

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

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

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

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

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

    有些人提到这个功能对他们来说确实有用。这包括拉里沃尔。 Michael Schwern says 该功能源于 20 多年前的 Larry。

    其他语言有这个功能吗?

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

    【讨论】:

    • 我喜欢你的总结——非常简洁而全面。我可以将它添加到perl-qa.hexten.net/wiki/index.php/Plan 吗?当然,除非你想自己做 :-)。
    • 此外,您不知道要运行多少测试。 foreach (@found_thing) { ok( ... ) },这不(也不应该)常见,但我已经发生了。 github.com/jberger/Alien-GSL/blob/master/t/locations.t
    • 在这种情况下,我喜欢使用Test::More::plan 并在初始化完成后声明计划计数,我知道计数是多少。
    【解决方案2】:

    我不确定您真正要问的是什么,因为文档摘录似乎回答了这个问题。我想知道我的所有测试是否都运行了。但是,直到测试套件稳定下来,我才发现这很有用。

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

    一些人提到了测试数量可能会有所不同的情况。我弄清楚了测试但是我需要计算数字然后在计划中使用它。拥有针对特定功能的小型测试文件也很有帮助,因此测试的数量很少。

    使用 vars qw( $tests ); 开始 { $测试 = ...; # 想办法 使用 Test::More 测试 => $tests; }

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

    使用测试::更多; 计划测试 => $tests;

    最新的 TAP 让您也可以将计划放在最后。

    【讨论】:

    • 谢谢布赖恩。我喜欢你在套件稳定之前使用 no_plan 的建议。
    【解决方案3】:

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

    您可能想查看 Test::Most 的延期计划选项,该选项即将出现在 Test::More 中(如果还没有的话)。

    最近在 perl-qa 列表上也对此进行了讨论。一个线程:http://www.nntp.perl.org/group/perl.qa/2009/03/msg12121.html

    【讨论】:

    • 谢谢。回答了我的问题。
    【解决方案4】:

    进行任何测试都比不进行测试要好,但测试是要经过深思熟虑的。说明预期的测试数量使您能够查看测试脚本中是否存在阻止测试执行(或执行太多次)的错误。如果您不在特定条件下运行测试,您可以使用 skip 函数来声明:

      SKIP: {
          skip $why, $how_many if $condition;
    
          ...normal testing code goes here...
      }
    

    【讨论】:

    • 感谢您的回答。你很有说服力……这只是我从来没有遇到过的问题——这张支票从来没有救过我。我的大部分代码都使用小类,所以我的测试脚本很简单(大约 15 个测试)。也许我只是没有尽可能多地测试......但那是另一个问题。
    【解决方案5】:

    我认为当制定计划的人力成本太高时,可以改变规则并使用 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;
    

    如果您不指定计划,很容易错过测试失败以及某些断言未按预期运行的情况。

    【讨论】:

    • 我通常只有 7 个测试,所以它并不那么难。只是烦人。你的例子很有趣。这似乎仍然是一个不常见的情况。我认为默认应该是跳过计划。那么我认为计划是一个很酷的功能。这是不合理的意见吗?
    【解决方案6】:

    在计划中明确列出测试的数量是个好主意,除非检索该数量的成本太高。这个问题已经得到了正确的回答,但我想强调两点:

    • 比 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】:

      我也觉得这很烦人,而且我通常在一开始就忽略这个数字,直到测试套件稳定下来。然后我只是手动更新它。我确实喜欢知道随着时间的推移有多少总测试,作为一种进度指示器。

      为了让计数更容易,我在每次测试之前都添加了以下内容:

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

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

      【讨论】:

        【解决方案8】:

        在进行 TDD 时会很痛苦,因为您是在投机取巧地编写新测试。当我教 TDD 并且商店使用 Perl 时,我们决定以无计划的方式使用我们的测试套件。我想我们本可以从 no_plan 更改为锁定测试数量。当时我认为它是障碍多于帮助。

        【讨论】:

          【解决方案9】:

          埃里克约翰逊的回答完全正确。我只是想补充一点,done_testingno_plan 的更好替代品,最近在Test-Simple 0.87_1 中发布。这是一个实验版本,但您可以直接从上一个链接下载。

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-12-24
            • 1970-01-01
            • 1970-01-01
            • 2012-05-14
            • 2013-06-13
            • 2023-03-30
            • 1970-01-01
            相关资源
            最近更新 更多