AI 年度盘点与2025发展趋势展望,50+案例解析亮相AICon 了解详情
写点什么

如何提高 PHP 代码的质量?第二部分 单元测试

  • 2019-11-21
  • 本文字数:3076 字

    阅读完需:约 10 分钟

如何提高PHP代码的质量?第二部分 单元测试

说实话,在代码质量方面,PHP 的压力非常大。通过阅读本系列文章,您将了解如何提高 PHP 代码的质量。


在“如何提高 PHP 代码的质量?”的前一部分中,我们设置了一些自动化工具来自动检查我们的代码。这很有帮助,但关于我们的代码如何满足业务需求并没有给我们留下任何印象。我们现在需要创建特定代码域的测试。

1 单元测试

最常见的测试软件的方法可能是编写单元测试。它们的目的是测试代码的特定单元,基于这样的假设:一切都按预期运行。为了能够编写适当的单元测试,我们的代码应该遵循一些基本的设计规则。我们应该特别关注 SOLID 原则。


  • 通过实现单一责任原则(我们的代码应该只关注功能的单个部分),我们将确保在测试期间,我们只会同时关注项目的一小部分

  • 通过使用 Liskov 替换原则和依赖倒置原则,我们的代码不会关心我们是否注入模拟依赖关系,只要它们实现了适当的接口


在单元测试中,我们确实希望用模拟对象替换所有依赖的服务,因此我们一次只测试一个类。但模拟是什么?它们是实现与其他对象相同的接口的对象,但它们的行为是受控的。例如,假设我们在创建一个价格比较服务,我们利用另一个服务来获取当前的汇率。在测试我们的比较器时,我们可以使用一个模拟对象来为特定的货币返回特定的汇率,因此我们的测试既不依赖也不调用真正的服务。

2 应该使用哪个框架?

有几个好的框架可以达到这个目的。最常见的可能是 PHPUnit。在我的工作中,我发现使用行为方法来编写测试会带来更好的结果,并使我更急切地编写测试。对于我们的项目,我们选择 phpspec。


安装过程相当简单 - 只需使用:


$ php composer.phar require --dev phpspec/phpspec
复制代码


然后,如果你在本文的第一部分中配置了 PHing,那么你可以在 build.xml 中添加构建目标:


<target name="phpspec">    <exec executable="bin/phpspec" passthru="true" checkreturn="true">        <arg line="run --format=pretty"/>    </exec></target>...<target name="run" depends="phpcs,phpcpd,phan,phpspec"/>
复制代码


然后,你必须为你想要测试的每个服务类创建一个测试类。让 PHPSpec 非常容易使用的是模型创建。你只需使用严格的输入,就可以将模拟对象声明为测试函数的参数。PHPSpec 会自动为你创建模拟。让我们看一下代码示例:


// spec/Domain/PriceComparatorSpec.php<?phpnamespace spec\Domain;use Domain\Price;use Domain\PriceConverter;use PhpSpec\ObjectBehavior;class PriceComparatorSpec extends ObjectBehavior{    public function let(PriceConverter $converter)    {        $this->beConstructedWith($converter);    }
public function it_should_return_equal() { $price1 = new Price(100, 'EUR'); $price2 = new Price(100, 'EUR'); $this->compare($price1, $price2)->shouldReturn(0); }
public function it_should_convert_first(PriceConverter $converter) { $price1 = new Price(100, 'EUR'); $price2 = new Price(100, 'PLN'); $priceConverted = new Price(25, 'EUR'); $converter->convert($price2, 'EUR')->willReturn($priceConverted); $this->compare($price1, $price2)->shouldReturn(1); }}
复制代码


这里有三个函数:


  • let( ) - 它允许使用依赖来初始化服务

  • 两个 it_* 函数实现测试。其中一种方法是使用模拟 $priceConverter 的方法实现 priceConverter 接口,该接口被注入到测试对象的创建中。


你可以看到创建模拟非常容易。你所需要做的就是将它定义为测试函数的参数,并通过指定在执行代码时应该运行哪些函数来配置 mock。如果需要,你还可以设置返回值。


