You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在xUnit中按百分比容差断言两个数值相等?

在xUnit中实现百分比容差的数值断言

我之前也遇到过这个问题!xUnit的Assert.Equal确实没有直接对应NUnit那种.Within(xxx).Percent的重载——你尝试的Assert.Equal(turnOver, turnoverExpected, tolerance)编译失败,是因为xUnit里这个方法的第三个参数是整数类型的有效数字位数,而非double类型的百分比容差。

这里有两种靠谱的实现方式,完全可以替代NUnit的功能:

方法一:手动计算相对误差并断言

直接通过Assert.True来验证实际值与预期值的相对误差是否在允许的百分比范围内,这种方式简单直接,不需要额外类:

double turnOver = /* 你的实际值 */;
double turnoverExpected = /* 你的预期值 */;
double percentTolerance = 0.00001; // 允许0.00001%的误差

// 特殊处理预期值为0的情况(避免除以0)
if (turnoverExpected == 0)
{
    Assert.Equal(turnOver, turnoverExpected);
}
else
{
    // 计算相对误差:|(实际-预期)/预期| <= 容差百分比/100
    double relativeError = Math.Abs((turnOver - turnoverExpected) / turnoverExpected);
    Assert.True(
        relativeError <= percentTolerance / 100,
        $"实际值 {turnOver} 与预期值 {turnoverExpected} 的误差超过 {percentTolerance}%"
    );
}

方法二:自定义百分比容差比较器

如果需要在多个测试中复用这个逻辑,可以创建一个实现IEqualityComparer<double>的比较器类,这样就能直接用Assert.Equal的重载:

自定义比较器类

public class PercentToleranceComparer : IEqualityComparer<double>
{
    private readonly double _percentTolerance;

    public PercentToleranceComparer(double percentTolerance)
    {
        _percentTolerance = percentTolerance;
    }

    public bool Equals(double actual, double expected)
    {
        if (expected == 0)
            return actual == expected; // 可根据需求调整0值的处理逻辑

        double relativeError = Math.Abs((actual - expected) / expected);
        return relativeError <= _percentTolerance / 100;
    }

    public int GetHashCode(double obj)
    {
        return obj.GetHashCode();
    }
}

使用比较器

Assert.Equal(turnOver, turnoverExpected, new PercentToleranceComparer(0.00001));

内容的提问来源于stack exchange,提问作者nick gowdy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:35:23