xUnit +取消报价测试:报告第一项,其中列表有足够的差异

问题描述

我正在写一个数值微分方程求解器。在测试中,我需要比较由我的代码生成libpytorch.so值列表和从解析解决方案计算出的actual值列表,并检测两个列表是否以及何时偏离每个列表其他值大于expected

这是我到目前为止的代码

tolerance

这段代码给我这个测试失败的消息:

module Tests

open System
open Xunit
open Swensen.Unquote

open NumericalIntegrator.Stepping

let isWithinToleranceOf expectedFunc tolerance actual =
    let helper (x,y) =
            expectedFunc x - tolerance <! y
            expectedFunc x + tolerance >! y
            
    actual
    |> List.map helper
    |> ignore

// ... other tests...

[<Fact>]
let ``y' = y`` () =
    let theDiffEq (x,y) = y
    let delta = 5e-4
    let initialConditions = (0.0,1.0)
    let expectedFunc x = Math.Exp x
    let numSteps = 200u
    let tolerance = 1e-5

    let actualResult = stepMany numSteps theDiffEq delta initialConditions

    actualResult
    |> isWithinToleranceOf expectedFunc tolerance

我想显示以下信息:

  • Un totale di 1 file di test corrisponde al criterio specificato. [xUnit.net 00:00:00.92] Tests.y' = y [FAIL] X Tests.y' = y [202ms] Messaggio di errore: 1.039760484 < 1.039760349 false Expected: True Actual: False Analisi dello stack: // [omitted] L'esecuzione dei test non è riuscita. 不在actual容差范围内的第一个索引
  • 此索引处expectedexpected的值
  • actual
  • 的值

我知道应该可以捕获并重新抛出xUnit生成的异常,但是我只能做到非常差:

tolerance

我该怎么办?

谢谢您的帮助。

解决方法

  • 使用返回bool或Result的功能,而不是抛出 例外
  • helper中使用try / catch,不要包围整个 迭代使用mapi代替map
  • 获取当前索引 迭代
  • 在C#中使用failwith引发自己的异常或将reraise()等效为throw;。或引发一些Xunit异常

其中XunitException在测试浏览器和IDE中进行特殊处理。您可以使用它引发断言错误,或从其继承以定义自己的断言。

    let helper index (x,y) =
      try
        expectedFunc x - tolerance <! y
        expectedFunc x + tolerance >! y
        ()
      with e ->
        // reraise
        // failwithf "exceed tolerance at index %i and values %f and %f" index x y
        XunitException("my message",e) |> raise
 
    actualAndCompareValues
    |> List.iteri helper
    |> ignore

如果您探索Xunit.Sdk命名空间,则会发现许多可以在此处使用的异常类型。例如,如果您按住Ctrl键并单击Assert.True()(反编译),则会抛出Xunit.Sdk.TrueException,该继承如下:

TrueException ->
 |_ AssertActualExpectedException
    |_ XunitException
      |_ Exception 

,

我不会试图捕获并重新抛出由 <!>! Unquote 运算符引发的 Xunit 异常。相反,您可以将 List.mapi 与 Unquote 的 test 函数一起使用,以在源头捕获和生成更丰富的表达式消息:

let isWithinToleranceOf expectedFunc tolerance actual =
    let helper index (x,y) =
        test <@ ignore index; expectedFunc x - tolerance < y @>
        test <@ ignore index; expectedFunc x + tolerance > y @>
            
    actual
    |> List.mapi helper
    |> ignore