douangoo48863 2017-07-25 17:46
浏览 82
已采纳

InDelta和InEpsilon之间的区别

From documentation:

https://godoc.org/github.com/stretchr/testify/assert#InDelta

InDelta asserts that the two numerals are within delta of each other

https://godoc.org/github.com/stretchr/testify/assert#InEpsilon

InEpsilon asserts that expected and actual have a relative error less than epsilon

And their code seems to be identical in purpose:

func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {

    af, aok := toFloat(expected)
    bf, bok := toFloat(actual)

    if !aok || !bok {
        return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...)
    }

    if math.IsNaN(af) {
        return Fail(t, fmt.Sprintf("Expected must not be NaN"), msgAndArgs...)
    }

    if math.IsNaN(bf) {
        return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...)
    }

    dt := af - bf
    if dt < -delta || dt > delta {
        return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
    }

    return true
}

func calcRelativeError(expected, actual interface{}) (float64, error) {
    af, aok := toFloat(expected)
    if !aok {
        return 0, fmt.Errorf("expected value %q cannot be converted to float", expected)
    }
    if af == 0 {
        return 0, fmt.Errorf("expected value must have a value other than zero to calculate the relative error")
    }
    bf, bok := toFloat(actual)
    if !bok {
        return 0, fmt.Errorf("actual value %q cannot be converted to float", actual)
    }

    return math.Abs(af-bf) / math.Abs(af), nil
}

// InEpsilon asserts that expected and actual have a relative error less than epsilon
//
// Returns whether the assertion was successful (true) or not (false).
func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
    actualEpsilon, err := calcRelativeError(expected, actual)
    if err != nil {
        return Fail(t, err.Error(), msgAndArgs...)
    }
    if actualEpsilon > epsilon {
        return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)
"+
            "        < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...)
    }

    return true
}

What is the difference? what are the use cases where one would be used over the other and vice versa?

  • 写回答

1条回答 默认 最新

  • dongtan9518 2017-07-25 18:01
    关注

    They are related but not identical.

    InDelta receives an absolute value and checks that the difference is less than that value.

    InEpsilon receives a % of difference that would be acceptable.

    The behaviour of InDelta is quite straightforward:

    InDelta(t, 100, 101, 2) // that's OK
    InDelta(t, 100, 103, 2) // fail!
    

    But sometimes, you just care that the actual value is not too far away from the expected value.

    Depending on how small or large the expected value is "not too far away" might get tricky with InDelta.

    It might be a problem to use the same delta value for any number:

    InDelta(t, 100, 101, 2) // ok, 101 is "not too far away" from 100
    InDelta(t,   1,   2, 2) // hm, 2 sounds "too far away" from 1...
    

    If you use InEpsilon, you can always use the same %:

    InEpsilon(t, 100, 101, 0.02) // ok, up to 102 would be acceptable
    InEpsilon(t,   1,   2, 0.02) // will not pass.. this time up to 1.02 would be acceptable
    

    In summary, the use case for ÌnEpsilon is to discard small differences (and making "small" relative to the actual values compared).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图