В этом уроке мы расскажем о том, как начать писать функциональные тесты PHPUnit в Laravel.
Давайте рассмотрим блог-приложение, где есть модель Post и она имеет поля title и body. Давайте напишем функциональный тест в стиле TDD (Test-Driven Development — Разработка через тестирование), чтобы проверить функциональность модели.
Прежде чем перейти к тестам, вам нужно самостоятельно создать модель, ресурный контроллер и файл миграции, а также наполнить модель данными.
Прежде, чем мы начнем писать наш первый тест, поймите, что мы нам не нужно тестировать нашу базу данных, так как в ней могут быть тонны пользовательских записей и другой информации.
Для тестов мы должны иметь возможность брать точные данные, которые необходимы для работы конкретного теста.
Для этого мы внесем изменения в настройки тестовой базы данных, которая будет использоваться для тестирования phpunit. Откройте файл phpunit.xml, который находится в корневой папке вашего проекта, и добавьте в конец файла следующие свойства в переменные окружения.
<env name="APP_ENV" value="testing"/> <env name="DB_CONNECTION" value="sqlite"/> <env name="DB_DATABASE" value=":memory:"/>
Значение :memory: переменной DB_DATABASE говорит sqlite, что мы используем не реальные файлы, а работаем в памяти.
Отлично, теперь мы готовы написать первый функциональный тест.
Откройте вашу IDE и перейдите в папку tests/Feature.

Обратите внимание, что в папке уже есть файл ExampleTest.php. Здесь мы и создадим новый тест.
Для этого перейдите в терминал/командную строку и выполните следующую команду.
php artisan make:test PostsTest
В папке tests/Feature появится новый тест под названием PostsTest.php со следующим кодом
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
class PostsTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testExample()
{
$this->assertTrue(true);
}
}
Давайте изменим его и поработаем в стиле TDD.
Модифицируйте ваш PostsTest как показано ниже.
namespace Tests\Feature;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Tests\TestCase;
class PostsTest extends TestCase
{
use DatabaseMigrations;
/**
* A basic test example.
*
* @return void
*/
/** @test */
public function a_user_can_browse_posts()
{
$response = $this->get('/posts');
$response->assertStatus(200);
}
}
Мы используем DatabaseMigrations, это обеспечит запуск миграций при каждом запуске теста. И, как только тест завершится, миграции откатятся обратно. И помните, что миграция делаются прямо в память, как мы задали в файле phpunit.xml.
Мы переименовали нашу функцию в a_user_can_browse_posts и обратите внимание на комментарий /** @test */ в верхней части функции. Это важно, так как по нему phpunit распознает наш тест во время работы.
Перейдите в терминал и запустите тест, выполнив следующую команду.
vendor/bin/phpunit
Тест не пройден с ошибкой
1) Tests\Feature\PostsTest::a_user_can_browse_posts
Expected status code 200 but received 404.
Failed asserting that false is true.
Это было ожидаемо, ведь в файле web.php еще нет маршрута для /posts.
Давайте его добавим. Перейдите в файл web.php и добавьте следующий маршрут.
Route::get('/posts', 'PostsController@index');
Запустите тест снова и он должен выдать зеленое сообщение

Все идёт отлично. Давайте теперь изменим этот тест, так как пока он нам только говорит, что страница /posts работает. Нам нужно убедиться, что на этой странице мы также видим сообщения.
Откройте PostController.php и измените метод index для получения сообщений и передачи их в шаблон.
public function index()
{
$posts = Post::latest()->get();
return view('posts.index',compact('posts'));
}
Теперь нам нужно создать шаблон index.blade.php в папке resources/views/posts
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Posts</div>
<div class="card-body">
@foreach($posts as $post)
{{$post->title}}<br/>
{{$post->body}}
<hr/>
@endforeach
</div>
</div>
</div>
</div>
</div>
@endsection
Изменим наш тест для проверки того, что мы видим сообщения на странице /posts.
/** @test */
public function a_user_can_browse_posts()
{
$post = factory('App\Post')->create();
$response = $this->get('/posts');
$response->assertSee($post->title);
}
Запустите тест еще раз, он должен выдать зеленое сообщение. Готово! Мы написали свой первый функциональный тест в Laravel.
Автор: tgugnani
Перевод: Алексей Широков
Наш Телеграм-канал — следите за новостями о Laravel.
