双值的assertEquals的epsilon参数的含义
我有一个关于junit assertEqualstestingdouble值的问题。 阅读API文档我可以看到:
@Deprecated public static void assertEquals(double expected, double actual)
已过时。 使用assertEquals(double expected,double actual,double epsilon)来代替
epsilon的价值是什么意思? (Epsilon是希腊字母中的一个字母,对吧?)。
有人可以向我解释如何使用它?
Epsilon是2个数字可以被忽略的值。 所以,只要Math.abs(expected - actual) < epsilon
就会声明为true
哪个版本的JUnit是这个? 我只见过三angular洲,而不是epsilon – 但这是一个侧面的问题!
从JUnit javadoc :
三angular洲 – 预期与实际之间的最大三angular洲,这两个数字仍被视为相等。
这可能是过度的,但我通常使用一个非常小的数字,例如
private static final double DELTA = 1e-15; @Test public void testDelta(){ assertEquals(123.456, 123.456, DELTA); }
如果你使用的是hamcrest断言,你可以使用两个双打的标准equalTo()
(它不使用delta)。 但是,如果你想要一个增量,你可以使用closeTo()
(见javadoc ),例如
private static final double DELTA = 1e-15; @Test public void testDelta(){ assertThat(123.456, equalTo(123.456)); assertThat(123.456, closeTo(123.456, DELTA)); }
仅供参考当使用两个双打调用assertEquals()
时,即将推出的JUnit 5也将使Delta成为可选项 。 实现 (如果你感兴趣的话)是:
private static boolean doublesAreEqual(double value1, double value2) { return Double.doubleToLongBits(value1) == Double.doubleToLongBits(value2); }
浮点计算并不精确 – 通常有四舍五入的错误,以及由于表示而导致的错误。 (例如,0.1不能用二进制浮点正确表示。)
因此,直接比较两个浮点值是否相等通常不是一个好主意,因为根据计算方式的不同,它们可能会有所不同。
在JUnit javadocs中调用的“delta”描述了值可以容忍的差异量,它们仍然被认为是相等的。 这个值的大小完全取决于你正在比较的值。 比较双打时,我通常使用预期值除以10 ^ 6。
事情是由于浮点数固有的精度问题,两个double可能不完全相等。 使用这个增量值,您可以根据错误因素控制相等的评估。
另外一些浮点值可以有特殊的值,如NAN和-Infinity / + Infinity,它们可以影响结果。
如果你真的打算比较两个双打是完全相等的,最好把它们作为一个长的表示
Assert.assertEquals(Double.doubleToLongBits(expected), Double.doubleToLongBits(result));
要么
Assert.assertEquals(0, Double.compareTo(expected, result));
哪些可以考虑到这些细微差别。
我还没有深入研究Assert方法,但我只能假设以前已被弃用的这种问题,新的一个考虑到他们。
请注意,如果您没有进行math运算,则声明精确的浮点值没有任何问题。 例如:
public interface Foo { double getDefaultValue(); } public class FooImpl implements Foo { public double getDefaultValue() { return Double.MIN_VALUE; } }
在这种情况下,您要确保它是真正的MIN_VALUE
,而不是零或-MIN_VALUE
或MIN_NORMAL
或其他非常小的值。 你可以说
double defaultValue = new FooImpl().getDefaultValue(); assertEquals(Double.MIN_VALUE, defaultValue);
但这会给你一个贬低警告。 为了避免这种情况,你可以调用assertEquals(Object, Object)
来代替:
// really you just need one cast because of autoboxing, but let's be clear assertEquals((Object)Double.MIN_VALUE, (Object)defaultValue);
而且,如果你真的想看起来很聪明:
assertEquals( Double.doubleToLongBits(Double.MIN_VALUE), Double.doubleToLongBits(defaultValue) );
或者你可以使用Hamcreststream畅式的断言:
// equivalent to assertEquals((Object)Double.MIN_VALUE, (Object)defaultValue); assertThat(defaultValue, is(Double.MIN_VALUE));
如果你正在检查的值是来自做一些math,但是,使用epsilon。
Epsilon是expected
值和actual
值之间的差异,您可以接受认为它们是平等的。 例如,您可以设置.1
。
没有必要涉及epsilon或三angular洲。
Assert.assertTrue("Not equals", expectedDouble - actualDouble == 0);