InfoQ Geekathon 大模型技术应用创新大赛 了解详情
写点什么

如何提高 PHP 代码的质量?第三部分 端到端 / 集成测试

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

    阅读完需:约 10 分钟

如何提高PHP代码的质量?第三部分 端到端/集成测试

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


在本系列的最后一部分,是时候设置端到端/集成测试环境,并确保我们已经准备好检查我们工作的质量。


在本系列的前几部分中,我们建立了一个构建工具,一些静态代码分析器,并开始编写单元测试。


为了使我们的测试堆栈更完整,有一些测试可以检查你的代码是否在真实环境中运行,以及它是否能在更复杂的业务场景中运行良好。


在这里,我们可以使用为行为驱动开发构建的工具——官方 PHP 的 Cucumber 实现——Behat。我们可以通过运行以下代码来安装它:


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


增加一个目标到 build.xml(在本文的第一部分中描述了 Phing 设置)


<target name="behat">   <exec executable="bin/behat" passthru="true" checkreturn="true"/></target><target name="run" depends="phpcs,phpcpd,phan,phpspec,behat"/>
复制代码


然后,你应该为文件 features/price.feature 的测试创建一个规范。


Feature: Price Comparison  In order to compare prices  As a customer  I need to break the currency barrier   Scenario: Compare EUR and PLN    Given I use nbp.pl comparator    When I compare “100EUR” and “100PLN”    Then It should return some result
复制代码


这个测试场景非常容易阅读,并且应该给你一个关于该特性应该如何工作的良好印象。不幸的是,计算机通常并不真正理解人类语言,所以现在是为每一步编写代码的时候了。


你可以通过运行 ./bin/behat-init 来生成它的代码模板。它应该会创建一个这样的类:


//features/bootstrap/FeatureContext.php
use Behat\Behat\Context\SnippetAcceptingContext;use Behat\Gherkin\Node\PyStringNode;use Behat\Gherkin\Node\TableNode;class FeatureContext implements SnippetAcceptingContext{ /** * Initializes context. */ public function __construct() { }}
复制代码


然后你可以执行:


$ bin/behat --dry-run --append-snippets
复制代码


Behat 将自动为场景中定义的每个步骤创建函数。


现在你可以通过填充函数的主体来开始实现真正的检查:


// features/bootstrap/FeatureContext.php
<?phpuse Behat\Behat\Context\Context;use Domain\Price;use Domain\PriceComparator;use Infrastructure\NBPPriceConverter;
/*** Defines application features from the specific context.*/class FeatureContext implements Context{ /** @var PriceComparator */ private $priceComparator; /** @var int */ private $result; /** * Initializes context. * * Every scenario gets its own context instance. * You can also pass arbitrary arguments to the * context constructor through behat.yml. */ public function __construct() { }
/** * @Given I use nbp.pl comparator */ public function iUseNbpPlComparator() { $this->priceComparator = new PriceComparator(new NBPPriceConverter()); }
/** * @When I compare :price1 and :price2 */ public function iCompareAnd($price1, $price2) { preg_match('/(\d+)([A-Z]+)/', $price1, $match1); preg_match('/(\d+)([A-Z]+)/', $price2, $match2); $price1 = new Price($match1[1], $match1[2]); $price2 = new Price($match2[1], $match2[2]); $this->result = $this->priceComparator->compare($price1, $price2); }
/** * @Then It should return some result */ public function itShouldReturnSomeResult() { if (!is_int($this->result)) { throw new \DomainException('Returned value is not integer'); } }}
复制代码


最后,使用 ./bin/phing 运行所有的测试。你应该得到以下结果:


Buildfile: /home/maciej/workspace/php-testing/build.xmlMyProject > phpcs:
MyProject > phpcpd:
phpcpd 4.0.0 by Sebastian Bergmann.0.00% duplicated lines out of 103 total lines of code.
Time: 17 ms, Memory: 4.00MB
MyProject > phan:
MyProject > phpspec:
/ skipped: 0% / pending: 0% / passed: 100% / failed: 0% / broken: 0% / 3 examples2 specs3 examples (3 passed)15ms
MyProject > behat:
Feature: Price Comparison In order to compare prices As a customer I need to break the currency barrier
Scenario: Compare EUR and PLN # features/price.feature:6 Given I use nbp.pl comparator # FeatureContext::iUseNbpPlComparator() When I compare "100EUR" and "100PLN" # FeatureContext::iCompareAnd() Then It should return some result # FeatureContext::itShouldReturnSomeResult()1 scenario (1 passed)3 steps (3 passed)0m0.01s (9.13Mb)
MyProject > run:
BUILD FINISHED
Total time: 1.1000 second
复制代码


正如你所看到的,Behat 准备了一份很好的报告,说明我们的应用程序做了什么,结果是什么。下一次,当项目经理询问你在测试中涉及到哪些场景时,你可以给他一个 Behat 输出!

1 测试的结构

每个测试都包括:


  • 对该场景的一些准备,用“Given”部分表示

  • “When”部分所涵盖的一些动作

  • 一些检查被标记为“Then”部分


每个部分都可以包含多个与“And”关键字连接的步骤:


Scenario: Compare EUR and PLN    Given nbp.pl comparator is available    And I use nbp.pl comparator    When I compare "100EUR" and "100PLN"    And I save the result    Then It should return some result    And the first amount should be greater
复制代码

2 上下文

Behat 允许你为你的测试定义多个上下文。这意味着你可以将步骤代码分割成多个类,并从不同的角度去测试你的场景。


