如果你想要测试一个方法内部逻辑是否正确,那么就写一个测试用例测试一下,给它一个值,看看输出的结果是否和我们预期的一样。
Laravel 植根于测试,实际上,框架内置 PHPUnit 对测试提供支持是开箱即用的,并且 phpunit.xml
文件已经为应用设置好了。框架还提供了方便的辅助方法允许你对应用进行优雅的测试。
默认情况下,tests 目录包含了两个子目录:Feature
和 Unit
,分别用于功能测试和单元测试
,单元测试专注于小的、相互隔离的代码,实际上,大部分单元测试可能都是聚焦于单个方法。功能测试可用于测试较大区块的代码,包括若干组件之前的交互,甚至一个完整的HTTP请求。
Feature 和 Unit 测试目录下都提供了ExampleTest.php
文件,安装完新的 Laravel 应用后,只需在项目根目录下简单运行 phpunit
命令 即可自动运行项目的所有测试(如果提示找不到命令,得重新安装phpunit,见第二步)。
注:PHPUnit 是一个面向程序员的、功能强大的 PHP 单元测试框架,如果你之前没接触过 PHPUnit,可以通过官网及中文文档快速入门。
我们在写代码的时候,通常就需要验证程序的执行是不是符合预期,所以我们需要做testcase;
可以看到这个系统有「限制活动的报名人数20人」的设定,要测试这个设定是否符合我们的预期(20人内能成功报名,超过20人将不能报名),要怎么做呢?
最容易想到就是手动或人工测试:让 20 个以上的使用者来报名活动,如果没超过限制的人数,使用者就能继续报名,反之,超过了限制人数的话,使用者就无法继续报名了!
1.测试案例一多,会花太多时间
如果把人数限制从20改为30, 或者 再增加一个报名截止日期的测试案例,这样可能要再重新做一次测试。
2.改了代码之后,需要再做一次测试
日常维护时,会需要再次修改代码,要验证修改后的代码没问题,肯定又要从头做一次测试。
3.与其他程序混在一起测试
所以,我们需要一个可以自动化、重复的、独立的测试,即使用phpunit,在这里我使用laravel框架下自带的phpunit,没有用laravel框架的也可以独立安装phpunit。
我是win7系统,安装了composer和laravel框架,laravel框架的路径是D:\wamp64\www\question_bank\
,question_bank是我的laravel项目名,虽然框架下的D:\wamp64\www\question_bank\verdor\bin
有phpunit文件,但是不能使用,直接在项目中输入phpunit命令会有以下提示:
Yliku@USER-20181020VX MINGW64 /d/wamp64/www/question_bank (master)
$ phpunit
bash: phpunit: command not found
所以得在项目中重新引入phpunit组件:
Yliku@USER-20181020VX MINGW64 /d/wamp64/www/question_bank (master)
$ composer update
Yliku@USER-20181020VX MINGW64 /d/wamp64/www/question_bank (master)
$ composer global require phpunit/phpunit
composer global remove phpunit/phpunit
phpunit包的删除命令
成功引入以后,phpunit组件将会存在于vendor/phpunit/phpunit
下,
phpunit命令存放在项目的 vendor/bin
目录下。
桌面-我的电脑-右键属性-高级系统设置-高级-环境变量-系统变量-选择 系统变量 里面的 path
,点击编辑,将phpunit的存放路径 D:\wamp64\www\question_bank\vendor\bin;
添加进去,注意最后一定要加分号!
执行以下命令 phpunit -v
或者 phpunit --version
,出现以下提示即安装成功。
Yliku@USER-20181020VX MINGW64 /d/wamp64/www/question_bank (master)
$ phpunit -v
PHPUnit 7.4.3 by Sebastian Bergmann and contributors.
Yliku@USER-20181020VX MINGW64 /d/wamp64/www/study/laravel (master)
$ phpunit
Fatal error: Uncaught TypeError: Argument 1 passed to PHPUnit\Runner\BaseTestRunner::getTest() must be of the type string, object given, called in D:\.......
这个错误应该是 phpunit 和 php版本 不兼容的问题造成;可查看 phpunit package 支持的 php版本,更新到相应的兼容版本。
// 该命令会在 /tests/Feature/下生成一个Usertest.php文件,也叫创建Feature测试类(功能测试)
php artisan make:test UserTest
// 该命令会在 /tests/Unit/下生成一个Usertest.php文件,也叫创建Unit测试类(单元测试)
php artisan make:test UserTest --unit
cd进入laravel框架项目,
phpunit
,自动运行项目下的所有测试案例:Yliku@USER-20181020VX MINGW64 /d/wamp64/www/question_bank (master)
$ phpunit
PHPUnit 7.4.3 by Sebastian Bergmann and contributors.
EE............................................................... 65 / 68 ( 95%)
..E 68 / 68 (100%)
Time: 1.8 seconds, Memory: 18.00MB
There were 3 errors:
上面的意思是:我的项目总共有68个测试案例,只有65个测试成功,3个测试结果是E,总共花了时间1.8秒和内存18M,E代表ERROR
,·代表测试成功
,参考下表:
. 成功时输出
F 运行过程中一个断言失败时输出
E 运行过程中产生一个错误时输出
R 被标记为有风险时输出
S 被跳过时输出
I 被标记为不完整或未实现时输出
phpunit tests/feature/ExampleTest.php
,单独运行文件名为 ExampleTest.php
里面的所有Test方法,一个方法代表一个测试案例:Yliku@USER-20181020VX MINGW64 /d/wamp64/www/question_bank (master)
$ phpunit tests/Feature/ExampleTest.php
PHPUnit 7.4.3 by Sebastian Bergmann and contributors.
.... 4 / 4 (100%)
Time: 333 ms, Memory: 12.00MB
OK (4 tests, 8 assertions)
我的 tests/feature/ExampleTest.php
文件内容如下:
namespace Tests\Feature;
//laravel项目自带phpunit,所有的测试类在根目录tests/ 下存放
//这句是必要的!!所有测试类必须继承Tests\TestCase,因为要使用该TestCase类的方法
use Tests\TestCase;
class ExampleTest extends TestCase {
//简单测试示例 ,所有测试类文件的命名必须为: *Test.php
//所有要测试的方法/函数必须为公开的public,且命名格式:public function test*(){},所以这个类里面总共包含了4个测试
//当然可以在你的测试用例中包含private的方法,但它们不能被phpunit识别为要测试的方法
public function testBasicTest1() {
$this->assertTrue(3>2); //断言括号内的内容为真,是的话则该方法测试成功
}
public function testExample2() {
$this->assertFalse(3<2); //断言括号内的内容为假,是的话则该方法测试成功
}
public function testExample3() {
$this->assertFalse(false); //断言括号内的内容为假,是的话则该方法测试成功
}
public function testExample4() { //这个方法下有很多断言,但只要有一个断言失败了,该方法就是测试失败,所以一般是一个方法放一个断言
$stack = []; //新建数组$stack,给它一个数组,看看输出的结果是否和我们预期的一致,判断是否一致就要开始断言了~~
$this->assertEquals(0, count($stack)); //count()提取数组的长度,断言0和数组的长度相等,相等的话测试成功
array_push($stack, 'foo'); //array_push向数组尾部插入元素'foo'
$this->assertEquals('foo', $stack[count($stack) - 1]);
$this->assertEquals(1, count($stack));
$this->assertEquals('foo', array_pop($stack)); //array_pop()删除数组的最后一个元素,返回值是被删除的元素
$this->assertEquals(0,count($stack) ); //判断括号内右边的值是否和左边的一致,左边的值是我们的预期输出
}
}
assertEquals() 判断是否相等
assertContains() 判断输入是否包含指定的值
assertInstanceOf()
assertTrue/assertFalse 断言是否为真值还是假
assertEquals 判断输出是否和预期的相等
assertGreaterThan 断言结果是否大于某个值,同样的也有LessThan 小于
GreaterThanOrEqual 大于等于
LessThanOrEqual 小于等于
assertType 判断是否属于指定类型
assertNull 判断是否为空值
assertFileExists 判断文件是否存在
assertRegExp 根据正则表达式判断
phpunit.xml
为phpunit的核心配置文件,在laravel项目根目录下,其中:
testsuites
中定义了测试文件存放路径为根目录下tests
文件下的Feature
和Unit
目录。filter
中定义了需要进行单元测试的PHP文件存放位置。php
中配置了测试环境的环境变量,默认APP_ENV为testing
,array
,array
,sync
。Feature
和 Unit
Feature
和 Unit
下都提供了ExampleTest.php
文件;Feature
和 Unit
分别用于功能测试
和单元测试
;功能测试
可用于测试较大区块的代码,包括若干组件之前的交互,甚至一个完整的HTTP请求。单元测试
专注于小的、相互隔离的代码,实际上,大部分单元测试可能都是聚焦于单个方法。运行测试的时候,Laravel 会自动设置环境为 testing
,这是因为 phpunit.xml
中定义了环境变量。Laravel 在测试时还会自动配置 Session 和缓存驱动为 array
,这意味着测试时不会持久化存储会话和缓存。
如果需要的话,你也可以定义其它测试环境配置值。testing
环境变量可以在 phpunit.xml
文件中配置,但是要确保在运行命令之前使用 Artisan 命令 config:clear
清除配置缓存。
此外,你还可以在项目根目录下创建一个 .env.testing
文件,该文件会在运行 PHPUnit 测试或执行带 --env=testing
开关的 Artisan 命令时覆盖 .env
文件中的环境变量。