宝哥软件园

使用PHPUnit进行单元测试并生成代码覆盖率报告的方法

编辑:宝哥软件园 来源:互联网 时间:2021-08-27

安装PHPUnit

使用设计者安装PHPUnit

#查看设计者的全局容器目录将其加入系统小路路径方便后续直接运行安装的命令设计者全局配置bin-dir - absolute#全局安装phpunitcomposer global require-dev phpunit/phpunit #查看版本phpunit -版本使用设计者构建你的项目

我们将新建一个单位项目用于演示单元测试的基本工作流

创建项目结构

创建目录装置激光唱片装置创建目录应用测试报告#结构如下。/应用#存放业务代码报告#存放覆盖率报告测试#存放单元测试使用设计者构建工程

#一路回车即可作曲家初始化#注册命名空间vi composer.json.自动加载: { ' PSR-4 ' : { ' App ' : ' App/',' Tests\': 'tests/' } }.#更新命名空间作曲家转储-自动加载#安装框架组件库composer require-dev phpunit/phpunit到此我们就完成项目框架的构建,下面开始写业务和测试用例。

编写测试用例

创建文件应用程序/示例这里我为节省排版就不写注释了

?phpnamespace App类示例{ private $ msg=' hello world公共函数getTrue(){返回true}公共函数getFalse(){ return false;}公共函数setMsg($ value){ $ this-msg=$ value;} public function getMsg(){ return $ this-msg;}}创建相应的测试文件测试/范例测试。服务器端编程语言(Professional Hypertext Preprocessor的缩写)

?phpnamespace测试;使用PHPUnit 框架测试用例作为BaseTestCase使用App 示例;类示例测试扩展了base testcase { public function testGetTrue(){ $ Example=new Example();$ result=$ example-GetRue();$ this-assertTrue($ result);}公共函数testGetFalse(){ $ Example=新示例();$ result=$ example-getFalse();$ this-assertFalse($ result);}公共函数testGetMsg(){ $ Example=new Example();$ result=$ example-GetRue();//$ result是world not big _ cat $ this-assertekals($ result,' hello big _ cat ');}}执行单元测试

[[电子邮件保护]单元]# PHPUnit-bootstrap=供应商/自动加载。PHP tests/PHPUnit 6。5 .14作者:塞巴斯蒂安博格曼和投稿人.F 3/3 (100%)时间: 61毫秒,内存: 4.00 bthere 1故障:1)测试示例测试33603360 testgetmsgfailed断言“你好,大猫”匹配预期的真值/opt/unit/tests/example TeSt。PHP :27/root/.config/composer/vendor/phpunit/phpunit/src/Textui/command。PHP :195/root/.config/composer/vendor/phpunit/phpunit/src/Textui/command。PHP :148失败!测试: 3,评估: 3,故障: 1。这是一个非常简单的测试用例类,可以看到,执行了共3个测试用例,共3个断言,共一个失败,可以参照PHPUnit手册学习更多高级用法。

代码覆盖率

代码覆盖率反应的是测试用例对测试对象的行,函数/方法,类/特质的访问率是多少(PHP_CodeCoverage尚不支持操作码覆盖率、分支覆盖率及路径覆盖率),虽然有很多人认为过分看重覆盖率是不对的,但我们初入测试还是俗气的追求一下吧。

测试覆盖率的检测对象是我们的业务代码,PHPUnit通过检测我们编写的测试用例调用了哪些函数,哪些类,哪些方法,每一个控制流程是否都执行了一遍来计算覆盖率。

PHPUnit的覆盖率依赖Xdebug,可以生成多种格式:

-覆盖率-三叶草文件生成三叶草XML格式的代码覆盖率报告。- coverage-crap4j文件以Crap4J XML格式生成代码覆盖率报告。生成html格式的代码覆盖率报告。- coverage-php文件将PHP_CodeCoverage对象导出到文件。-覆盖率-文本=文件以文本格式生成代码覆盖率报告。-coverage-XML dir生成phpunit XML格式的代码覆盖率报告。同时,我们需要使用-白名单dir参数来设置我们需要检测覆盖率的业务代码路径。这里有一个具体的操作:

phpunit -bootstrapvendor/autoload . PHP -coverage-html=reports/-白名单app/ tests/#查看覆盖率报告CD reports/PHP-s 0 . 0 . 0 . 033608899

这样,我们对业务代码AppExample做单元测试,得到我们单元测试的代码覆盖率,现在自然是100%,因为我的测试用例已经访问了AppExample的所有方法,如果没有遗漏的话,开发可以体现你测试时业务代码测试程度的完善。

上下文共享测试数据

也许你会发现,我们在每个测试方法中都创建了一个AppExample对象,这在某些场景下是重复的工作。为什么我们不能只创建一次,然后通过其他测试方法访问它?这需要理解PHPUnit执行测试用例的工作流程。

我们不能在不同的测试方法中通过成员属性传递数据,因为每个测试方法都是通过创建一个新的测试类对象,然后调用相应的测试方法来执行的。

也就是说,测试的执行模式不是

testObj=new example test();testObj-testmethod 1();testObj-testmethod 2();但是.

testObj1=新示例test();testobj 1-testmethod 1();testobj 2=new example test();testobj 2-testmethod 2();因此,由testMethod1()修改的属性状态不能传递给testMethod2()。

PHPUnit为我们提供了一个全面的钩子接口:

公共静态函数setup beforeclass()/distandownfafterclass()//在执行测试方法之前调用受保护函数setup()/distandown()//在调用受保护函数AssertConditions()/assertposconditions()/在断言之前/之后运行测试时,每个测试类大致有以下执行步骤

#测试类后台构造setUpBeforeClass #新建一个测试类对象#第一个测试用例setupassertpreception sassertposconditionsserdown #新建一个测试类对象#第二个测试用例setupassertpreconditionsassertposconditiondisterdown.#在测试类的上下文中解构distrownafterclass,这样我们就可以使用setUpBeforeClass创建一个App Example对象作为测试类的静态成员变量(distrownafterclass主要用于一些资源清理,比如关闭文件和数据库连接),然后每个测试方法案例都使用它:

?phpnamespace测试;使用App 示例;使用PHPUnitFrameworkTestCase作为BaseTestCase类示例测试扩展了基本测试用例{//class static property private static $ example;公共静态函数setUpBeforeClass(){ self : $ Example=new Example();} public function testgettrue(){//更新class self :3360 $ example-setmsg(' hello big _ cat ')的静态属性;$ result=self : $ example-GetRue();$ this-assertTrue($ result);}公共函数testGetFalse(){ $ result=self : $ example-getFalse();$ this-assertFalse($ result);}/* * *已执行dependency testGetTrue * @ dependency testGetTrue * @ return[type][description]*/public function testgetmsg(){ $ result=self :3360 $ example-getmsg();$ this-asserteqals($ result,' hello big _ cat ');}}或者使用@depends注释来声明它们的执行顺序,并传递满足要求的参数。

公共函数test method 1(){ $ this-assertTRUe(true);返回"你好";}/* * * @ dependent test method 1 */public function test method 2($ str){ $ this-assertekals(' hello ',$ str);}#执行模式大概如下testObj1=新测试;$ str=TestObj 1-TestMethod 1();testObj2=新测试;test obj 2-test method 2($ str);理解测试执行的模式还是很有帮助的,其他高级特性请浏览官方文档。

使用phpunit.xml编排测试套件

使用测试套件来管理测试,vi phpunit.xml:

?可扩展标记语言版本='1.0 '编码='UTF-8 '?phpunit备份全局变量=' false ' backupstatification属性=' false ' bootstrap=' ./供应商/自动加载。PHP ' colors=' true ' converterstoexceptions=' true ' convertNoticesToExceptions=' true ' convertWarningsToExceptions=' true ' process solution=' false ' stopOnFailure=' false '测试套件!-可以定义多个后缀用于指定待执行的测试类文件后缀测试套件名称='测试'目录后缀='Test.php ' ./test/目录/测试套件/测试套件筛选器白名单来自白名单的processUncoveredFilesFromWhitelist白名单='true '!-可以定义多个对/app .下的业务代码做覆盖率统计-目录后缀='。php ./app/目录/白名单/过滤日志!-覆盖率报告生成类型和输出目录低上限低覆盖率阈值高功率绑定高覆盖率阈值-日志类型='coverage-html' target=' ./reports '低上限=' 35 '高下限=' 70 '/logging/phpunit然后直接运框架行即可:

[[电子邮件保护]单元]# PHPUnit PHPUnit 6。5 .14作者:塞巴斯蒂安博格曼和投稿人。时间: 81毫秒,内存: 4.00兆字节未执行测试!生成超文本标记语言格式的代码覆盖率报告.完成的以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

更多资讯
游戏推荐
更多+