它应该是"Arrange-Assert-Act-Assert"吗?

Car*_*ter 92 language-agnostic unit-testing arrange-act-assert

关于Arrange-Act-Assert的经典测试模式,我经常发现自己在Act之前添加了一个反主张.这样我知道传递的断言实际上是作为动作的结果传递的.

我认为它是类似于红-绿-重构红色,只有当我看到红条在我的测试过程中我知道,绿坝是指我写的代码有差别.如果我写一个通过测试,那么任何代码都会满足它; 同样,对于安排,断言法断言,如果我的第一个断言失败,我知道,任何法案会通过最后断言-因此,它实际上并没有证实有关都难.

你的测试是否遵循这种模式?为什么或者为什么不?

更新澄清:最初的断言基本上与最终断言相反.这不是安排工作的主张; 这是法案尚未奏效的断言.

Mar*_*ann 119

这不是最常见的事情,但仍然很常见,有自己的名字.这种技术称为Guard Assertion.您可以在Gerard Meszaros 的优秀书籍xUnit Test Patterns(强烈推荐)中找到第490页的详细说明.

通常情况下,我自己不使用这种模式,因为我发现编写一个特定的测试更加正确,该测试验证了我认为需要确保的任何前提条件.如果前提条件失败,这样的测试应该总是失败,这意味着我不需要在所有其他测试中嵌入它.这样可以更好地隔离问题,因为一个测试用例只能验证一件事.

对于给定的测试用例,可能需要满足许多前提条件,因此您可能需要多个Guard Assertion.不是在所有测试中重复这些测试,而是对每个前提条件进行一次(和唯一一次)测试,这样可以使测试代码更具可持续性,因为这样可以减少重复次数.

  • 我通常也是这样做的,但是有一个单独的测试来确保前提条件(特别是对于需要改变的大型代码库)的问题 - 前置条件测试会随着时间的推移而被修改并与'main'不同步测试预先假定这些先决条件.所以前提条件可能都是精细和绿色,但主要测试中不满足这些先决条件,现在总是显示绿色和精细.但如果先决条件是在主要测试中,他们就会失败.您是否遇到过这个问题,并为它找到了一个很好的解决方案? (3认同)
  • 如果你经常更改你的测试,你可能[有其他问题](http://blog.ploeh.dk/2013/04/02/why-trust-tests),因为这会使你的测试不那么值得信赖.即使面对不断变化的需求,也要考虑[以仅附加方式设计代码](http://blog.ploeh.dk/2012/01/03/SOLIDisAppend-only). (2认同)

Ole*_*nge 31

它也可以指定为Arrange- Assume -Act-Assert.

在NUnit中有一个技术手段,如下例所示:http://nunit.org/index.php? p = theory&r = 2.5.7


Car*_*ter 8

这是一个例子.

public void testEncompass() throws Exception {
    Range range = new Range(0, 5);
    assertFalse(range.includes(7));
    range.encompass(7);
    assertTrue(range.includes(7));
}
Run Code Online (Sandbox Code Playgroud)

可能是我写Range.includes()的只是回归真实.我没有,但我可以想象我可能有.或者我可以用其他许多方式写错了.我希望并期望通过TDD我实际上做对了 - includes()这才有效 - 但也许我没有.所以第一个断言是一个健全性检查,以确保第二个断言真的有意义.

阅读本身,assertTrue(range.includes(7));是说:"断言修改后的范围包括7".阅读第一个断言的上下文,它说:"断言调用包含()会导致它包含7.并且由于包含是我们正在测试的单位,我认为这是一些(小)值.

我接受了自己的答案; 很多其他人误解了我的问题是关于测试设置.我认为这略有不同.


Sam*_*mmi 7

一个Arrange-Assert-Act-Assert测试可以随时被重构到两个测试:

1. Arrange-Assert
Run Code Online (Sandbox Code Playgroud)

2. Arrange-Act-Assert
Run Code Online (Sandbox Code Playgroud)

第一个测试只会断言在编配阶段建立的测试,第二个测试只会声明在法案阶段发生的测试.

这样做的好处是能够提供更准确的反馈,无论是安排还是行动失败,而原来Arrange-Assert-Act-Assert这些都是混淆的,你必须深入挖掘并仔细检查断言失败的原因以及为什么失败以便知道是否失败失败的是安排或行为.

它还可以更好地满足单元测试的目的,因为您将测试分成较小的独立单元.

最后,请记住,每当您在不同的测试中看到类似的"排列"部分时,您应该尝试将这些部分放入共享帮助程序方法中,以便将来测试更干燥,更易于维护.


Val*_*mas 5

我现在正在这样做。不一样的AAAA

Arrange - setup
Act - what is being tested
Assemble - what is optionally needed to perform the assert
Assert - the actual assertions
Run Code Online (Sandbox Code Playgroud)

更新测试示例:

Arrange: 
    New object as NewObject
    Set properties of NewObject
    Save the NewObject
    Read the object as ReadObject

Act: 
    Change the ReadObject
    Save the ReadObject

Assemble: 
    Read the object as ReadUpdated

Assert: 
    Compare ReadUpdated with ReadObject properties
Run Code Online (Sandbox Code Playgroud)

原因是 ACT 不包含 ReadUpdated 的读取,因为它不是该行为的一部分。该行为只是改变和拯救。所以真的,ARRANGE ReadUpdated 用于断言,我正在调用 ASSEMBLE 进行断言。这是为了防止混淆 ARRANGE 部分

ASSERT 应该只包含断言。这使得 ACT 和 ASSERT 之间的 ASSEMBLE 设置了断言。

最后,如果你在排列中失败了,你的测试是不正确的,因为你应该有其他测试来防止/发现这些微不足道的错误。因为对于我提出的场景,应该已经有其他测试来测试 READ 和 CREATE。如果您创建“保护断言”,您可能会破坏 DRY 并创建维护。