带小数的 PHP 和单元测试断言

Posted

技术标签:

【中文标题】带小数的 PHP 和单元测试断言【英文标题】:PHP and unit testing assertions with decimals 【发布时间】:2010-12-30 02:28:21 【问题描述】:

我有一个方法可以返回像 1.234567890 这样的浮点数。我想测试它是否确实如此。但是,这个返回的浮点数似乎在不同的平台上具有不同的精度,那么我如何断言返回的值为 1.23456789?如果我这样做:

$this->assertEqual(1.23456789, $float);

那么在某些精度不够的平台上可能会失败。

【问题讨论】:

【参考方案1】:

到目前为止还没有提到 assertEquals 支持通过offering a delta to specifiy precision比较浮点数:

$this->assertEquals(1.23456789, $float, '', 0.0001);

感谢@Antoine87 提供pointing out:since phpunit 7.5,您应该使用assertEqualsWithDelta()

$this->assertEqualsWithDelta(1.23456789, $float, 0.0001);

【讨论】:

喜欢简单的解决方案。这应该是公认的。接受的解决方案会让我在 BCMath 中挖掘一个小时。【参考方案2】:

作为@bernhard-wagner 答案的更新,您现在应该使用assertEqualsWithDelta() since phpunit 7.5。

$this->assertEqualsWithDelta(1.23456789, $float, 0.0001);

【讨论】:

【参考方案3】:

一般来说,测试内置浮点数是否相等是个坏主意。由于accuracy problems 的浮点表示,两种不同计算的结果在数学上可能完全相等,但是当您在 PHP 运行时比较它们时会有所不同。

解决方案 1:比较它们之间的距离。比如说,如果绝对差值小于 0.000001,则将值视为相等。

解决方案 2:使用arbitrary precision mathematics,它支持任意大小和精度的数字,以字符串表示。

【讨论】:

+1 表示从不测试浮点数是否相等。可怕的是有多少人不知道这一点。希望我能投票更多... 对,老兄。我很久以前就真正学会了它,编写了自己的光线追踪程序,并想知道为什么我在屏幕上只得到几个点而不是美丽的多边形。 :-)【参考方案4】:

为了获得更高的准确性,您可以考虑使用BCMath。

【讨论】:

bccomp() 很适合我的情况。【参考方案5】:

除了使用 bcmath() 之外,您还可以设置默认精度,如下所示:

ini_set('precision', 14);

【讨论】:

以上是关于带小数的 PHP 和单元测试断言的主要内容,如果未能解决你的问题,请参考以下文章

Spock单元测试断言日志调用并查看输出

JSON 响应断言失败 PHP 单元

PHP单元测试,带模拟的受保护方法

python+selenium+unittest测试框架1-unittest单元测试框架和断言

学习单元测试常用的断言 assertTrue 和 assertEquals 一篇文章就够了

使用闭包进行 PHP 单元测试