1. Тестирование
  2. Тесты консоли

Присоединяйся к нашему Telegram сообществу @webblend!

Здесь ты найдешь сниппеты по Laravel и полезные советы по веб-разработке.

Введение

Помимо упрощения тестирования HTTP, Laravel предоставляет простой API для тестирования ваших пользовательских консольных команд.

Ожидания успешного/неуспешного выполнения

Чтобы начать, давайте рассмотрим, как делать утверждения относительно кода завершения Artisan-команды. Для этого мы будем использовать метод artisan для вызова команды Artisan из нашего теста. Затем мы воспользуемся методом assertExitCode для проверки того, что команда завершилась с заданным кодом завершения:

/**
* Тестирование консольной команды.
*/
public function test_console_command(): void
{
$this->artisan('inspire')->assertExitCode(0);
}

Метод assertNotExitCode можно использовать для проверки того, что команда не завершилась с заданным кодом завершения:

$this->artisan('inspire')->assertNotExitCode(1);

Конечно, все терминальные команды обычно завершаются с кодом состояния 0, когда они успешны, и кодом завершения, отличным от нуля, когда они не успешны. Поэтому, для удобства, вы можете использовать утверждения assertSuccessful и assertFailed для проверки того, что заданная команда завершилась успешным кодом завершения или нет:

$this->artisan('inspire')->assertSuccessful();
 
$this->artisan('inspire')->assertFailed();

Ожидания ввода/вывода

Laravel позволяет вам легко "мокать" ввод пользователя для ваших консольных команд с использованием метода expectsQuestion. Кроме того, вы можете указать код завершения и текст, который вы ожидаете увидеть в выводе консоли, с использованием методов assertExitCode и expectsOutput. Например, рассмотрим следующую консольную команду:

Artisan::command('question', function () {
$name = $this->ask('Как вас зовут?');
 
$language = $this->choice('Как вас зовут?', [
'PHP',
'Ruby',
'Python',
]);
 
$this->line('Ваше имя - '.$name.', и вы предпочитаете '.$language.'.');
});

Вы можете протестировать эту команду с помощью следующего теста, который использует методы expectsQuestion, expectsOutput, doesntExpectOutput, expectsOutputToContain, doesntExpectOutputToContain и assertExitCode:

/**
* Тестирование консольной команды.
*/
public function test_console_command(): void
{
$this->artisan('question')
->expectsQuestion('Как вас зовут?', 'Taylor Otwell')
->expectsQuestion('Какой язык вы предпочитаете?', 'PHP')
->expectsOutput('Ваше имя - Taylor Otwell, и вы предпочитаете PHP.')
->doesntExpectOutput('Ваше имя - Taylor Otwell, и вы предпочитаете Ruby.')
->expectsOutputToContain('Taylor Otwell')
->doesntExpectOutputToContain('вы предпочитаете Ruby')
->assertExitCode(0);
}

Ожидания подтверждения

При написании команды, которая ожидает подтверждения в форме ответа "да" или "нет", вы можете использовать метод expectsConfirmation:

$this->artisan('module:import')
->expectsConfirmation('Вы действительно хотите выполнить эту команду?', 'no')
->assertExitCode(1);

Ожидания таблицы

Если ваша команда отображает таблицу информации с использованием метода table Artisan, может быть неудобно писать ожидания вывода для всей таблицы. Вместо этого вы можете использовать метод expectsTable. Этот метод принимает заголовки таблицы в качестве первого аргумента и данные таблицы в качестве второго аргумента:

$this->artisan('users:all')
->expectsTable([
'ID',
'Email',
], [
]);

События консоли

По умолчанию события Illuminate\Console\Events\CommandStarting и Illuminate\Console\Events\CommandFinished не отправляются при выполнении тестов вашего приложения. Тем не менее, вы можете включить эти события для определенного тестового класса, добавив трейт Illuminate\Foundation\Testing\WithConsoleEvents в класс:

<?php
 
namespace Tests\Feature;
 
use Illuminate\Foundation\Testing\WithConsoleEvents;
use Tests\TestCase;
 
class ConsoleEventTest extends TestCase
{
use WithConsoleEvents;
 
// ...
}