核心要点
- PHPUnit 将 PHP 原生的错误处理转换为异常,这可能会改变测试期间代码执行的流程。这在测试使用
trigger_error()
函数的代码时可能会导致问题。 - PHPUnit 将错误转换为异常,这会导致代码在开发和测试中的行为与生产环境中的行为有所不同。这是因为遇到错误时执行流程发生了变化。
- 为了准确测试使用
trigger_error()
的代码,可以使用自定义错误处理程序来捕获错误信息,以便稍后使用断言进行分析。这允许代码继续执行,同时仍然允许检查引发的错误条件。 - 了解 PHPUnit 的默认行为对于准确测试至关重要。在需要执行触发错误后逻辑的情况下,补充 PHPUnit 的功能可以促进在尽可能接近生产环境的条件下进行准确测试。
假设您正在维护使用 PHP 原生 trigger_error()
函数记录错误信息的代码。同时,您正在使用 PHPUnit 为该代码编写单元测试。如果您参考 PHPUnit 手册,有一节内容专门介绍如何测试错误条件。它描述了 PHPUnit 如何实现自己的错误处理程序,该处理程序将错误、警告和通知转换为异常,并且捕获这些异常是您应该如何处理此类错误测试的方法。但是,根据您的代码外观,您可能会遇到 PHPUnit 的这种方法的问题。本文将详细说明这个问题是什么,它如何影响您测试代码的能力,以及如何解决它。
问题是什么?
错误和异常的行为方式根本不同。与本文特别相关的是,如果传递给它的错误级别常量不表示致命错误,则代码执行可以在 trigger_error()
之后立即继续。当抛出异常时,执行将在找到与该异常类对应的 catch
块的开头继续,这可能在抛出异常的点之后立即发生,也可能不会。让我们来看一些这些行为的示例。首先是错误。
<?php error_reporting(E_ALL | E_STRICT); echo "Before warning\n"; trigger_error("Danger Will Robinson!", E_USER_WARNING); echo "After warning\n"; ?>
如果您运行上述代码,您将获得以下输出:
<code>Before warning PHP Warning: Danger Will Robinson! in /home/matt/error_handler.php on line 4 After warning</code>
由此可见,trigger_error()
调用后的 echo
语句已执行。现在,异常。
<?php try { echo "Before exception\n"; throw new Exception("Danger Will Robinson!"); echo "After exception\n"; } catch (Exception $e) { echo "In catch block\n"; } ?>
输出:
<code>Before exception In catch block</code>
与错误示例相反,抛出异常后的代码未执行。因为 PHPUnit 将错误转换为异常,所以错误在单元测试中的行为与异常相同。在测试期间,任何在触发错误后执行的代码都不会执行。再举一个例子:
<?php function foo($param) { if (is_string($param)) { trigger_error(__FUNCTION__ . " no longer supports strings, pass an array", E_USER_NOTICE); } // do useful stuff with $param ... } ?>
通过错误到异常的转换,无法测试是否对 $param
进行了有用的处理,因为当错误转换为异常时,该代码将永远不会执行。
PHPUnit 行为的副作用
这种错误到异常的转换会导致代码在开发和测试中的行为与在生产环境中的行为有所不同。这是一个例子:
<?php error_reporting(E_ALL | E_STRICT); echo "Before warning\n"; trigger_error("Danger Will Robinson!", E_USER_WARNING); echo "After warning\n"; ?>
输出:
<code>Before warning PHP Warning: Danger Will Robinson! in /home/matt/error_handler.php on line 4 After warning</code>
第一个 var_dump()
调用(在此期间,将错误转换为异常的自定义错误处理程序正在生效)输出 NULL。第二个 var_dump()
调用(在此期间,PHP 的默认错误处理程序正在生效)输出有关已触发错误的信息。请注意,这不是因为使用了自定义错误处理程序而导致第一个 var_dump()
调用输出 NULL,而是因为该错误处理程序抛出了异常。如果此示例中显示的错误处理程序没有这样做,则第一个 var_dump()
调用的输出将与第二个相同。
解决方案
我们需要一个解决方案,该解决方案允许继续执行正在测试的代码,同时仍然允许我们检查是否引发了错误条件。如上面的示例所示,允许代码执行继续可以使用不将错误转换为异常的自定义错误处理程序来完成。此错误处理程序应该做的是捕获错误信息,以便稍后使用断言进行分析。这就是它的样子:
<?php try { echo "Before exception\n"; throw new Exception("Danger Will Robinson!"); echo "After exception\n"; } catch (Exception $e) { echo "In catch block\n"; } ?>
setUp()
(在每个测试方法之前运行)处理设置错误处理程序,该处理程序只是同一类中的另一个方法,该方法将有关每个错误的信息存储在一个数组中。然后,其他方法(如 assertError()
)由测试方法(如 testDoStuff()
)使用,以对该错误信息执行断言并输出相关的调试信息,例如与预期错误相比触发的错误是什么。其他有用的断言类型包括逻辑反转(即断言未触发特定错误)、检查消息与正则表达式匹配的错误或检查触发的错误数量。
结论
如果您不关心测试触发错误后的逻辑是否仍在执行,则 PHPUnit 的默认行为完全适合您的需求。但是,重要的是您要了解该行为的含义。如果您确实关心此类逻辑的执行,同样重要的是您要知道如何补充 PHPUnit 的功能,以便在尽可能接近生产环境的条件下促进对代码的准确测试。
图片来自 Fotolia
(以下为FAQ,已根据原文内容调整格式和表达,并对部分问题进行了合并或简化)
关于使用 PHPUnit 测试错误条件的常见问题解答 (FAQ)
Q1: 为什么 PHPUnit 在控制台中没有显示任何错误?
PHPUnit 的设计方式允许有效测试错误和异常。如果您在控制台中没有看到任何错误,则 PHPUnit 可能正在捕获它们并将它们视为失败的测试。要查看这些错误的详细信息,可以在运行测试时使用 --debug
选项。这将提供更详细的输出,包括在测试期间捕获的任何错误或异常。
Q2: 如何断言 PHPUnit 中抛出了异常?
PHPUnit 提供了一组专门用于处理异常的断言。最常用的是 expectException()
,您可以使用它来指定您期望抛出的异常类型。如果在测试期间抛出了指定的异常,则测试将通过。如果没有,则测试将失败。这允许您编写专门检查错误条件的正确处理的测试。
Q3: PHP 中的错误报告是如何工作的?
PHP 的错误报告功能允许您控制报告哪些错误以及如何处理它们。默认情况下,所有错误都会被报告并显示。但是,您可以使用 error_reporting()
函数和 display_errors
ini 指令更改这些设置。这允许您隐藏某些类型的错误,或记录错误而不是显示它们。
Q4: 如何在 PHPUnit 中测试异常?
与Q2相同。
Q5: 如何为 PHPUnit 编写测试?
为 PHPUnit 编写测试涉及创建一个新的测试用例类,该类扩展 PHPUnitFrameworkTestCase 类。每个测试都是此类中的一个公共方法,以单词“test”开头。在每个测试方法内部,您可以使用 PHPUnit 的断言来检查您的代码是否按预期运行。例如,您可以使用 assertEquals()
方法来检查函数是否返回预期的结果。
Q6: 如何在 PHPUnit 中处理错误?
PHPUnit 提供了一组专门用于处理错误的断言。最常用的是 expectError()
,您可以使用它来指定您期望触发的错误类型。如果在测试期间触发了指定的错误,则测试将通过。如果没有,则测试将失败。这允许您编写专门检查错误条件的正确处理的测试。
Q7: 如何调试 PHPUnit 中的测试?
PHPUnit 提供了几个调试测试的选项。--debug
选项提供更详细的输出,包括在测试期间捕获的任何错误或异常。--stop-on-error
、--stop-on-failure
和 --stop-on-risky
选项可用于在遇到某种类型的错误时停止测试运行。这可以使识别和修复问题更容易。
Q8: 如何在 PHPUnit 中测试错误条件?
PHPUnit 提供了几种测试错误条件的方法。expectError()
方法允许您指定您期望触发的错误类型。expectWarning()
方法允许您指定您期望触发的警告类型。如果在测试期间触发了指定的错误或警告,则测试将通过。如果没有,则测试将失败。
Q9: 如何在 PHPUnit 中处理警告?
PHPUnit 提供了一组专门用于处理警告的断言。最常用的是 expectWarning()
,您可以使用它来指定您期望触发的警告类型。如果在测试期间触发了指定的警告,则测试将通过。如果没有,则测试将失败。这允许您编写专门检查警告条件的正确处理的测试。
Q10: 如何在 PHPUnit 中使用数据提供程序?
数据提供程序是 PHPUnit 的一个强大功能,允许您使用不同的数据集多次运行测试。要使用数据提供程序,您可以创建一个返回数组的数组的方法。每个内部数组都是测试的一组参数。然后,您使用 @dataProvider
注释您的测试方法,后跟您的数据提供程序方法的名称。然后,PHPUnit 将为每一组参数运行一次测试,并将参数传递给测试方法。
以上是PHP主|使用Phpunit测试错误条件的详细内容。更多信息请关注PHP中文网其他相关文章!

PHP仍然流行的原因是其易用性、灵活性和强大的生态系统。1)易用性和简单语法使其成为初学者的首选。2)与web开发紧密结合,处理HTTP请求和数据库交互出色。3)庞大的生态系统提供了丰富的工具和库。4)活跃的社区和开源性质使其适应新需求和技术趋势。

