如何在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
相关产品推荐
相关产品推荐

