Skip to content

Commit 4ed68c6

Browse files
committed
docs: phpunit.xml说明
1 parent 3ea4800 commit 4ed68c6

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
## 25. 2019-06-17-Laravel 单元测试 phpunit.xml 目录结构及测试编排文件说明
2+
3+
### 目录结构
4+
Laravel 框架基于 PHPUnit 提供了开箱即用的测试功能,对代码测试的支持非常有好:
5+
6+
Laravel PHPUnit 测试
7+
8+
以 Laravel 5.8 为例,在框架初始化过程中通过 Composer 安装了 PHPUnit 7(也可以手动升级到 PHPUnit 8),并且在项目根目下创建了 tests 目录用于存放测试文件:
9+
10+
Laravel测试目录结构
11+
12+
在该目录中包含的 Unit 和 Feature 子目录下存放的测试用例分别用于单元测试和功能测试,二者都是基于 PHPUnit 实现,对应的测试用例的根类都是 PHPUnit\Framework\TestCase。而 Broswer 目录下存放的则是基于 Laravel Dusk(底层基于 Selenium)实现的浏览器测试文件(后面我们再介绍)。
13+
14+
此外,在 Laravel 项目根目录下还有一个与 PHPUnit 息息县关的 phpunit.xml 文件,该文件我们在上篇教程中简单介绍过,是 PHPUnit 的编排文件,用于编排和初始化 PHPUnit 的测试行为,PHPUnit 在执行测试之前会基于这个文件进行初始化设置,你可以将其看作是 PHPUnit 的配置文件,下面我们就从这个文件为入口,分析 Laravel 框架如何集成 PHPUnit 进行单元测试和功能测试。
15+
16+
### 通过 phpunit.xml 编排 PHPUnit
17+
在上一篇 PHPUnit 入门教程中,我们已经介绍过,可以通过 XML 配置文件来编排 PHPUnit 的测试,对应的 XML 文件位于项目根目录下的 phpunit.xml,Laravel 框架已经为我们做好了如下初始化设置:
18+
19+
<?xml version="1.0" encoding="UTF-8"?>
20+
<phpunit backupGlobals="false"
21+
backupStaticAttributes="false"
22+
bootstrap="vendor/autoload.php"
23+
colors="true"
24+
convertErrorsToExceptions="true"
25+
convertNoticesToExceptions="true"
26+
convertWarningsToExceptions="true"
27+
processIsolation="false"
28+
stopOnFailure="false">
29+
<testsuites>
30+
<testsuite name="Unit">
31+
<directory suffix="Test.php">./tests/Unit</directory>
32+
</testsuite>
33+
34+
<testsuite name="Feature">
35+
<directory suffix="Test.php">./tests/Feature</directory>
36+
</testsuite>
37+
</testsuites>
38+
<filter>
39+
<whitelist processUncoveredFilesFromWhitelist="true">
40+
<directory suffix=".php">./app</directory>
41+
</whitelist>
42+
</filter>
43+
<php>
44+
<server name="APP_ENV" value="testing"/>
45+
<server name="BCRYPT_ROUNDS" value="4"/>
46+
<server name="CACHE_DRIVER" value="array"/>
47+
<server name="MAIL_DRIVER" value="array"/>
48+
<server name="QUEUE_CONNECTION" value="sync"/>
49+
<server name="SESSION_DRIVER" value="array"/>
50+
</php>
51+
</phpunit>
52+
该文件的第一行是 XML 文件的版本和编码描述信息,从第二行开始的 <phpunit> 元素则正式开始配置 PHPUnit 的核心功能,在该元素里面还嵌套定义了其它子元素,用于配置测试套件、过滤器、PHP 变量等其它信息。下面我们逐一来介绍这些元素和属性。
53+
54+
#### 通用配置
55+
首先来看 phpunit 元素上的属性,其中很多属性其实都可以在执行 phpunit 命令时通过命令行参数的形式传入,但是如果参数太多,且每次传入参数都是一样的,显然配置到 phpunit.xml 中更方便,也更加易于维护,PHPUnit 执行的命令行参数可以在这里查看,或者通过 phpunit --help 在命令行查看:
56+
57+
backupGlobals 属性对应命令行参数里的 --globals-backup,用于在每个测试中备份和恢复 PHP 超全局变量 $GLOBALS,这里设置为 false 表示不做相应的备份和恢复操作。
58+
backupStaticAttributes 属性对应命令行参数里的 static-backup,用于在每个测试中备份和恢复静态属性,这里设置为 false 表示不做相应的备份和恢复操作。
59+
bootstrap 属性对应命令行参数里面的 --bootstrap <file>,用于指定测试运行前需要引入的文件,这里配置为 vendor/autoload.php 表示会引入 Composer 自动加载和管理的所有依赖,以便在测试文件中使用。
60+
colors 属性对应命令行参数里的 --colors=<flag>,用于指示在输出中是否用颜色进行标识。
61+
processIsolation 属性对应命令行参数里的 --process-isolation,用于表示是否在隔离的 PHP 进程中执行测试。
62+
stopOnFailure 属性对应命令行参数里的 --stop-on-failure,用于表示测试出错或失败时是否退出脚本执行,配置为 false 表示不退出。
63+
接下来是一些不能通过命令行参数指定的属性:
64+
65+
convertErrorsToExceptions 属性用于定义是否将 PHP ERROR 级别错误转化为异常,默认会转化为异常的错误类型包括:E_WARNING、E_NOTICE、E_USER_ERROR、E_USER_WARNING、E_USER_NOTICE、E_STRICT、E_RECOVERABLE_ERROR、E_DEPRECATED、E_USER_DEPRECATED,这里将该属性设置为 true 表示启用该功能。
66+
convertNoticesToExceptions 属性用于定义是否将 PHP NOTICE 级别错误转化为异常,设置为 true 表示会将 E_NOTICE、E_USER_NOTICE、E_STRICT 三种级别错误转化为异常。
67+
convertWarningsToExceptions 属性用于定义是否将 PHP WARNING 级别错误转化为异常,设置为 true 表示会将 E_WARNING 或 E_USER_WARNING 级别错误转化为异常。
68+
当然,这里只包含了 PHPUnit 所支持的 phpunit 配置的一部分属性,更多配置请参考官方文档 及 PHPUnit 命令行参数配置。
69+
70+
#### 测试套件
71+
接下来,我们看 Laravel 框架为我们默认配置的测试套件,它们定义在子元素 <testsuites> 中,在 PHPUnit 中,我们可以像上篇教程那样配置单个 <testsuite>,也可以像 Laravel 框架这样通过 <testsuites> 配置多个 <testsuite>,这取决于项目的复杂度或者你的需求。
72+
73+
Laravel 框架默认通过 <testsuites> 定义了两个 <testsuite>,分别是用于单元测试的 Unit 和用于功能的测试的 Feature,在它们各自的测试套件中,通过 directory 子元素指定对应测试文件所在的目录,并通过 suffix 属性指定测试文件的文件名后缀,这样,当运行 phpunit 命令时,PHPUnit 会从指定目录下匹配指定后缀的测试文件进行测试。
74+
75+
在运行 phpunit 命令时,我们可以通过相应测试套件的名称匹配要执行的测试用例:
76+
77+
78+
79+
更多测试套件的配置选项可以参考官方文档。
80+
81+
#### 过滤器
82+
另外,Laravel 框架还通过 <filter> 元素配置了过滤器,在该元素中我们可以通过 whitelist 子元素指定用于配置代码覆盖率报告分析所使用的白名单,代码覆盖率是代码测试中一个很重要的概念,我们的测试代码要尽可能覆盖到 100% 的业务代码,这样的测试才有意义,而 Laravel 应用代码都位于项目根目录下的 app 目录中,并且我们只测试 PHP 代码,所以在 <whitelist> 中通过 directory 子元素做了相应的配置。
83+
84+
这样,我们在运行 phpunit 时加上 --coverage-html . 参数,就可以在根目录下生成 HTML 格式的测试覆盖率报告文档了:
85+
86+
87+
88+
打开对应的 index.html 文档,就可以在浏览器中看到测试覆盖率报告页面:
89+
90+
Laravel PHPUnit 代码覆盖率
91+
92+
#### PHP 变量
93+
最后,Laravel 框架还通过 <php> 元素为我们初始化了一些 PHPUnit 测试环境下的 PHP 常量:
94+
95+
<php>
96+
<server name="APP_ENV" value="testing"/>
97+
<server name="BCRYPT_ROUNDS" value="4"/>
98+
<server name="CACHE_DRIVER" value="array"/>
99+
<server name="MAIL_DRIVER" value="array"/>
100+
<server name="QUEUE_CONNECTION" value="sync"/>
101+
<server name="SESSION_DRIVER" value="array"/>
102+
</php>
103+
上述配置相当于以下 PHP 代码:
104+
105+
$_SERVER['APP_ENV'] = 'testing';
106+
$_SERVER['BCRYPT_ROUNDS'] = '4';
107+
$_SERVER['CACHE_DRIVER'] = 'array';
108+
$_SERVER['MAIL_DRIVER'] = 'array';
109+
$_SERVER['QUEUE_CONNECTION'] = 'sync';
110+
$_SERVER['SESSION_DRIVER'] = 'array';
111+
通过上述配置我们可以得知,在 Laravel 测试环境下,APP_ENV 的值是 testing,因此,我们可以在根目录下创建一个 .env.testing 文件作为测试环境下的环境配置文件,运行 phpunit 时实际执行的是控制台应用的 Kernel 来启动应用,这样,系统就会通过 .env.testing 读取环境配置。
112+
113+
缓存、邮件、会话驱动都是通过数组模拟,因而不会持久化到硬盘,此外队列驱动是 sync,表示会同步执行推送到队列的任务。
114+
115+
除此之外,还可以初始化 PHP 请求、常量、INI 设置、Cookie、超全局变量等信息,更多使用明细请参考官方文档。
116+
117+
如果需要的话,你还可以在 phpunit.xml 在编排 PHPUnit 的日志和监听器,由于 Laravel 框架默认没有提供这方面的配置,我们这里就不详细展开了,后面如果有用到会提及。
118+
119+
有了以上的概念和基础,下一篇我们将开始在 Laravel 框架中通过 PHPUnit 编写单元测试代码。
120+
121+
参考地址:[测试系列 —— 在 Laravel 中基于 PHPUnit 进行代码测试:目录结构及测试编排文件 phpunit.xml 详解](https://laravelacademy.org/post/19579.html)

0 commit comments

Comments
 (0)