【问题标题】:False Negative Unit Test with Pex, Contracts, and QuickGraph使用 Pex、Contracts 和 QuickGraph 进行假阴性单元测试
【发布时间】:2011-01-30 20:05:30
【问题描述】:

每个人。我在合同、pex 和 quickgraph 之间有一个令人困惑的交互,非常感谢知识渊博的人提供的建议。我把它归结为一个复制案例,其中注释掉一个合同会使假阴性消失,但我无法在允许的时间内用调试器诊断它,因为主题代码(快速图)对属性有副作用- getters,意味着调试器在显示属性值时执行副作用,干扰实际执行顺序。

首先是一点背景,然后是细节,然后是一个可供下载和试用的项目的指针,如果您愿意深入研究的话!

我安装了 Pex 和 Moles

http://research.microsoft.com/en-us/projects/pex/downloads.aspx

和 .NET 4.0 的 CodeContracts

http://research.microsoft.com/en-us/projects/contracts/

我通过 nuget 下载了最新版本的 QuickGraph,它都是为 .NET 3.5 构建的。我将它修剪到我需要的最低限度,进入所有项目属性,将它们全部从 .NET 3.5 客户端配置文件更新到 .NET 4.0,修复了一个源中断更改(这是微不足道的,非常非常不可能与我的问题)。然后我转到每个项目页面上的 Code Contracts 选项卡并启用所有静态和动态选项。

http://quickgraph.codeplex.com/releases/view/55262

该项目有 192 个单元测试,其中许多是 Pex 生成的(非常好!)。要运行测试,请从

获取我的项目 zip 文件

http://dl.dropbox.com/u/1997638/QuickGraph.zip

确保您拥有上述链接中的 Pex & Moles 和 Contracts。打开解决方案,重建所有内容,然后在解决方案级别,“在解决方案中运行所有测试”(control-R,A)。一切都会过去的。然后转到 IImplicitUndirectedGraphContracts.cs 的第 49 行并取消注释大注释下的合同(由我插入)。一项测试,Prim12240WithDelegate 将失败。

该测试通过在 Edges 和 EdgeCount 的属性获取器中调用用户提供的委托来动态构建边的图形构造函数。可爱的。但是 IImplicitUndirecteGraphContracts.cs 第 49 行的 Contract 出了点问题。

这是一个假阴性,因为如果我注释掉这个合同,测试就通过了。在调试器中尝试遵循这一点时,它与在属性 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>);
  }

【问题讨论】:

    标签: unit-testing c#-4.0 pex contracts quickgraph


    【解决方案1】:

    Pex 在 .NET 4.0 运行时处理 LINQ 表达式时存在问题。来自first answer on this MSDN forum post for more details

    我们的 Linq 支持适用于 .NET 2.0/3.5,但我们似乎有一个 .NET4.0 的回归。如果您正在运行 4.0,那将解释为什么 Pex 无法生成有趣的测试用例 - 我们不检测 Linq 正确。

    为什么 Pex 仍然与 Linq 斗争:简而言之,Linq 使用 DynamicMethod 的生成代码。 DynamicMethod 方法不是 当他们被 jitted 时报告给分析器。因为我们的分析器 无法在 DynamicMethod 中注入回调,Pex 无法跟踪 数据流通过 Linq 查询。我们有一个解决方法可以拦截 Linq to Object 编译器的内部结构并强制它使用 改为 Reflection.Emit。

    这可能会使其忽略您在评估期间注释掉的合同,从而导致误报。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-10
      • 1970-01-01
      • 1970-01-01
      • 2011-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多