所有测试的方法都是从 $this 上下文中运行的,你可以使用与模拟相同的语法来轻松地检查它们的结果。

3 如何设置测试?

Phpspec 有一个很好的文档,但是我将尝试向你展示一些在日常实践中有用的基本用例。

构建测试对象

一般来说,设置测试对象的最简单方法是调用 $this->beConstructedWith(…)方法,该方法将所有应该传递给对象构造函数的 params 作为参数。


如果你的对象应该使用工厂方法来创建,那么你可以使用methodName,$argumentsArray)方法。

在模拟中匹配运行时参数

你会发现 phpspec 使用一种非常类似于人类的语法来配置模拟。例如,如果你想要检查在运行时是否有一个模拟方法 someMethod 与参数“desired value”被调用,你可以在测试中定义它,如下面的例子:


$mockObject->someMethod("desired value")->shouldBeCalled();
复制代码


如果你想要测试代码的行为,当一些 mock 的函数返回“some value”时,你可以通过调用来轻松地设置它:


$mockObject->someFunction("some input")->willReturn("some value");
复制代码


有时我们并不真正关心传递给 mock 的确切参数。然后可以写这段代码:


use Prophecy\Argument\Token\AnyValueToken;...$mockObject->someFunction(new AnyValueToken())->willReturn(true);
复制代码


有时你会关心一些参数,最好是写一个检查函数,它会告诉你是否正确地调用了一些方法,例如:


use Prophecy\Argument\Token\CallbackToken;...$checker = function (Message $message) use ($to, $text) {   return $message->to === $to && $message->text === $text;};$msgSender->send(new CallbackToken($messageChecker))->shouldBeCalled()
复制代码

匹配运行时异常

。在某些情况下,异常是代码接口的一部分。你希望它们在特定的场景被抛出。你可以通过编写以下代码来完成这项工作:


$this->shouldThrow(\DomainException::class)->during('execute', [$command, $responder]);
复制代码


传给 during()的第一个参数是将要调用的方法的名称,第二个参数是将传递给我们的方法的参数数组。

5 在哪里可以找到更多的例子?

在本文中,我们只介绍了一些基本的用例。请参考 phpspec 的文档,以找到更多的示例,这些示例将使你的测试代码变得漂亮!


代码覆盖率


PHPSpec 附带了扩展子系统,它允许例如创建代码覆盖率报告。如果您想要检查在测试中执行了多少代码,它们是很有帮助的。


你可以通过以下来安装这个扩展:


$ php composer.phar require --dev leanphp/phpspec-code-coverage
复制代码


然后通过创建 phpspec 来启用它。yml 文件内容:


extensions:  LeanPHP\PhpSpec\CodeCoverage\CodeCoverageExtension: ~
复制代码


默认情况下,这个扩展会使用 PHP 的 Xdebug 扩展生成代码覆盖率信息,但是 PHP 的本机调试器 - phpdbg 会更快速一些:


$ phpdbg -qrr phpspec run
复制代码


现在,你可以在 build 中更改 phpspec 的构建目标。xml:


<target name="phpspec">    <exec executable="phpdbg" passthru="true" checkreturn="true">        <arg line="-qrr bin/phpspec run --format=pretty"/>    </exec></target>...<target name="run" depends="phpcs,phpcpd,phan,phpspec"/>
复制代码


报告在覆盖率/目录中生成,作为漂亮的 HTML 页面,可以浏览以检查测试覆盖率。


6 应该什么时候写单元测试?

答案是……尽可能多的!它们运行得非常快,它们可能是目前最简单的检查代码的方法。这是一种最好的方法,它可以让你花几个小时不花在手工测试上,相反,它是在几秒钟内完成的。单元测试在非编译代码中特别有用,比如 PHP。它们有助于捕获在运行时只会出现的问题。


编写测试还可以帮助您编写更有组织的代码。考虑测试?创建一个可测试的代码结构。

总结

现在是时候拿起你的键盘,为你的项目写一些测试,对你的代码充满信心了!


本文转载自公众号 360 云计算(ID:hulktalk)。


原文链接:


