使用Pex,Contracts和QuickGraph进行假阴性单元测试

大家。我在合同,pex和quickgraph之间有一种令人困惑的互动,并且非常感谢更有见识的人的建议。我把它归结为一个责备案例,其中评论一个合同使得假负面消失,但我无法在允许的时间内使用调试器对其进行诊断,因为主题代码(quickgraph)在属性中有副作用 - getters,意味着调试器在显示属性的值时执行副作用,干扰实际的执行顺序。 首先是一个小背景,然后是具体细节,然后指向要下载和试用的项目的指针,如果你倾向于深入研究! 我安装了Pex&痣 http://research.microsoft.com/en-us/projects/pex/downloads.aspx 和CodeContracts for .NET 4.0 http://research.microsoft.com/en-us/projects/contracts/ 我通过nuget下载了最新版本的QuickGraph,它全部是为.NET 3.5构建的。我把它修剪到我需要的最小值,进入所有项目属性,从.NET 3.5 Client Profile更新到.NET 4.0,修复了一个来源的破坏变化(这很简单,非常,非常不可能与我的任何连接问题)。然后,我转到每个项目页面上的Code Contracts选项卡,并启用所有静态和动态选项。 http://quickgraph.codeplex.com/releases/view/55262 该项目有192个单元测试,其中许多是Pex生成的(非常好!)。要运行测试,请从中获取我的项目zip文件 http://dl.dropbox.com/u/1997638/QuickGraph.zip 确保你有Pex&来自上述链接的摩尔和合同。打开解决方案,重建所有内容,然后在解决方案级别“运行所有测试解决方案”(control-R,A)。一切都会过去的。然后转到IImplicitUndirectedGraphContracts.cs的第49行,并在大评论(由我插入)下取消注释合同。一个测试,Prim12240WithDelegate将失败。 该测试通过在Edges和EdgeCount的property-getters中调用用户提供的委托来运行图形构造函数,该构造函数即时构建边缘。可爱。但是IImplicitUndirecteGraphContracts.cs第49行的合同出了问题。 这是假阴性,因为如果我注释掉这个合同,测试就会通过。在调试器中试图遵循这一点时,它与在属性getter中创建边缘的时间有关。然而,我无法解开这个问题,因为调试器会调用这些getter,主题代码会调用它们,合同代码会调用它们,也许是静态的,也许是动态的,我只是很想丢失试图跟随它,并且认为我将这个问题提交给那些比我更了解合同执行细节的人。 这是违规合同;评论它使单元测试成功:
[Pure]
  IEnumerable<TEdge> IImplicitUndirectedGraph<TVertex, TEdge>.AdjacentEdges(TVertex v)
  {
    IImplicitUndirectedGraph<TVertex, TEdge> ithis = this;
    Contract.Requires(v != null);
    Contract.Requires(ithis.ContainsVertex(v));
    Contract.Ensures(Contract.Result<IEnumerable<TEdge>>() != null);
~~~~~~> Contract.Ensures(
      Enumerable.All(
        Contract.Result<IEnumerable<TEdge>>(),
        edge => 
          edge != null && 
          ithis.ContainsEdge(edge.Source, edge.Target) && 
          (edge.Source.Equals(v) || edge.Target.Equals(v))
        )
      );
    return default(IEnumerable<TEdge>);
  }
    
已邀请:
Pex在.NET 4.0运行时中处理LINQ表达式存在问题。从MSDN论坛帖子的第一个回答中了解更多详情:   我们的Linq支持适用于.NET 2.0 / 3.5,但我们似乎有一个   .NET4.0的回归。如果您运行4.0,那将解释原因   Pex无法生成有趣的测试用例 - 我们不会使用Linq   正确。      为什么Pex无论如何都要与Linq斗争:简而言之,Linq使用   DynamicMethod用于生成代码。 DynamicMethod方法不是   在他们被jitted时向分析者报告。因为我们的探查器   无法在DynamicMethod中注入回调,Pex无法跟踪   数据流通过Linq查询。我们有一个拦截的解决方法   Linq to Object编译器的内部并强制它使用   反思。改为。 这可能会使其忽略您在评估期间注释掉的合同,从而导致误报。     

要回复问题请先登录注册