PHPUnit 单元测试入门笔记
为什么要进行单元测试?
项目代码经常修改,往往修改一下地方后,其它地方可能相应地也需要作一些修改,但常常被忽视了,从而经常出现各种小 bug,怎样减少这类错误? 一种是使用强类型,可以发现一些简单的错误;另一个就是使用单元测试,当然返回结果不符合预期时意味着代码可能有 bug .
单元测试需要做什么?
每个公共函数或接口的返回值有固定的数据类型与结构,通过判断结果值是否符合预期来排除一些简单的错误。 运行测试时,希望一条命令运行所有测试代码,可能是跨文件甚至是跨目录。 phpunit 是一个可能实现单元测试常用需要的工具。
单元测试之外的测试:
单元测试不能解决所有问题,单元测试主要测试函数的返回值,而具体页面的呈现是否正确,需要模仿浏览器行为来进行测试,比如php-webdriver,chrome拓展程序等都是可以考虑的方法。
单元测试的覆盖率能不能达到100%?
如果简单粗暴地计算,只要是有测试的函数或方法就是覆盖,那答案是可以。 但每个函数的所有可能都测试到? 这个应该是不可能的,不然,程序就永远不会出 bug 了。 单元测试的目的是减少 bug ,而没有人能保证程序绝对不会有 bug 。
下载与安装:
- 下载各个版本的地址:https://phar.phpunit.de/ 搜索:phpunit-5.
其中php5.6 对应 phpunit5.X 版本
phpuint6.X 要求 php7.0以上
- 在phpunit.phar 同级目录创建一个文件,文件名为:phpunit.bat (windows环境下)
内容为:
@ php %~dp0phpunit-5.7.9.phar %*
然后把该目录添加到环境变量中,安装完成 运行
phpunit -v
测试一下即可
测试单个文件
hahaTest.php 的基本内容可以这样写:
<?php
use PHPUnit\Framework\TestCase;
require("./src/index.php");
class hahaTest extends TestCase{
//必须是public且方法名是test开头的才会参与测试,protected和private的测试时会提示错误
public function test_index(){
$index=new index();//index.php中的类
$re=$index->haha();
$this->assertEquals(1,$re);//测试 ./src/index.php 中的index类的haha方法返回值是不是1
}
}
命令行运行:
phpunit hahaTest.php
测试整个文件夹的方法:
- 递归读取文件夹下所有的文件命名为 *Test.php,如果文件名不是Test.php结尾的,不会加载到测试
- 每个方法必须以test开关,否则会直接跳过
- 方法的权限必须是 public
- 运行 phpunit 目录名,即可
phpunit 中依赖 (@depends) 的使用:
- depends 的使用:
/** //必须是文档注释,不能自动生成文档注释的要注意一下:第一行一定要两个*号
* @depends test_haha 提供数据的函数的返回值作为参数
*/
public function test_hehe($re){
//$re 是 test_haha 的返回值,可以在这个方法内使用
}
-
最好先创建一个基类:baseTest继承自 TestCase类,文件名为aaTest.php,写aa是保证让它最先被加载,加Test是因为不加的不会被加载运行。 aaTest.php 文件中可以写公共函数,需要公共引进的,一些前置的操作,然后其它测试类继承这个类就可以了
-
另一种解决方案: 使用 phpunit.xml 文件,把启动需要的内容写到 base.php 文件,然后在 phpunit 的 bootstrap 属于中引入该文件 执行 phpunit dir 时,如果没有添加 -c phpunit.xml 的话,它会自动在当前目录下查找phpunit.xml或phpunit.xml.dist文件,通过配制文件,可以指定加载顺序 在配置中引入了的文件会优先加载,然后会默认加载*Test.php文件
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./Index/baseTest.php">
<testsuites>
<testsuite name="index">
<file>./Index/loginTest.php</file> //写了的会优先加载
</testsuite>
</testsuites>
</phpunit>
- phpunit.xml 的配置:https://phpunit.readthedocs.io/zh_CN/latest/configuration.html#appendixes-configuration
问题
- 怎样指定测试文件的顺序?
<!-- 使用 phpunit.xml 配置文件,写在testsuite 中的会优先加载,并且按写的顺序加载 -->
- 跨文件/跨类 怎样使用@depends
<!-- 目前的解决方法:继承需要依赖的类,再重写需要依赖的方法,直接通过parent:: 来调用,这样就可以使用 @depends 了 补充:这样会有问题,继承其它测试类,会没被继承的方法重复测试, 经测试后发现,直接使用 类名::方法名 是可以添加到依赖的 -->
- 怎样知道哪些测试方法被 phpunit 跳过了?
<!-- 运行时,添加 -v 参数,如: phpunit index -v -->