Phpunit: assertEquals 在带有小数 ('0', '0.00') 的等效字符串上意外失败

创建于 2018-06-26  ·  22评论  ·  资料来源: sebastianbergmann/phpunit

| 问 | 一种
| --------------------| ---------------
| PHPUnit 版本 | 7.3-g2e9ab30
| PHP版本| 7.1.18
| 安装方法 | 作曲家


作曲家信息 | 种类
前因/拼凑 2.1.8 方法重定义(monkey-...
aws/aws-sdk-php 3.10.1 适用于 PHP 的 AWS 开发工具包 - 使用亚马逊...
cebe/markdown 1.1.0 一个超快速、高度可扩展的...
cocur/slugify v0.7 将字符串转换为 slug。
composer/ca-bundle dev-master 134242f 让你找到通往......的路径
学说/注释 dev-master 2497b1f Docblock 注释解析器
学说/缓存 dev-master beb0fa3 缓存库提供了一个......
学说/集合 dev-master 42c4039 集合抽象库
教义/通用开发大师 a3e240f 教义通用库...
学说/inflector dev-master 40daa06 常见的字符串操作...
学说/实例化器 dev-master 870a62d 一个小而轻的实用程序...
学说/词法分析器 dev-master cc709ba 词法分析器的基础库...
facebook/fbmock dev-master b90fce5 FBMock 是一个 PHP 模拟框架...
firebase/php-jwt v5.0.0 一个简单的库来编码...
friendsofsymfony/rest-bundle 1.8.x-dev 12081a7 这个 Bundle 提供了各种...
giggsey/libphonenumber-for-php 5.9.1 Googl 的非官方 PHP 端口...
google/apiclient 1.0.5-beta 用于 Google API 的客户端库
guzzlehttp/guzzle 6.3.0 Guzzle 是一个 PHP HTTP 客户端......
guzzlehttp/promises dev-master 2e3e428 Guzzle 承诺库
guzzlehttp/psr7 dev-master b27e0bd PSR-7 消息实现...
hamcrest/hamcrest-php dev-master be5380f 这是Hamc的PHP移植...
ircmaxell/password-compat 1.0.x-dev 9b99377 兼容库...
jms/metadata 1.6.0 类/方法/属性元数据...
jms/parser-lib dev-master 6067cc6 一个用于轻松创建...的库
jms/serializer-bundle 1.5.0 让你轻松序列化...
jms/serializer dev-master f4683f4 用于(反)序列化的库...
League/csv 8.x-dev fa8bc05 CSV 数据操作使电子...
League/oauth2-client 2.2.1 OAuth 2.0 客户端库
maknz/slack 1.7.0 一个简单的 PHP 包,用于...
mikey179/vfsStream v1.2.0
mockery/mockery 1.0 Mockery 是一个简单而灵活的...
monolog/monolog 1.x-dev fd8c787 将您的日志发送到文件,所以...
mtdowling/cron-expression v1.0.4 CRON for PHP:计算...
mtdowling/jmespath.php 2.4.0 以声明方式指定如何...
myclas/deep-copy 1.x-dev 3e01bda 创建深拷贝(克隆)...
nutshell/nutshell-billing dev-master 8514786 Nusthell 计费
paragonie/random_compat v2.0.11 PHP 5.x polyfill for random_...
phar-io/manifest dev-master 29654cc 组件,用于读取 phar.i...
phar-io/version 2.0.0 用于处理版本的库...
phpcollection/phpcollection 0.5.0 通用集合 L...
phpdocumentor/reflection-common 1.0.1 常见反射类我们...
phpdocumentor/reflection-docblock 4.3.0 有了这个组件,一个库...
phpdocumentor/类型解析器 0.4.0
phpoption/phpoption 1.5.0 PHP 选项类型
phpspec/prophecy dev-master 6471ce6 高度自以为是的嘲讽...
phpunit/dbunit dev-master 22843ee 用于数据库的 PHPUnit 扩展...
phpunit/php-code-coverage dev-master 8656625 库,提供收集...
phpunit/php-file-iterator dev-master cecbc68 FilterIterator实现...
phpunit/php-text-template 1.2.1 简单的模板引擎。
phpunit/php-timer dev-master 9ef9968 计时工具类
phpunit/php-token-stream dev-master 711ca0c 包装器围绕 PHP 的 tokeniz...
phpunit/phpunit dev-master 2e9ab30 PHP 单元测试框架。
psr/http-message dev-master f6561bf HTTP 我的通用接口...
psr/log dev-master 4ebe3a8 常用的日志接口...
quickbooks/v3-php-sdk dev-master c69c881 官方 PHP SDK for Qui...
recurly/recurly-client dev-master 6f6d82a 用于 t...
ruudk/twitter-oauth dev-request-headers 665b1b4 PHP 5.3 版本的 abraham/t...
sabre/vobject 3.5.x-dev 129d805 PHP 的 VObject 库...
sebastian/code-unit-reverse-lookup dev-master 22f5f5f 查找哪个函数或 m...
sebastian/comarator dev-master c9eb293 提供了功能...
sebastian/diff dev-master 366541b Diff 实现
sebastian/environment dev-master 32c5cba 提供功能以...
sebastian/exporter dev-master 2096271 提供功能 t...
sebastian/global-state dev-master 30367ea 全局状态快照
sebastian/object-enumerator dev-master 06d95dc 遍历数组结构...
sebastian/object-reflector dev-master 7707193 允许反射对象......
sebastian/recursion-context dev-master dbe1869 提供重新...
sebastian/resource-operations dev-master 0f9911f 提供 PHP 构建的列表...
sebastian/version 2.0.1 有助于管理的库...
segmentio/analytics-php 1.4.2 Segment Analytics PHP 库
sensio/distribution-bundle dev-master 51554e1 Symf 的基本包...
sensio/framework-extra-bundle 2.3.x-dev f9e4c97 这个包提供了一种方法来...
sensio/generator-bundle 2.5.x-dev ab9345f 这个包生成代码 f...
sensiolabs/security-checker 4.1.x-dev d539ccb 一个安全检查器,适用于您的...
symfony/monolog-bundle 2.x-dev c710da0 Symfony MonologBu​​ndle
symfony/polyfill-apcu dev-master cec3239 Symfony polyfill 向后移植...
symfony/polyfill-intl-icu dev-master 4aa0b65 Symfony polyfill for intl ...
symfony/polyfill-mbstring dev-master 7c8fae0 用于 Mbs 的 Symfony polyfill...
symfony/polyfill-php54 dev-master b776342 Symfony polyfill 向后移植...
symfony/polyfill-php55 dev-master 29b1381 Symfony polyfill 向后移植...
symfony/polyfill-php56 dev-master e85ebde Symfony polyfill 向后移植...
symfony/polyfill-php70 dev-master b6482e6 Symfony polyfill 向后移植...
symfony/polyfill-util dev-master 67925d1 Symfony 实用程序,用于便携式...
symfony/psr-http-message-bridge dev-master b209840 PSR HTTP 消息桥接
symfony/security-acl dev-master ab4dfe2 Symfony 安全组件 -...
symfony/symfony v2.8.27 Symfony PHP 框架
symfony/yaml 3.3.x-dev 8c7bf1e Symfony Yaml 组件
这些er/tokenizer 1.1.0 一个用于转换的小型库...
twig/twig 2.x-dev d8d888e Twig,灵活、快速、...
twilio/sdk 3.13.1 Twilio API 的 PHP 包装器
webmozart/assert dev-master 53927dd 断言验证方法...
webonyx/graphql-php dev-master eaadae4 GraphQL 参考的 PHP 端口...
willdurand/jsonp-callback-validator v1.1.0 JSONP 回调验证器。
willdurand/negotiation 1.x-dev 2a59f23 内容协商工具,用于...
zendframework/zend-diactoros 1.7.x-dev 89d471c PSR HTTP 消息实现...

我是新用户,正在尝试将 phpunit 从 6.3 升级到 7.3。 我发现我们的一些测试开始失败。 根据assertEquals使用==来检查相等性的说法,他们似乎不应该这样做。

这失败了:

$this->assertEquals('0', '0.00');

但:

php -a
Interactive mode enabled

php > var_dump('0' == '0.00');
php shell code:1:
bool(true)

这是预期的吗?

最有用的评论

我们也受到这次严重的公元前中断的影响。 虽然我同意 #58 中的边缘情况很糟糕,应该避免,但我不认为更改assertEquals是正确的举动。 AssertEquals 一直是(对我来说),关于可能包括类型杂耍的松散比较。 如果您知道两个值都是字符串类型,并且您想确保上述边缘情况不会像'0.0' !== '0'那样触发,只需使用assertSame 。 基本上 assertEquals 现在是 assertEquals 和 assertSame 的混合,具体取决于类型,这使得行为根本不明显。

所有22条评论

+符号在字符串中时,我也遇到了另一个(相关的?)问题,这正是我链接到的原始问题所说的应该_不_失败的问题。

$this->assertEquals('+1', '1');

Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'+1'
+'1'

我认为这可能是由于更改: https :

我做了更多调查,这对我来说在7.1.5上开始失败,这可能是由于该版本中sebastian/comparator的主要版本升级。 事实上,我现在猜测我看到的行为是由于https://github.com/sebastianbergmann/comparator/pull/58。

需要明确的是,我并不是说这一定是一个_坏_变化。 事实上,它可能在我之前通过测试的代码中发现了一些错误。 这只是补丁版本碰撞中的一个意外的突破性变化。

ping @Ocramius

@sebastianbergmann 根据我自己的知识,为了让每个人都清楚,断言的“预期”结果是什么
$this->assertEquals('+1', '1');$this->assertEquals('0', '0.00');

如果 php 根据==将它们视为相等,则assertEquals的合同是否应该通过断言? 如果您想与===进行严格比较,请改用assertSame

不,它不是@IanVS
我的变化是针对 7.2。
7.1.4 带来了回归,7.1.3 有效

由于comparator包的变化,这两个例子都失败了,
作为一种解决方法,将"sebastian/comparator": "^2.1",到您的作曲家文件中,它将为您工作。

同时,我将深入研究比较器 3 问题

啊,在我打开页面,消失开会,回来输入我的答案之间 - 新的输入在这里。 刚看到:D

assertEquals 的契约是如果 php 根据 == 将它们视为相等,则断言应该通过? 如果您想与 === 进行严格比较,请改用 assertSame?

确实,至少根据文档;)