你可以例如:为 web 上下文编写代码,它将使用你的应用程序 HTTP 控制器运行你的测试步骤。你还可以创建“domain”上下文,它将只使用 PHP API 调用来运行你的业务逻辑。通过这种方式,你可以单独地测试业务逻辑集成,从端到端应用程序测试。


关于如何在 Behat 建立许多上下文的更多信息,请参考http://behat.org/en/latest/userguide/context.html的文档。

3 我是如何使用 Behat 的?

正如一开始所提到的,你可以使用 Behat 进行集成测试。通常情况下,你的代码依赖于一些外部的第三方系统。当我们在第 2 部分中编写单元测试时,我们总是假设外部依赖关系像预期的那样工作。使用 Behat,你可以编写测试场景,它将自动运行你的代码,并检查它是否正确地使用真实场景的服务。


最重要的是,Behat 对于测试系统使用的复杂的端到端场景非常有用。它允许你隐藏在一个可读性的名字后面运行测试步骤所需的复杂代码,并编写一个人人都能理解的场景。

总结

从以上的文章中,你已经学习了如何在你的项目中设置六个有用的工具:


  • PHing 用于运行你的构建

  • PHPCS 用于自动检查代码格式

  • PHPCPD 用于检测重复代码的

  • Phan 用于高级静态代码分析

  • PHPSpec 用于单元测试

  • Behat 用于端到端和集成测试


现在,你可以向 git 提交钩子添加 ./bin/phing,并设置持续集成来运行每个提交的测试。


是不是突然之间,没有什么能阻止你写出高质量的 PHP 代码!


Well done!


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


原文链接:


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


活动推荐:

2023年9月3-5日,「QCon全球软件开发大会·北京站」 将在北京•富力万丽酒店举办。此次大会以「启航·AIGC软件工程变革」为主题,策划了大前端融合提效、大模型应用落地、面向 AI 的存储、AIGC 浪潮下的研发效能提升、LLMOps、异构算力、微服务架构治理、业务安全技术、构建未来软件的编程语言、FinOps 等近30个精彩专题。咨询购票可联系票务经理 18514549229(微信同手机号)。

2019-11-21 23:462726

评论

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

Spring 实战:自定义 Filter 优雅获取请求参数和响应结果

看山

Spring实战

如果你不知道从哪本书开始阅读,那就从这本开始吧

小天同学

读书 好书推荐 读后感 4月日更

认识流媒体协议,从RTSP协议解析开始!

明儿

c c++ 协议 Wireshark rtp

【一定要看哦】转瞬之间的成长,传播知识的梦想(赠予极客邦【1周年】)

洛神灬殇

程序人生 1 周年盛典 InfoQ 写作平台 1 周年 InfoQ 的朋友们

WebAssembly + Dapr = 下一代云原生运行时?

阿里巴巴云原生

云计算 容器 开发者 运维 云原生

关于企业数字化转型的一些思考

石云升

数字化转型 28天写作 4月日更

你必须明白的新生代垃圾回收:YoungGC

小Q

Java 架构 面试 JVM GC

shell的三种循环

做个人吧

菩萨心肠 霹雳手段|靠谱点评

无量靠谱

精选8道Java集合最常见面试题,进大厂99%都会被问到,限时送!

飞飞JAva

JAVA集合

Dubbo 注册中心

青年IT男

dubbo

漫游语音识别技术——带你走进语音识别技术的世界

攻城先森

深度学习 学习 音视频 nlp 语音识别

写作平台一周年-感谢曾经的自己

数据社

InfoQ 写作平台 1 周年 人气作者 TOP10

弱网下的极限实时视频通信

疯狂的驸马

音视频 编码 极限视频通信

大数据技术发展的过程

菜菜

太简单了!这套java内部类和异常的总结,只学了2个小时就学会了

牛哄哄的java大师

Java

seata-golang 一周年回顾

阿里巴巴云原生

Java 数据库 微服务 云原生 Go 语言

不想搞Java了,现在Java面试为何这么难

Java架构师迁哥

“Windows找不到文件...”,怎么处理?

Emotion

Windows 10 系统 找不到系统文件 错误弹窗 windows找不到文件

技术向上,雪坡向下:拼多多的“新帅”与新路

脑极体

【翻译】JVM-技术专题-ZGC学习手册(1)概念定义

洛神灬殇

翻译 ZGC JVM 基本概念

接纳不完美的自己,才能拥有完整的人生|靠谱点评

无量靠谱

资源数据治理的应用实践

鲸品堂

数据 治理 运营商

这份清华学霸的Java反射完整版学习笔记,2小时带你从入门到入土

飞飞JAva

数据人上班划水都聊什么

数据社

大数据 程序员

002 ES NGram 分词 + suggest

小林-1025

ES es7

话题讨论|三大运营商Q1业绩大增,5G开始收割?

程序员架构进阶

5G 话题讨论 28天写作 4月日更 通信运营商

奋力前行,感谢有你

IT蜗壳-Tango

IT蜗壳 人气作者 TOP10

谈Android端的高音质和低延时音频编码

Changing Lin

音视频 4月日更

笔记分享--弱网下的极限实时视频通信

攻城先森

音视频 端到端 #弱网 极限视频通信

弱网下的极限视频通信学习感悟!

txp

音视频

  • 扫码添加小助手
    领取最新资料包
如何提高PHP代码的质量?第三部分 端到端/集成测试_文化 & 方法_360云计算_InfoQ精选文章