6

从文档:

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

InDelta 断言这两个数字在彼此的 delta 范围内

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

InEpsilon 断言预期和实际的相对误差小于 epsilon

他们的代码在目的上似乎是相同的:

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)\n"+
            "        < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...)
    }

    return true
}

有什么不同?有哪些用例可以将一个用于另一个,反之亦然?

4

1 回答 1

13

它们相关但不相同。

InDelta接收绝对值并检查差值是否小于该值。

InEpsilon收到可接受的差异百分比。

的行为InDelta非常简单:

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

但有时,您只关心实际值与期望值相差不是太远。

根据期望值“不太远”的大小,可能会变得棘手InDelta

delta对任何数字使用相同的值可能是个问题:

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...

如果使用InEpsilon,则始终可以使用相同的 %:

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

总而言之,for 的用例ÌnEpsilon是丢弃小的差异(并使相对于比较的实际值“小”)。

于 2017-07-25T18:01:32.390 回答