这些是字符串:它们将作为字符串进行比较。 ==在类型不匹配时在内部使用。

@sebastianbergmann 根据我自己的知识,为了让每个人都清楚,断言的“预期”结果是什么
$this->assertEquals('+1', '1');$this->assertEquals('0', '0.00');

断言将失败。 您可以使用的正确断言是:

  • $self::assertEquals(+1, '1');
  • $self::assertEquals(+1, 1);
  • $self::assertEquals(0, '0.00');
  • $self::assertEquals('0', 0.00);

如果两者都是字符串,则类型杂耍只是危险的,因为您可能会将错误类型的数据从一层传递到下一层,而测试甚至无法捕获这些数据。

意外的重大变化

这是一个非常重要的错误修正。
是的,这意味着在糟糕的测试中可能存在 BC 中断,但我什至可以考虑将其升级为安全版本,因为您的测试失败并需要调整(请参阅 https://github.com/sebastianbergmann/phpunit/issues/3185# issuecomment-400578650)仍然比没有暴露一个潜伏的错误要好。

注意: self::assertEquals(new Comment('0.0'), new Comment('0.')) (是的,这是最好的例子——更多例子见 https://github.com/sebastianbergmann/comparator/pull/58/files)不能被self::assertSame(new Comment('0.0'), new Comment('0.'))替换。

是的,不是。 也许让我们介绍assertEqualsObjects需要传递 2 个相同类型的对象,并弃用assertEquals以阻止(后来禁止)依赖类型转换?

@sebastianbergmannIsEqual约束如何工作?
文档https://github.com/sebastianbergmann/phpunit/blob/master/src/Framework/Constraint/IsEqual.php#L19不是匹配的实现,我相信这带来了这个话题的混乱

ping @sebastianbergmann ,你能看看这个吗?

最终:是的。 这需要时间(思考和讨论)。

此问题已自动标记为过时,因为它在过去 60 天内没有活动。 如果没有进一步的活动,它将在 7 天后关闭。 感谢你的贡献。

你好,有没有进一步考虑这个? (我主要是评论以保持问题的开放性,因为似乎没有解决方案。)

我们也受到这次严重的公元前中断的影响。 虽然我同意 #58 中的边缘情况很糟糕,应该避免,但我不认为更改assertEquals是正确的举动。 AssertEquals 一直是(对我来说),关于可能包括类型杂耍的松散比较。 如果您知道两个值都是字符串类型,并且您想确保上述边缘情况不会像'0.0' !== '0'那样触发,只需使用assertSame 。 基本上 assertEquals 现在是 assertEquals 和 assertSame 的混合,具体取决于类型,这使得行为根本不明显。

FWIW,要么事情是平等的,要么不是:你需要弥补
你对你的代码是否遵循这个非常基本的原则的看法
与否,因为==肯定不再是合适的等价物
无论如何,根据测试资产中的发现,操作符(或操作码)
这里。

2018 年 10 月 11 日星期四,17:34 Tobias Schultze, notifications@ github.com
写道:

我们也受到这次严重的公元前中断的影响。 虽然我同意边缘
#58 https://github.com/sebastianbergmann/phpunit/issues/58中的案例是
不好,应该避免,我不认为为此更改 assertEquals
是正确的举动。 AssertEquals 一直是(对我来说),关于松散
可能包括类型杂耍的比较。 如果你知道这两个值
是字符串类型,并且您想确保上述边缘情况不会
触发像 '0.0' !== '0',只需使用 assertSame。 基本上 assertEquals
现在是 assertEquals 和 assertSame 的混合,具体取决于类型
使行为根本不明显。


你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/sebastianbergmann/phpunit/issues/3185#issuecomment-429000073
或静音线程
https://github.com/notifications/unsubscribe-auth/AAJakG73OfK6Ki-kh1rPiudasXyFVqc8ks5uj2TzgaJpZM4U3XOz
.

在我们的例子中,我们将 assertEquals 用于货币值(显然表示为字符串)并依赖于忽略尾随零的事实(因为内部表示可能使用更多的小数)。

因此,给我的@Ocramius使用$self::assertEquals(0, '0.00')的解决方法也不起作用,因为您没有将货币表示为浮点数,而是表示为字符串。 所以这两个值总是字符串,但现在 assertEquals 抱怨到处都是不匹配的尾随零。

一个解决方案是提供一个新的断言,忽略以字符串表示的数值的尾随零,这也是@IanVS报告的问题

此问题已自动标记为过时,因为它在过去 60 天内没有活动。 如果没有进一步的活动,它将在 7 天后关闭。 感谢你的贡献。

此问题已自动关闭,因为它自标记为陈旧后就没有活动。 感谢你的贡献。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

AnmSaiful picture AnmSaiful  ·  4评论

keradus picture keradus  ·  4评论

sebastianbergmann picture sebastianbergmann  ·  3评论

stephen-leavitt-sonyatv-com picture stephen-leavitt-sonyatv-com  ·  4评论

sebastianbergmann picture sebastianbergmann  ·  4评论