在单个测试中断言多个条件,还是分成多个测试?

时间:2009-04-17 21:02:13

标签: php unit-testing testing correctness

如果您正在测试类似下面的计数函数,那么在一个函数中为函数测试多个东西而不是为每个测试都测试函数会被认为是“正确”还是“错误”?

function testGetKeywordCount() {
    $tester = $this -> getDatabaseTester($this -> CompleteDataFile);
    $tester -> onSetUp();

    $KeywordID = 0;
    $this -> setExpectedException('InvalidArgumentException');
    $this -> keyword -> getKeywordCount($KeywordID,'Active');

    $KeywordID = 1;
    $this -> setExpectedException('InvalidArgumentException');
    $this -> keyword -> getKeywordCount($KeywordID,'InvalidStatus');

    $this -> assertEquals(1, $this -> keyword -> getKeywordCount($KeywordID,'Active'));

    $tester -> onTearDown();
}

6 个答案:

答案 0 :(得分:4)

你应该有多个测试函数,每个函数都测试自己的条件。这样就可以更容易地在没有调试的情况下发现故障。

答案 1 :(得分:4)

每种方案都有一个测试用例是理想的。但是,在某些情况下,在一个测试用例中测试多个场景更方便(从实现工作的角度来看很有效)。如果您使用的框架在第一次失败时不会停止,但尝试在测试用例中尽可能多地执行,那么该框架适用于每个测试用例的多个场景。

我更喜欢在单元测试上花费尽可能少的时间,并且在那段时间内尽可能获得尽可能多的覆盖率。

最后,重要的是你实现单元测试的方式,更重要的是这些测试的正确性。

答案 2 :(得分:1)

测试框架并不总是值得您按照每个测试规则遵循一个断言。

对Ruby来说就是RSpec,它允许你设置nested example groups。例如:

  • 用户
    • 没有密码
      • 无效
      • 抛出异常
    • 用密码
      • 以前使用过的
        • 无效
        • 抛出异常
        • 旅行安全警告
      • 之前没有用过的
        • 有效
        • 重定向到帐户页面

通过逐步构建场景并测试每个步骤,每个测试方法更容易坚持一个断言。它还可以更容易地发现未经测试的场景。

答案 3 :(得分:1)

将断言拆分为两个单独的测试的一个论点是,如果其中一个断言失败,则会导致一个失败;如果两个断言都失败了,你将会遇到两次失败。

此外,通过使每个测试的名称尽可能具有建议性,当出现问题时,您将获得额外的线索。

答案 4 :(得分:0)

我不会在上面的示例代码中讨论单元测试 您的示例更像是一个自动化功能测试,用于测试功能流。

BUT 在这种情况下,可以有多个断言。

确保2个断言不会落后于另一个断言。

错误的例子

public void ValidateRulesEntry_Valid_ValidConditionsFromFile()
{
    string condition = "Target.HasValue";
    string returnMessage;

    bool successFul = CodeParserTryParseCondition(condition, out returnMessage);


    Assert.IsTrue(successFul);
    Assert.IsFalse(string.IsNullOrEmpty(returnMessage));
    Assert.IsTrue(returnMessage == "OK");

}  

最后两个断言依赖于第一个断言IsTrue(successFul)。

想想:如果该测试失败 - >告诉我原因(不看调试输出)

答案 5 :(得分:0)

根据您的要求,这是一个不同答案的问题,主要取决于他/她的个人观点或专业经验。一些超理论的人会告诉你,在考试中拥有一个以上的断言是至高无上的罪,你将永远注定失败。但是具有更多现实世界经验的其他人可能会告诉您,在每次测试中有10个甚至50个断言是完全正常的情况。

那么,谁是对的?

在面对这种困境时,我总是尽量做到客观,并且做出选择我决定用经过认证和经验丰富的专业人士今天开发的一些最受欢迎的github回购进行一项小型研究。

那么,大玩家如何测试他们自己的项目?更重要的是,单元测试框架如何自行进行单元测试?

让我们看几个例子:

休眠

https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/test/java/org/hibernate/engine/spi/EntityEntryTest.java https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/test/java/org/hibernate/engine/spi/NonSortedExecutableListTest.java https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/test/java/org/hibernate/engine/spi/SortedExecutableListTest.java https://github.com/hibernate/hibernate-orm/blob/master/hibernate-envers/src/test/java/org/hibernate/envers/test/JpaStaticMetamodelTest.java https://github.com/hibernate/hibernate-orm/blob/master/hibernate-hikaricp/src/test/java/org/hibernate/test/hikaricp/HikariCPConnectionProviderTest.java https://github.com/hibernate/hibernate-orm/blob/master/hibernate-proxool/src/test/java/org/hibernate/test/proxool/ProxoolConnectionProviderTest.java

弹簧

https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/test/java/org/springframework/util/AutoPopulatingListTests.java

junit 4

https://github.com/junit-team/junit4/blob/master/src/test/java/junit/tests/extensions/ActiveTestTest.java https://github.com/junit-team/junit4/blob/master/src/test/java/junit/tests/extensions/RepeatedTestTest.java https://github.com/junit-team/junit4/blob/master/src/test/java/junit/tests/runner/ResultTest.java https://github.com/junit-team/junit4/blob/master/src/test/java/org/junit/rules/TimeoutRuleTest.java

junit 5

https://github.com/junit-team/junit5/blob/master/platform-tests/src/test/java/org/junit/platform/launcher/core/DefaultLauncherTests.java https://github.com/junit-team/junit5/blob/master/platform-tests/src/test/java/org/junit/platform/launcher/core/LauncherDiscoveryRequestBuilderTests.java https://github.com/junit-team/junit5/blob/master/platform-tests/src/test/java/org/junit/platform/launcher/listener/SummaryGenerationTests.java https://github.com/junit-team/junit5/blob/master/junit-jupiter-engine/src/test/java/org/junit/jupiter/engine/StandardTestClassTests.java https://github.com/junit-team/junit5/blob/master/junit-jupiter-engine/src/test/java/org/junit/jupiter/engine/DiscoveryFilterApplierTests.java

Google Truth

https://github.com/google/truth/blob/master/core/src/test/java/com/google/common/truth/DoubleSubjectTest.java https://github.com/google/truth/blob/master/core/src/test/java/com/google/common/truth/BigDecimalSubjectTest.java https://github.com/google/truth/blob/master/core/src/test/java/com/google/common/truth/DoubleSubjectTest.java

正如我们在上面的例子中所看到的,专业开发人员似乎并不关心单个断言命令。事实上,他们大部分时间都违反了这个规则,看起来他们完全没问题。也许他们会忽略它,因为这不是一个严格的规则,而只是一个建议。 值得一提的是,即使是单元测试框架也会在大多数情况下对每个测试使用多个断言进行自我测试。

所以我的结论很清楚:关于这个问题,在一次测试中拥有尽可能多的断言是完全有效的。如果专业开发人员正在这样做,你也可以这样做。