PHP和Python都是高层次的编程语言,广泛应用于Web开发、数据处理和自动化任务。1.PHP常用于构建动态网站和内容管理系统,而Python常用于构建Web框架和数据科学。2.PHP使用echo输出内容,Python使用print。3.两者都支持面向对象编程,但语法和关键字不同。4.PHP支持弱类型转换,Python则更严格。5.PHP性能优化包括使用OPcache和异步编程,Python则使用cProfile和异步编程。

PHP主要是过程式编程,但也支持面向对象编程(OOP);Python支持多种范式,包括OOP、函数式和过程式编程。PHP适合web开发,Python适用于多种应用,如数据分析和机器学习。

PHP起源于1994年,由RasmusLerdorf开发,最初用于跟踪网站访问者,逐渐演变为服务器端脚本语言,广泛应用于网页开发。Python由GuidovanRossum于1980年代末开发,1991年首次发布,强调代码可读性和简洁性,适用于科学计算、数据分析等领域。

PHP适合网页开发和快速原型开发,Python适用于数据科学和机器学习。1.PHP用于动态网页开发,语法简单,适合快速开发。2.Python语法简洁,适用于多领域,库生态系统强大。

PHP在现代化进程中仍然重要,因为它支持大量网站和应用,并通过框架适应开发需求。1.PHP7提升了性能并引入了新功能。2.现代框架如Laravel、Symfony和CodeIgniter简化开发,提高代码质量。3.性能优化和最佳实践进一步提升应用效率。

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP类型提示提升代码质量和可读性。1)标量类型提示:自PHP7.0起,允许在函数参数中指定基本数据类型,如int、float等。2)返回类型提示:确保函数返回值类型的一致性。3)联合类型提示:自PHP8.0起,允许在函数参数或返回值中指定多个类型。4)可空类型提示:允许包含null值,处理可能返回空值的函数。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

Atom编辑器mac版下载
最流行的的开源编辑器

SublimeText3 Linux新版
SublimeText3 Linux最新版

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

禅工作室 13.0.1
功能强大的PHP集成开发环境

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。