测试 | 服务 | Laravel 5.1 中文文档


本站和网页 https://laravelacademy.org/post/238.html 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

测试 | 服务 | Laravel 5.1 中文文档
Laravel 学院
文档
Laravel 10.x 中文文档
Laravel 8.x 中文文档
Laravel 7.x 中文文档
Laravel 6.x 中文文档
Laravel 5.8 中文文档
Laravel 5.7 中文文档
Laravel 5.6 中文文档
Laravel 5.5 中文文档
Laravel 5.4 中文文档
Laravel 5.3 中文文档
Laravel 5.2 中文文档
Laravel 5.1 中文文档
Lumen 中文文档
全栈教程
PHP 全栈工程师指南
PHP 入门到实战
Laravel 入门到精通
Vue.js 入门到实战
玩转 PhpStorm 教程
Laravel 博客入门项目
Laravel 微信小程序项目
Laravel 前后端分离项目
Swoole 入门到实战
Eloquent 性能优化实战
Redis 高性能实战系列
Laravel 新版本特性
PHP 新特性与最佳实践
Golang
Go 入门教程
Go Web 编程
Gin 使用教程
微服务开发
内功修炼
数据结构与算法
网络协议
微服务从入门到实践
高性能 MySQL 实战
高性能 Redis 实战
Laravel 消息队列实战
Laravel 从学徒到工匠
PHP 设计模式系列
名企面试指南
资源库
Laravel 资源大全
Laravel 开源项目
Laravel 扩展包
Laravel 资源下载
更多
博客 & 新闻
问答 & 讨论
Leetcode 题解
学院君读书笔记系列
关于 Laravel 学院
Laravel 互助学习群
Golang 互助学习群
更多
Laravel 中文文档
Laravel 全栈教程
Laravel 学习路径
Go 入门教程
程序员内功修炼
博客
问答
搜索
注册
登录
Info
Content
章节导航
Laravel 5.1 中文文档
目录索引
序言
3篇文章
发行版本说明
升级指南
贡献代码
起步
2篇文章
安装及配置
Laravel Homestead
教程
2篇文章
简单任务管理系统
带用户功能的任务管理系统
基础组件
7篇文章
HTTP 路由
HTTP 中间件
HTTP 控制器
HTTP 请求
HTTP 响应
视图
Blade 模板引擎
核心架构
6篇文章
一次请求的生命周期
应用目录结构
服务提供者
服务容器
契约(Contracts)
门面(Facades)
服务
24篇文章
用户认证
用户授权
Artisan 控制台
Laravel Cashier
缓存
集合
Laravel Elixir
加密
事件
错误&日志
文件系统/云存储
哈希
帮助函数
本地化
邮件
包开发
分页
队列
Redis
Session
Envoy 任务运行器(SSH任务)
任务调度
测试
验证
数据库操作
4篇文章
起步
查询构建器
迁移
填充数据
Eloquent模型
5篇文章
起步
关联关系
集合
访问器&修改器
序列化
图书
Laravel 5.1 中文文档
服务
测试
测试
由 学院君 创建于7年前, 最后更新于 2年前
版本号 #2
32978 views
15 likes
0 collects
1、简介
Laravel植根于测试,实际上,内置使用PHPUnit对测试提供支持是即开即用的,并且phpunit.xml文件已经为应用设置好了。框架还提供了方便的帮助方法允许你对应用进行富有表现力的测试。
tests目录中提供了一个ExampleTest.php文件,安装完新的Laravel应用后,只需简单在命令行运行phpunit来运行测试。
1.1 测试环境
运行测试的时候,Laravel自动设置配置环境为testing。Laravel在测试时自动配置session和cache驱动为数组驱动,这意味着测试时不会持久化存储session和cache。
如果需要的话你可以自由创建其它测试环境配置。testing环境变量可以在phpunit.xml文件中配置。
1.2 定义&运行测试
要创建一个测试用例,只需简单在tests目录创建一个新的测试文件,测试类应该继承TestCase,然后你可以使用PHPUnit定义测试方法。要运行测试,简单从终端执行phpunit命令即可:
<?php
class FooTest extends TestCase{
public function testSomethingIsTrue()
$this->assertTrue(true);
注意:如果你在测试类中定义自己的setUp方法,确保在其中调用parent::setUp。
2、应用测试
Laravel为生成HTTP请求、测试输出、以及填充表单提供了平滑的API。举个例子,我们看下tests目录下包含的ExampleTest.php文件:
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase{
/**
* 基本功能测试示例
* @return void
*/
public function testBasicExample()
$this->visit('/')
->see('Laravel 5')
->dontSee('Rails');
visit方法生成了一个GET请求,see方法对我们从应用返回响应中应该看到的给定文本进行断言。dontSee方法对给定文本没有从应用响应中返回进行断言。在Laravel中这是最基本的有效应用测试。
2.1 与应用交互
当然,除了对响应文本进行断言之外还有做更多测试,让我们看一些点击链接和填充表单的例子:
2.1.1 点击链接
在本测试中,我们将为应用生成请求,在返回的响应中“点击”链接,然后对访问URI进行断言。例如,假定响应中有一个“关于我们”的链接:
<a href="/about-us">About Us</a>
现在,让我们编写一个测试点击链接并断言用户访问页面是否正确:
public function testBasicExample(){
$this->visit('/')
->click('About Us')
->seePageIs('/about-us');
2.1.2 处理表单
Laravel还为处理表单提供了多个方法。type, select, check, attach, 和press方法允许你与所有表单输入进行交互。例如,我们假设这个表单存在于应用注册页面:
<form action="/register" method="POST">
{!! csrf_field() !!}
<div>
Name: <input type="text" name="name">
</div>
<div>
<input type="checkbox" value="yes" name="terms"> Accept Terms
</div>
<div>
<input type="submit" value="Register">
</div>
</form>
我们可以编写测试完成表单并检查结果:
public function testNewUserRegistration(){
$this->visit('/register')
->type('Taylor', 'name')
->check('terms')
->press('Register')
->seePageIs('/dashboard');
当然,如果你的表单包含其他输入比如单选按钮或下拉列表,也可以轻松填写这些字段类型。这里是所有表单操作方法列表:
方法
描述
$this->type($text, $elementName)
"Type" 文本到给定字段
$this->select($value, $elementName)
"Select" 单选框或下拉列表
$this->check($elementName)
"Check" 复选框
$this->attach($pathToFile, $elementName)
"Attach" 文件到表单
$this->press($buttonTextOrElementName)
"Press"  给定文本或name的按钮
2.1.3 处理附件
如果表单包含file输入类型,可以使用attach方法添加文件到表单:
public function testPhotoCanBeUploaded(){
$this->visit('/upload')
->name('File Name', 'name')
->attach($absolutePathToFile, 'photo')
->press('Upload')
->see('Upload Successful!');
2.2 测试 JSON API
Laravel还提供多个帮助函数用于测试JSON API及其响应。例如,get, post, put, patch, 和 delete方法用于通过多种HTTP请求方式发出请求。你还可以轻松传递数据和头到这些方法。作为开始,我们编写测试来生成POST请求到/user并断言返回的数据是否是JSON格式:
<?php
class ExampleTest extends TestCase{
/**
* 基本功能测试示例
* @return void
*/
public function testBasicExample()
$this->post('/user', ['name' => 'Sally'])
->seeJson([
'created' => true,
]);
seeJson方法将给定数组转化为JSON,然后验证应用返回的整个JSON响应中的JSON片段。因此,如果在JSON响应中有其他属性,只要给定片段存在的话测试依然会通过。
2.2.1 精确验证JSON匹配
如果你想要验证给定数组和应用返回的JSON能够精确匹配,使用seeJsonEquals方法:
<?php
class ExampleTest extends TestCase{
/**
* 基本功能测试示例
* @return void
*/
public function testBasicExample()
$this->post('/user', ['name' => 'Sally'])
->seeJsonEquals([
'created' => true,
]);
2.3 Session/认证
Laravel提供个多个帮助函数在测试期间处理session,首先,可以使用withSession方法设置session值到给定数组。这通常在测试请求前获取session数据时很有用:
<?php
class ExampleTest extends TestCase{
public function testApplication()
$this->withSession(['foo' => 'bar'])
->visit('/');
当然,session的通常用于操作用户状态,例如认证用户。帮助函数actingAs 提供了认证给定用户为当前用户的简单方法,例如,我们使用模型工厂生成和认证用户:
<?php
class ExampleTest extends TestCase{
public function testApplication()
$user = factory('App\User')->create();
$this->actingAs($user)
->withSession(['foo' => 'bar'])
->visit('/')
->see('Hello, '.$user->name);
2.4 禁止中间件
测试应用时,为某些测试禁止中间件很方便。这种机制允许你将路由和控制器与中间件孤立开来做测试,Laravel包含了一个简单的WithoutMiddleware trait,可以使用该trait自动在测试类中禁止所有中间件:
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase{
use WithoutMiddleware;
//
如果你只想在某些方法中禁止中间件,可以在测试方法中调用withoutMiddleware方法:
<?php
class ExampleTest extends TestCase{
/**
* 基本功能测试示例
* @return void
*/
public function testBasicExample()
$this->withoutMiddleware();
$this->visit('/')
->see('Laravel 5');
2.5 自定义HTTP请求
如果你想要在应用中生成自定义HTTP请求并获取完整的Illuminate\Http\Response对象,可以使用call方法:
public function testApplication(){
$response = $this->call('GET', '/');
$this->assertEquals(200, $response->status());
如果你要生成POST, PUT, 或者 PATCH请求可以在请求中传入输入数据数组,在路由或控制器中可以通过Request实例访问请求数据:
$response = $this->call('POST', '/user', ['name' => 'Taylor']);
3、处理数据库
Laravel还提供了多种有用的工具让测试数据库驱动的应用更加简单。首先,你可以使用帮助函数seeInDatabase来断言数据库中的数据是否和给定数据集合匹配。例如,如果你想要通过email值为sally@example.com的条件去数据表users查询是否存在该记录 ,我们可以这样做:
public function testDatabase(){
// 调用应用...
$this->seeInDatabase('users', ['email' => 'sally@foo.com']);
3.1 每次测试后重置数据库
每次测试后重置数据库通常很有用,这样的话上次测试的数据不会影响下一次测试。
3.1.1 使用迁移
一种方式是每次测试后回滚数据库并在下次测试前重新迁移。Laravel提供了一个简单的DatabaseMigrations trait来自动为你处理。在测试类上简单使用该trait如下:
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase{
use DatabaseMigrations;
/**
* 基本功能测试示例
* @return void
*/
public function testBasicExample()
$this->visit('/')
->see('Laravel 5');
3.1.2 使用事务
另一种方式是将每一个测试用例包裹到一个数据库事务中,Laravel提供了方便的 DatabaseTransactions trait自动为你处理:
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase{
use DatabaseTransactions;
/**
* 基本功能测试示例
* @return void
*/
public function testBasicExample()
$this->visit('/')
->see('Laravel 5');
3.2 模型工厂
测试时,通常需要在执行测试前插入新数据到数据库。在创建测试数据时,Laravel允许你使用"factories"为每个Eloquent模型定义默认的属性值集合,而不用手动为每一列指定值。作为开始,我们看一下database/factories/ModelFactory.php文件,该文件包含了一个工厂定义:
$factory->define(App\User::class, function (Faker\Generator $faker) {
return [
'name' => $faker->name,
'email' => $faker->email,
'password' => bcrypt(str_random(10)),
'remember_token' => str_random(10),
];
});
在闭包中,作为工厂定义,我们返回该模型上所有属性默认测试值。该闭包接收PHP库Faker实例,从而允许你方便地为测试生成多种类型的随机数据。
当然,你可以添加更多工厂到ModelFactory.php文件。
3.2.1 多个工厂类型
有时候你可能想要为同一个Eloquent模型类生成多个工厂,例如,除了正常用户外可能你想要为“管理员”用户生成一个工厂,你可以使用defineAs方法定义这些工厂:
$factory->defineAs(App\User::class, 'admin', function ($faker) {
return [
'name' => $faker->name,
'email' => $faker->email,
'password' => str_random(10),
'remember_token' => str_random(10),
'admin' => true,
];
});
你可以使用raw方法获取基本属性而不用重复基本用户工厂中的所有属性,获取这些属性后,只需将你要求的额外值增补进去即可:
$factory->defineAs(App\User::class, 'admin', function ($faker) use ($factory) {
$user = $factory->raw(App\User::class);
return array_merge($user, ['admin' => true]);
});
3.2.2 在测试中使用工厂
定义好工厂后,可以在测试或数据库填充文件中通过全局的factory方法使用它们来生成模型实例,所以,让我们看一些生成模型的例子,首先,我们使用make方法,该方法创建模型但不将其保存到数据库:
public function testDatabase(){
$user = factory(App\User::class)->make();
// 用户模型测试...
如果你想要覆盖模型的一些默认值,可以传递数组值到make方法。只有指定值被替换,其他数据保持不变:
$user = factory(App\User::class)->make([
'name' => 'Abigail',
]);
还可以创建多个模型集合或者创建给定类型的集合:
// 创建3个 App\User 实例...
$users = factory(App\User::class, 3)->make();
// 创建1个 App\User "admin" 实例...
$user = factory(App\User::class, 'admin')->make();
// 创建3个 App\User "admin" 实例...
$users = factory(App\User::class, 'admin', 3)->make();
3.2.3 持久化工厂模型
create方法不仅能创建模型实例,还可以使用Eloquent的save方法将它们保存到数据库:
public function testDatabase(){
$user = factory(App\User::class)->create();
//用户模型测试...
你仍然可以通过传递数组到create方法覆盖模型上的属性:
$user = factory(App\User::class)->create([
'name' => 'Abigail',
]);
3.2.4 添加关联关系到模型
你甚至可以持久化多个模型到数据库。在本例中,我们添加一个关联到创建的模型,使用create方法创建多个模型的时候,会返回一个Eloquent集合实例,从而允许你使用集合提供的所有便利方法,例如each:
$users = factory(App\User::class, 3)
->create()
->each(function($u) {
$u->posts()->save(factory(App\Post::class)->make());
});
4、模拟
4.1 模拟事件
如果你在重度使用Laravel的时间系统,可能想要在测试时模拟特定事件。例如,如果你在测试用户注册,你可能不想所有UserRegistered的时间处理器都被触发,因为这可能会发送欢迎邮件,等等。
Laravel提供可一个方便的expectsEvents方法来验证期望的事件被触发,但同时阻止该事件的其它处理器运行:
<?php
class ExampleTest extends TestCase{
public function testUserRegistration()
$this->expectsEvents(App\Events\UserRegistered::class);
// 测试用户注册代码...
如果你想要阻止所有事件运行,可以使用withoutEvents方法:
<?php
class ExampleTest extends TestCase{
public function testUserRegistration()
$this->withoutEvents();
// 测试用户注册代码...
4.2 模拟队列任务
有时候,你可能想要在请求时简单测试控制器分发的指定任务,这允许你孤立的测试路由/控制器——将其从任务逻辑中分离出去,当然,接下来你可以在一个独立测试类中测试任务本身。
Laravel提供了一个方便的expectsJobs方法来验证期望的任务被分发,但该任务本身不会被测试:
<?php
class ExampleTest extends TestCase{
public function testPurchasePodcast()
$this->expectsJobs(App\Jobs\PurchasePodcast::class);
// 测试购买播客代码...
注意:这个方法只检查通过DispatchesJobs trait分发方法分发的任务,并不检查直接通过Queue::push分发的任务。
4.3 模拟门面
测试的时候,你可能经常想要模拟Laravel门面的调用,例如,看看下面的控制器动作:
<?php
namespace App\Http\Controllers;
use Cache;
use Illuminate\Routing\Controller;
class UserController extends Controller{
/**
* 显示应用用户列表
* @return Response
*/
public function index()
$value = Cache::get('key');
//
我们可以通过使用shouldReceive方法模拟Cache门面的调用,该方法返回一个Mockery模拟的实例,由于门面通过Laravel服务容器解析和管理,它们比通常的静态类更具有可测试性。例如,我们来模拟Cache门面的调用:
<?php
class FooTest extends TestCase{
public function testGetIndex()
Cache::shouldReceive('get')
->once()
->with('key')
->andReturn('value');
$this->visit('/users')->see('value');
注意:不要模拟Request门面,取而代之地,在测试时传递输入到HTTP帮助函数如call和post。
数据库
表单
断言
单元测试
PHPUnit
Mockery
模拟
测试
队列
模型工厂
Laravel
门面
事件
JSON
Session
请求
中间件
5.1
文档
点赞
取消点赞
收藏
取消收藏
赞赏
分享到以下平台:
<< 上一篇:
任务调度
>> 下一篇:
验证
10 条评论
#1
戴学鹏
评论于 7年前
正在删除评论...
这个测试服务,测试什么呢?
#2
学院君
评论于 7年前
正在删除评论...
所有后端程序功能的单元测试
#3
鸡仔食饭米
评论于 7年前
正在删除评论...
3.2.1 多个工厂类型
function ($faker)
这个function的参数没有引入FakerGenerator,也能生成参数,是不是这个modelFactory.php里面默认的function都是直接实例化faker?
#4
白色恋人
评论于 7年前
正在删除评论...
请问 AppUser::class 这个参数是什么意思?
#5
白色恋人
评论于 7年前
正在删除评论...
是不是代表User这个model呢?
#6
娃娃脾气
评论于 7年前
正在删除评论...
是的
#7
纳兰小九
评论于 7年前
正在删除评论...
学院君 这个测试服务 有没有具体的demo可以看下 只是了解方法 不知道该怎么使用
#8
学院君
评论于 7年前
正在删除评论...
参考博客系列测试部分:https://xueyuanjun.com/post/2232.html
#9
梦回
评论于 7年前
正在删除评论...
学院君,需要测试一个页面返回的状态码200,怎么测试?
#10
阿旺_ 
评论于 6年前
正在删除评论...
laravel5.1.*版本的laravel-elixir有点老,^4.0.0有bug,测试未通过也会出现成功的标志,升级^5.0.0解决了该问题。
登录后即可添加评论
升级为学院君订阅用户(新年优惠🎁)
内容导航
1、简介
1.1 测试环境
1.2 定义&运行测试
2、应用测试
2.1 与应用交互
2.1.1 点击链接
2.1.2 处理表单
2.1.3 处理附件
2.2 测试 JSON API
2.2.1 精确验证JSON匹配
2.3 Session/认证
2.4 禁止中间件
2.5 自定义HTTP请求
3、处理数据库
3.1 每次测试后重置数据库
3.1.1 使用迁移
3.1.2 使用事务
3.2 模型工厂
3.2.1 多个工厂类型
3.2.2 在测试中使用工厂
3.2.3 持久化工厂模型
3.2.4 添加关联关系到模型
4、模拟
4.1 模拟事件
4.2 模拟队列任务
4.3 模拟门面
相关推荐
测试
Lumen 5.1 中文文档
更多特性
测试
Laravel 5.2 中文文档
服务
单元测试
Lumen 5.2 中文文档
更多特性
应用测试
Laravel 5.3 中文文档
测试系列
单元测试
Lumen 5.3 中文文档
更多特性
回到顶部
2023 基于 Laravel 6 构建
关于学院
订阅服务
友情链接
站点地图
本站 CDN 加速服务由腾讯云提供