应该和应该在KotlinTest中有什么区别?
这是一个使用KotlinTest 1.3.5的测试代码。
val expect = 0.1 val actual: Double = getSomeDoubleValue() actual shouldBe expect
这个警告是在代码运行时打印的。
[WARN]比较双打时考虑使用宽容,例如:a shouldBe b plusOrMinus c
在这种情况下,我不想使用plusOrMinus
。 所以,我修复了代码
val expect = 0.1 val actual: Double = getSomeDoubleValue() actual shouldBe exactly(expect)
现在,没有任何警告。
不过,我想知道shouldBe
和shouldBe exactly
的区别。 它是什么?
根据目前的消息来源 :
infix fun Double.shouldBe(other: Double): Unit = ToleranceMatcher(other, 0.0).test(this)
ToleranceMatcher
位置
class ToleranceMatcher(val expected: Double, val tolerance: Double) : Matcher<Double> { override fun test(value: Double) { if (tolerance == 0.0) println("[WARN] When comparing doubles consider using tolerance, eg: a shouldBe b plusOrMinus c") val diff = Math.abs(value - expected) if (diff > tolerance) throw AssertionError("$value is not equal to $expected") } infix fun plusOrMinus(tolerance: Double): ToleranceMatcher = ToleranceMatcher(expected, tolerance) }
因此,匹配d shouldBe e
会精确地比较双打,没有任何宽容( a - b
不会给不同的双打0
),并打印警告:
[WARN]比较双打时考虑使用宽容,例如:a shouldBe b plusOrMinus c
而exactly(d)
被定义为
fun exactly(d: Double): Matcher<Double> = object : Matcher<Double> { override fun test(value: Double) { if (value != d) throw AssertionError("$value is not equal to expected value $d") } }
所以它也会这样做 ,尽管没有任何警告。
我想,这个警告的意思是鼓励开发人员明确地指定双精度比较,否则指定容差,因为即使按不同顺序完成相同的算术,也可能产生不同的双精度结果。
比较浮点数,特别是计算的浮点数,由于某些浮点数可能无法表示,因此将它们转换为二进制的方式总是受到舍入误差的影响。 所以在进行测试时,通常必须给出一个可接受的舍入误差值。
在KotlinTest中,这是使用plusOrMinus
说明符指定的。
如果有的情况下,你知道这个数字应该是一个给定的值(例如,它被初始化为0或10或其他),然后使用exactly
说明符。 大概这在幕后指定一个非常小的错误值或比较双打其他方式。
为了断言双精度等于另一个双精度值,应该正好(e)
要声明double在某个公差范围内是相等的,可以使用d shouldBe(e plus orrminin y)
资源
如果你只是自己使用shouldBe
,那么系统会做一个简单的if a == b
类型的测试,将暴露你的测试上述舍入错误。