В этом уроке мы расскажем о том, как начать писать функциональные тесты 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.