Почему бы вам не начать писать тесты?

Узнайте, как легко начать автоматизированное тестирование в Laravel

Существуют сотни статей о том, почему вы должны писать тесты для своего кода. И я предполагаю, что вы читали их много раз.

Многие разработчики понимают важность написания тестов, но просто не начинают.

Почему

В основном из-за некоторого непонимания.

  • Они боятся сделать это неправильно.
  • Они думают, что недостаточно хороши (пока) для написания тестов.
  • Они не уверены, какой тип тестов применим к их проектам.

Как человек, побывавший там, позвольте мне сказать вам, что все это временно. Как только вы начнете писать тесты, все это исчезнет.

Почему не сегодня

Если я скажу вам, что для того, чтобы начать тестирование, вам понадобится всего 5-10 минут вашего времени, не могли бы вы начать прямо сейчас?

Пусть сегодняшний день станет началом чего-то нового.

  • Уильям Шекспир

Итак, давайте начнем наше путешествие по тестированию с приложения Laravel. Вы можете использовать существующее веб-приложение или создать новое.

На самом деле, вы можете следовать этой статье даже для любого другого языка программирования/фреймворка, поскольку мы будем обсуждать только высокоуровневые вещи.

Тесты по умолчанию в Laravel

Laravel поставляется с парой тестов из коробки. Откройте терминал и введите:

php artisan test
Войти в полноэкранный режим Выйти из полноэкранного режима

И если вы ничего не испортили в своем веб-приложении, вас встретит что-то вроде:

Отлично, у нас есть отличная отправная точка. Давайте теперь напишем наши собственные тесты.

Немного кода веб-приложения

Если у вас новое веб-приложение Laravel, пожалуйста, добавьте следующий код в файл routes/web.php перед написанием первого теста.

use AppModelsUser;
use IlluminateHttpRequest;

// existing code...

Route::post('/users', function (Request $request) {
    $validated = $request->validate([
        'name' => ['required', 'string', 'max:255'],
        'email' => ['required', 'email', 'max:255'],
        'password' => ['required', 'confirmed'],
    ]);

    User::create($validated);

    return back()->with('success', 'User created successfully.');
});
Вход в полноэкранный режим Выйти из полноэкранного режима

В этом коде происходят следующие вещи:

  1. Мы проверяем данные формы.
  2. Мы создаем пользователя в базе данных.
  3. Мы перенаправляем пользователя обратно с сообщением об успехе.

И наши тесты должны охватывать все это.

Создайте новый файл теста

Мы начнем с создания нового тестового файла. Выполните следующую команду в терминале:

php artisan make:test UserTest
Войти в полноэкранный режим Выйти из полноэкранного режима

Новый файл теста должен быть создан по адресу tests/Feature/UserTest.php.

Внимание — сброс базы данных

Если ваш код и тесты работают с базой данных, вам следует сбрасывать базу данных после каждого теста, чтобы гарантировать, что один тест не сможет повлиять на результаты другого. Laravel облегчает эту задачу, предоставляя трейты, которые вы можете добавить в свои классы тестов.

Пожалуйста, добавьте следующий признак в файл UserTest.php:

use IlluminateFoundationTestingLazilyRefreshDatabase;

class UserTest extends TestCase
{
    use LazilyRefreshDatabase;

    // existing code...
Вход в полноэкранный режим Выход из полноэкранного режима

С этим все готово, давайте испечем тесты.

Ваш первый тест — Счастливый путь

Файл теста по умолчанию уже содержит тест для GET-запроса. Таким образом, мы можем напрямую написать тест для POST-запроса.

Когда пользователь отправляет форму из браузера, выполняется POST-запрос с введенными данными и значениями. Мы собираемся имитировать то же самое в наших тестах.

Добавьте следующий код в файл UserTest.php:

    // existing code...

    public function test_new_user_can_be_added()
    {
        $response = $this->post('/users', [
            'name' => 'Gaurav',
            'email' => 'gauravmakhecha@gmail.com',
            'password' => '123456',
            'password_confirmation' => '123456',
        ]);

        $response->assertRedirect('/')
            ->assertSessionHas('success', 'User created successfully.');

        $this->assertDatabaseHas('users', [
            'name' => 'Gaurav',
            'email' => 'gauravmakhecha@gmail.com',
        ]);
    }
Вход в полноэкранный режим Выход из полноэкранного режима

Laravel предоставляет простой способ сделать POST-запрос из ваших тестовых файлов с помощью метода post(). Используя его, мы делаем запрос и проверяем, что данные пользователя добавлены в базу данных, а ответом является перенаправление с соответствующим сообщением в сессии.

Разве это не просто? Давайте попробуем еще раз.

Тест для проверки достоверности

Как насчет добавления теста, чтобы убедиться, что наша валидация работает так, как ожидается? Добавьте следующий код в файл UserTest.php:

    // existing code...

