Skip to content

测试

介绍

Laravel 是以单元测试为基础构建的。实际上,支持使用 PHPUnit 进行测试的功能是开箱即用的,并且 phpunit.xml 文件已经为您的应用程序设置好了。除了 PHPUnit,Laravel 还利用 Symfony HttpKernel、DomCrawler 和 BrowserKit 组件来允许您在测试时检查和操作视图,从而模拟一个网络浏览器。

app/tests 目录中提供了一个示例测试文件。安装新 Laravel 应用程序后,只需在命令行中运行 phpunit 来运行您的测试。

定义与运行测试

要创建一个测试用例,只需在 app/tests 目录中创建一个新的测试文件。测试类应扩展 TestCase。然后,您可以像使用 PHPUnit 一样定义测试方法。

示例测试类

php
class FooTest extends TestCase {

	public function testSomethingIsTrue()
	{
		$this->assertTrue(true);
	}

}

您可以通过从终端执行 phpunit 命令来运行应用程序的所有测试。

lightbulb

如果您定义了自己的 setUp 方法,请确保调用 parent::setUp

测试环境

在运行单元测试时,Laravel 会自动将配置环境设置为 testing。此外,Laravel 在测试环境中包含 sessioncache 的配置文件。这两个驱动在测试环境中都设置为 array,这意味着在测试期间不会持久化会话或缓存数据。您可以根据需要创建其他测试环境配置。

从测试中调用路由

从测试中调用路由

您可以使用 call 方法轻松调用测试中的路由:

php
$response = $this->call('GET', 'user/profile');

$response = $this->call($method, $uri, $parameters, $files, $server, $content);

然后,您可以检查 Illuminate\Http\Response 对象:

php
$this->assertEquals('Hello World', $response->getContent());

从测试中调用控制器

您还可以从测试中调用控制器:

php
$response = $this->action('GET', 'HomeController@index');

$response = $this->action('GET', 'UserController@profile', array('user' => 1));

getContent 方法将返回响应的评估字符串内容。如果您的路由返回一个 View,您可以使用 original 属性访问它:

php
$view = $response->original;

$this->assertEquals('John', $view['name']);

要调用 HTTPS 路由,您可以使用 callSecure 方法:

php
$response = $this->callSecure('GET', 'foo/bar');
lightbulb

在测试环境中,路由过滤器是禁用的。要启用它们,请在测试中添加 Route::enableFilters()

DOM 爬虫

您还可以调用路由并接收一个 DOM 爬虫实例,您可以使用它来检查内容:

php
$crawler = $this->client->request('GET', '/');

$this->assertTrue($this->client->getResponse()->isOk());

$this->assertCount(1, $crawler->filter('h1:contains("Hello World!")'));

有关如何使用爬虫的更多信息,请参阅其 官方文档

模拟门面

在测试时,您可能经常想要模拟对 Laravel 静态门面的调用。例如,考虑以下控制器操作:

php
public function getIndex()
{
	Event::fire('foo', array('name' => 'Dayle'));

	return 'All done!';
}

我们可以通过在门面上使用 shouldReceive 方法来模拟对 Event 类的调用,这将返回一个 Mockery 模拟的实例。

模拟一个门面

php
public function testGetIndex()
{
	Event::shouldReceive('fire')->once()->with('foo', array('name' => 'Dayle'));

	$this->call('GET', '/');
}
lightbulb

您不应模拟 Request 门面。相反,在运行测试时将所需的输入传递给 call 方法。

框架断言

Laravel 附带了几个 assert 方法,以使测试变得更容易:

断言响应正常

php
public function testMethod()
{
	$this->call('GET', '/');

	$this->assertResponseOk();
}

断言响应状态

php
$this->assertResponseStatus(403);

断言响应是重定向

php
$this->assertRedirectedTo('foo');

$this->assertRedirectedToRoute('route.name');

$this->assertRedirectedToAction('Controller@method');

断言视图有一些数据

php
public function testMethod()
{
	$this->call('GET', '/');

	$this->assertViewHas('name');
	$this->assertViewHas('age', $value);
}

断言会话有一些数据

php
public function testMethod()
{
	$this->call('GET', '/');

	$this->assertSessionHas('name');
	$this->assertSessionHas('age', $value);
}

断言会话有错误

php
public function testMethod()
{
    $this->call('GET', '/');

    $this->assertSessionHasErrors();

    // 断言会话有给定键的错误...
    $this->assertSessionHasErrors('name');

    // 断言会话有多个键的错误...
    $this->assertSessionHasErrors(array('name', 'age'));
}

断言旧输入有一些数据

php
public function testMethod()
{
	$this->call('GET', '/');

	$this->assertHasOldInput();
}

辅助方法

TestCase 类包含几个辅助方法,以使测试您的应用程序更容易。

从测试中设置和清空会话

php
$this->session(['foo' => 'bar']);

$this->flushSession();

设置当前认证用户

您可以使用 be 方法设置当前认证用户:

php
$user = new User(array('name' => 'John'));

$this->be($user);

从测试中重新填充数据库

您可以使用 seed 方法从测试中重新填充数据库:

php
$this->seed();

$this->seed('DatabaseSeeder');

有关创建种子的更多信息,请参阅文档的 迁移和填充 部分。

刷新应用程序

正如您可能已经知道的,您可以通过 $this->app 从任何测试方法访问您的 Laravel Application / IoC 容器。此应用程序实例在每个测试类中都会被刷新。如果您希望手动强制应用程序在给定方法中被刷新,您可以在测试方法中使用 refreshApplication 方法。这将重置自测试用例开始运行以来在 IoC 容器中放置的任何额外绑定,例如模拟。