Pex(测试生成)真的很有用吗?

Yau*_*kha 28 .net unit-testing code-generation pex

是的,可以为"Sum"或"Divide"等函数生成边界值测试.Pex是一个很好的工具.

但更多时候我们会对商业行为进行测试.让我们考虑经典Beck的tdd书中的例子:

[Test]
public void ShouldRoundOnCreation()
{
  Money money = new Money(20.678);
  Assert.AreEqual(20.68,money.Amount);
  Assert.AreEqual(2068,money.Cents);
}
Run Code Online (Sandbox Code Playgroud)

可以生成此测试吗?没有:)我项目中95%的测试检查业务逻辑,无法生成.

Pex(特别是与Moles配对)可以提供100%的代码覆盖率,但是测试套件的高代码覆盖率从未表明,代码经过了充分测试 - 它只能让所有内容都经过测试.这非常危险.

所以,问题是 - Pex真的是有用的工具吗?

Pel*_*eli 29

我认为你错误的方式应该使用Pex:我们强烈建议用户在参数化单元测试中编写断言.

如果你编写断言,Pex会尝试系统地使它们失效 - 这就是Pex的强大之处:你写断言的次数越多,它就会越多地为你找到bug.

如果您使用Pex获得高代码覆盖率测试套件而不编写断言,那么您只能获得所要求的内容:代码覆盖率和有保证的运行时异常.Pex'只'试图覆盖分支(1断言= 1分支),如果没有分支覆盖(没有断言),它将不会产生有趣的测试用例.

通常,在参数化单元测试中编写断言更难写,因为......它们更通用.让我们从舍入行为开始:肯定有一个允许舍入发生的界限,这应该自然地转换为参数化单元测试:

[PexMethod]
public void RoundInBounds(double value) 
{
    var money = new Money(value);
    // distance between value and amount should be at most 0.01/2
    Assert.AreEqual(value, money.Amount, 0.005);
}
Run Code Online (Sandbox Code Playgroud)

还有许多模式可用于编写这些模式.例如,您的"Money"类可能是幂等的:如果您在Money实例中返回'Amount'的值,则会返回Amount.这优雅地转化为参数化单元测试:

[PexMethod]
public void RoundIsIdempotent(double value) 
{
     var first = new Money(value).Amount;
     var second = new Money(first).Amount;
     Assert.AreEqual(first, second, 0.0001);
}
Run Code Online (Sandbox Code Playgroud)

另请注意,参数化单元测试绝对属于TDD世界.首先编写参数化单元测试,Pex将找到失败的bug,修复bug,Pex找到下一个失败的bug等等......

这是否使Pex成为有用的工具?你是法官.

  • 我更喜欢NUnit而不是MSTest,因为它更完整.但是我真的没有任何反对MSTest的东西. (2认同)
  • 欢迎您将传统的单元测试和参数化单元测试相结合:参数化单元测试只是带参数的方法.如果你需要添加一个回归场景,只需添加它 - 不要陷入一种方法,拥抱所有. (2认同)
  • Pex可以为MSTest,NUnit,xUnit.net或MbUnit生成开箱即用的单元测试.实际上,它是可扩展的,因此您可以提出自己的单元测试框架并进行集成. (2认同)