Laravel: Три вещи, которые нужны для TDD

Источник: «3 Things You Need For Test-Driven Development»
Тестирование или Разработка Через Тестирование (Test-Driven Development) важные и сложные темы программирования. Особенно сложным будет переход от простого написания тестов к TDD.

После нескольких использования (TDD) я вижу три вещи, которые нужно знать, чтобы заставить его работать.

1. Нужно знать что тестировать

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

Вот почему всегда рекомендую начинать с очень простого теста. Тест, который сразу все понимают, но, что боле важно, могут сразу использовать.

public function it_gives_successful_response_for_homepage()
{
$this->get('/')
->assertSuccessful();
}

В этом тесте мы делаем запрос к домашней странице и проверяем, успешен ли ответ. Возможно, вам нужно объяснить, что это утверждение проверяет, находится ли код ответа в диапазоне от 200 до 300, но это всё. С этого момента вы знаете, что домашняя страница не выдаёт никаких ошибок. Это уже большой успех, и если у вас только один тест он всё равно оказывает положительное влияние.

Теперь вы можете тестировать все страницы вашего Laravel приложения, что я и делаю в каждом проекте. Точно так же вы узнаете, что ещё можно тестировать.

В следующем тесте я тестирую собственный класс фабрики. Я хочу убедиться, что результат метода create соответствует моим ожиданиям.

public function it_creates_new_post_file()
{
Storage::fake('posts');

$postPath = PostFactory::new()
->create();

$this->assertFileExists($postPath);
}

Поэтому помимо HTTP-тестов, где мы проверяем ответ или вывод HTTP-запроса, рекомендуется протестировать создаваемые вами классы, такие как мой PostFactory. Каждый публичный метод указывает на новый тест, который вы можете написать, чтобы убедиться в его поведении.

Другой пример пользовательского класс — команда Laravel. Здесь я хочу проверить, что она делает при вызове Artisan.

public function it_caches_posts_when_command_run()
{
$this->assertFalse(Cache::has('posts'));

$this->artisan(CachePostsCommand::class);

$this->assertTrue(Cache::has('posts'));

}

Примечание: Все примеры — реальные тесты из моих приложений.

Чем больше вы узнаёте о тестировании, тем больше будет расти ваш список для тестирования. Тестирование также даёт больше уверенности при развёртывании приложения или его изменении. Поэтому количество тестов, которые понадобятся для этого может варьироваться. Это ваш выбор.

2. Нужно знать свой стек

Что касается стека, я не имею в виду низкоуровневый стек, такой как локальная среда или язык разработки. Я имею в виду, как вы создаёте свои PHP-приложения.

В основном речь пойдёт о выбранном вами фреймворке и инструментах, которые вы используете для создания приложений. Для меня такими инструментами являются Laravel и Laravel Livewire. Это важно, потому что, то, как я пишу тесты, будет зависеть от этих инструментов.

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

public function it_includes_video_player_component () {
// Arrange
$user = User::factory()
->withPurchasedProduct();

// Act & Assert
$this->actingAs($user)
->get(route('videos', $user->products->first()))
->assertSeeLivewire(VideoPlayer::class);
});

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

public function it_orders_player_videos() {
// Arrange
createProductVideos(3, new Sequence(
['title' => 'Outro', 'order_slot' => '3'],
['title' => 'Intro', 'order_slot' => '1'],
['title' => 'Middle', 'order_slot' => '2']
));

// Act & Assert
Livewire::test(VideoPlayer::class, ['productId' => Product::first()->id])
->assertSeeInOrder(['Intro', 'Middle', 'Outro']);
});

Примечание: В Laravel Livewire есть собственный хэлпер для тестирования, который я использую для тестирования компонентов Livewire.

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

Вот почему я гарантирую, что компонент используется только на странице видео. Всё остальное будет проверено в отдельном компонентном тесте.

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

3. Нужно изменить свой рабочий процесс

С TDD всегда сначала пишете тест. Конечно, у этого подхода есть свои вариации, но сегодня мы сосредоточимся на исходной концепции.

Написание теста до того, как вы узнаете о его реализации — это значительный сдвиг в мышлении; это займёт некоторое время, прежде чем вы привыкните к этому. Новый рабочий процесс часто называют Красный Зелёный Рефакторинг, и вы, вероятно, уже слышали о нём. Он описывает три основных этапа рабочего процесса.

Красный 🛑

Красный означает неудачный тест. Это верно и для нового, пустого теста, с чего мы и начинаем.

Часто бывает полезно сначала подумать, что вы хотите протестировать, и написать пустую функцию для каждого из них.

public function it_shows_posts_per_page()
{
}

public function it_shows_post_prev_and_next_buttons()
{
}

public function it_resets_pagination_after_search()
{
}

Зелёный ✅

Следующий шаг — сделать ваш тест зелёным, что означает его прохождение. Теперь вы должны реализовать свою функцию, и тест покажет вам, работает ли она должным образом.

Это важный шаг, потому что есть много способов сделать ваш тест зелёным. Но нас интересует только самый быстрый. Нас не интересует, красивый ли код или SOLID или что-то ещё в этом роде. Нам нужно, чтобы это работало, и это самое главное.

Рефакторинг ♺

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

Поскольку мы уже знаем, что наше первое решение сработало, мы сразу же увидим, не сработает ли новое решение. Это придаст уверенность при рефакторинге кода в соответствии с вашими потребностями.

Заключение

Разработка через тестирование (TDD) стала моим стандартом кодирования в течение нескольких лет. Это помогает лучше сосредоточится на том, что я действительно хочу разработать, не теряясь в деталях или других задачах. Наличие тестов позволяет лучше спать по ночам, зная, что мой код работает.

Дополнительные материалы

Предыдущая Статья

TypeScript: 11 советов, которые улучшат ваши навыки

Следующая Статья

Laravel: Преимущество минимальных фабрик