    public function test_new_user_data_is_validated()
    {
        $response = $this->post('/users', [
            'name' => '',
            'email' => 'not_email_format',
            'password' => '123456',
            'password_confirmation' => '456789',
        ]);

        $response->assertStatus(302)
            ->assertSessionHasErrors(['name', 'email', 'password']);
    }
Вход в полноэкранный режим Выход из полноэкранного режима

Здесь мы передаем недействительные данные для ввода формы и подтверждаем (assert), что есть ответ перенаправления (код состояния HTTP 302) и что в сессии есть ошибки валидации.

Тест на уникальный адрес электронной почты

Требование бизнеса заключается в том, что адрес электронной почты каждого пользователя должен быть уникальным, поэтому давайте добавим тест для этого. Добавьте этот тест в файл UserTest.php:

    // existing code...

    public function test_new_user_with_same_email_cannot_be_added()
    {
        User::factory()->create([
            'email' => 'gauravmakhecha@gmail.com',
        ]);

        $response = $this->post('/users', [
            'name' => 'Gaurav',
            'email' => 'gauravmakhecha@gmail.com',
            'password' => '123456',
            'password_confirmation' => '123456',
        ]);

        $response->assertStatus(302)
            ->assertSessionDoesntHaveErrors(['name', 'password'])
            ->assertSessionHasErrors(['email']);
    }
Вход в полноэкранный режим Выход из полноэкранного режима

Этот тест использует Laravel Factory для добавления пользователя в базу данных, а затем пытается сделать POST-запрос с тем же адресом электронной почты. Давайте запустим тесты и посмотрим результаты.

Упс, это не удалось. А причина? Мы не добавили уникальную валидацию в наш код.

Исправление

Теперь ваши тесты помогают вам в разработке. (Да, TDD!)

Пожалуйста, сделайте следующее обновление в файле routes/web.php:

-        'email' => ['required', 'email', 'max:255'],
+        'email' => ['required', 'email', 'max:255', 'unique:users'],
Вход в полноэкранный режим Выход из полноэкранного режима

После обновления похлопайте себя по спине и запустите тесты снова (php artisan test).

Что еще?

Вы поняли, что теперь вы официально являетесь разработчиком, который пишет автоматизированные тесты? Поздравляем!

Нужно больше примеров? Посмотрите этот каталог из официального репозитория Laravel для тестов, относящихся к различным модулям.

Цель этой статьи — помочь вам начать писать тесты. А не рассмотреть различные случаи использования или сценарии. Поэтому я ограничиваю здесь практическое кодирование и хотел бы поделиться некоторыми другими вещами, которые помогут вам продвинуться в этом.

Паттерны, которые могут вам помочь

Многие разработчики не уверены, для каких частей кода им следует писать тесты. Самый простой ответ — это: Старайтесь писать автоматизированные тесты для всех функций, которые вы проверяете при ручном тестировании вашего веб-приложения.

В данном примере мы проверяли запись в БД, сообщения о валидации и перенаправление при ручном тестировании веб-приложения. И это то, что охватывали наши автоматизированные тесты.

Вот несколько шаблонов, которые помогут вам спланировать тесты:

1. Given-When-Then

2. Arrange-Act-Assert .

Обе схемы похожи, поэтому вы можете использовать любую из них. Идея заключается в следующем:

  1. Сначала вы создаете обстановку (Добавляете существующие записи в БД, вводите пользователя и т.д.).
  2. Затем вы выполняете действие (Переход по URL, отправка формы и т.д.).
  3. Наконец, вы проверяете результаты/эффекты (запись в БД, вызов сессии, код статуса ответа и т.д.).

Этот способ в целом может помочь вам в написании большинства тестовых примеров.

Более того, у нас есть специальная статья о написании тестов только для вашего кода, которая поможет вам сориентироваться в границах тестирования.

(Не очень) сложные вещи

То, что мы рассмотрели в этой статье, — это тесты функций. Существует множество других типов тестов (Unit-тесты, Feature-тесты, интеграционные тесты, приемочные тесты и т.д.).

Не спешите изучать/использовать их все, вам это не нужно. Вы сами почувствуете необходимость, если/когда придет время.

Такие темы как mocking и stubbing относятся к той же категории. Поверьте, их использование не является обязательным. Но имейте в виду, что они весьма удобны для средних и больших проектов. Мы используем их в своих проектах и не можем без них жить.

Замечание о PEST

Мы используем PEST для написания тестов, но я решил не рассказывать об этом в данной статье для простоты изложения. Хотелось бы (и я уверен), чтобы он поставлялся из коробки с Laravel.

До Луны

Надеюсь, эта статья поможет вам начать писать тесты, и вы никогда не остановитесь в будущем. Не стесняйтесь оставлять комментарии ниже в случае возникновения вопросов. Пусть эти инструменты дадут вам больше возможностей для тестирования 😉.

А если кто-то из ваших друзей тоже отнекивается от того, чтобы начать писать тесты, как насчет того, чтобы поделиться с ними этой статьей для толчка?

Будьте здоровы и с уважением.

Оцените статью
devanswers.ru
Добавить комментарий