Pex和代码合同的单元测试

时间:2011-12-12 20:54:04

标签: c# .net-4.0 tdd code-contracts pex

我有以下方法:

public static DateTime SubQtrs( this DateTime dt, int qtrs )
{
    Contract.Requires( qtrs > -1 );
    Contract.Requires( ( qtrs * 3 ) >= -120000 && ( qtrs * 3 ) <= 120000 );
              // do something
     }

我创建了一个参数化单元测试并使用Pex来进行一些单元测试。正如预期的那样,Pex测试了合同约束并传递了违反合同的qtrs值。我告诉单元测试期望异常:[ExpectedException(typeof(TraceAssertionException))]并且一切都通过了。

现在,当我使用MS Test Harness运行单元测试(没有Pex)时,我收到一个错误: Descrtipion:前提条件失败:(qtrs * 3&gt; = -120000&amp;&amp; ......

它给了我堆栈跟踪,基本上告诉我contracthelper失败了。然后我就可以选择中止,重试或忽略。

无论哪种方式,测试都失败了,我得到:失败SubQtrsThrowsTraceAssertionException818 DGALib.Extensions.Tests测试方法System.ExtensionMethodsTest.SubQtrsThrowsTraceAssertionException818抛出了异常System.ArgumentOutOfRangeException,但异常Microsoft.Pex.Framework.Exceptions.TraceAssertionException是预期的。异常消息:System.ArgumentOutOfRangeException:Months值必须介于+/- 120000之间。 ...

为什么单元测试不再识别代码合同错误?

2 个答案:

答案 0 :(得分:0)

听起来,当您手动运行单元测试时,您没有在程序集上运行合同重写器,因此Requires契约永远不会导致异常。它听起来像你在方法中有一些手动检查代码抛出ArgumentOutOfRangeException,这是正确的行为(在运行时,没有合同重写),但不匹配您的预期测试异常。确保安装了Code Contracts重写器,并确保Project设置包括重写异常。

或者,使用Requires重载指定Exception类型,使其与内部检查匹配。在这种情况下,您甚至可以删除其他显式异常,只要您知道您打算使用重写。

Contract.Requires<ArgumentOutOfRangeException>( ( qtrs * 3 ) >= -120000 && ( qtrs * 3 ) <= 120000 , "qtrs");

答案 1 :(得分:0)

似乎丢失了该屏幕的测试[HostType(“Moles”)]。

我将导致问题的测试与另一个也应该抛出跟踪断言并且没有引起问题的测试进行了比较。唯一的区别是导致问题丢失的那个[HostType(“Moles”)]。一旦我添加了该属性,测试就会起作用。

关于合同的错误必须从其他地方冒出来然后让我进行疯狂的追逐。

在我开始向其他测试场景添加摩尔之前,Pex必须已经创建了该测试。