https://mp.weixin.qq.com/s/Nt5YrVGNXVNA84zjclEEwg


2019-11-21 23:463860

评论

发布
暂无评论
发现更多内容

开发运营级海外语聊APP源码需要考虑哪些?借鉴Falla、WePlay、YoHo

山东布谷科技胡月

海外语聊APP 语聊APP开发 语音聊天室APP 语聊源码 语聊平台搭建

一文带你玩转全新采集配置 CRD:AliyunPipelineConfig

阿里巴巴云原生

阿里云 云原生 iLogtail

Koupleless 可演进架构的设计与实践|当我们谈降本时,我们谈些什么

SOFAStack

开源 微服务 应用 架构治理 应用构建

如何快速集成京东商品详情API

技术冰糖葫芦

api 货币化 API 接口 API 文档 API 测试

Keka for Mac(压缩解压工具) 1.3.6中文版

Mac相关知识分享

文件压缩软件

Cisdem PDFMaster for mac(专业PDF编辑转换器)v6.5.0激活版

Mac相关知识分享

PDF转换器

首届中文NL2SQL挑战赛亚军比赛攻略_BugCreater

阿里云天池

企业级敏捷框架:业务驱动型敏捷与产品需求团队

俞凡

团队管理 敏捷

VMware Fusion Pro 13密钥 for Mac(VM虚拟机)v13.5.2中文版

Rose

Native Instruments Komplete Kontrol for mac(音源制作软件)

Mac相关知识分享

Mac软件 音乐制作软件

深度解读KubeEdge架构设计与边缘AI实践探索

EquatorCoco

人工智能 边缘AI

Earth 3D for Mac(3D地球模拟软件)v8.1.3免激活版

Mac相关知识分享

数据飞轮驱动消费行业变革,火山引擎数智平台助力门店数智化转型

字节跳动数据平台

数字化转型 云服务 数据平台 火山引擎 数据飞轮

TeleVis:基于 NLP 的新闻舆情可视化项目

阿里云天池

美年健康AI算法大赛--季军解决方案

阿里云天池

FSNotes for mac(文本处理软件)v6.9.0中文免激活版

Mac相关知识分享

EdgeView 4 for Mac(快速图像查看器) v4.7.8激活版

Mac相关知识分享

虾皮商品数据接口全解析:高效采集,精准运营新利器

tbapi

shopee API shopee商品详情接口 shopee商品详情数据采集

汇聚行业实践,树立应用典范——《Serverless应用实践案例集》重磅发布

华为云PaaS服务小智

Serverless 华为云

1688商品详情API返回值:商品库存管理的智能化

技术冰糖葫芦

api 货币化 API 接口 API 文档 API 测试

被怼了:acks=all消息也会丢失?

王磊

Java

OpenAI 重大人事变动,联创加入死敌;阿里视频框架 Tora 操控物体运动轨迹丨 RTE 开发者日报

声网

FashionAI比赛-服饰属性标签识别比赛赛后总结(来自 Top14 Team)

阿里云天池

知识管理:最适合千人团队的8大知识库软件

爱吃小舅的鱼

知识管理 知识库 知识管理系统 知识管理软件 知识库工具

Mac硬盘检测:SMART Utility for mac 激活版

你的猪会飞吗

mac软件下载 mac破解软件下载

音频采样器Native Instruments Kontakt 7破解版安装包 Mac/win

Rose

鸿蒙智行享界S9发布上市|小艺一语直达奢享空间

Geek_2d6073

ppt目录页怎么做?2款自动生成PPT目录的AI工具推荐!

彭宏豪95

效率工具 职场 PPT 办公软件 AI生成PPT

盐城销量比赛 -- YR Tech团队比赛攻略

阿里云天池

OpenAI 收购 Rockset:大模型如何使用 OLAP 赋能实时洞察业务场景

腾讯云大数据

大模型 rag

Omnissa Horizon 8 2406 (8.13) 发布下载 - 虚拟桌面基础架构 (VDI) 和应用软件

sysin

vSphere vmware esxi horizon

如何提高PHP代码的质量?第二部分 单元测试_文化 & 方法_360云计算_InfoQ精选文章