Console Testing

Introduzione

Oltre a semplificare i test HTTP, Laravel offre una semplice API per testare i comandi console personalizzati della tua applicazione.

Aspettative di Successo e Fallimento

Per iniziare, esploriamo come fare asserzioni riguardo al codice di uscita di un comando Artisan. Per fare questo, useremo il metodo artisan per invocare un comando Artisan dal nostro test. Poi, useremo il metodo assertExitCode per asserire che il comando sia terminato con un determinato codice di uscita:

test('console command', function () {
    $this->artisan('inspire')->assertExitCode(0);
});
/**
 * Test a console command.
 */
public function test_console_command(): void
{
    $this->artisan('inspire')->assertExitCode(0);
}

Puoi usare il metodo assertNotExitCode per asserire che il comando non sia terminato con un determinato codice di uscita:

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

Naturalmente, tutti i comandi terminali normalmente terminano con un codice di stato 0 quando hanno successo e con un codice di uscita diverso da zero quando non hanno successo. Pertanto, per comodità, puoi utilizzare le asserzioni assertSuccessful e assertFailed per asserire che un determinato comando sia terminato con un codice di uscita di successo o meno:

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

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

Aspettative di Input/Output

Laravel permette di "simulare" facilmente l’input dell’utente per i comandi della console usando il metodo expectsQuestion. Inoltre, puoi specificare il codice di uscita e il testo che prevedi venga outputtato dal comando della console usando i metodi assertExitCode e expectsOutput. Ad esempio, considera il seguente comando della console:

    Artisan::command('question', function () {
        $name = $this->ask('What is your name?');

        $language = $this->choice('Which language do you prefer?', [
            'PHP',
            'Ruby',
            'Python',
        ]);

        $this->line('Your name is '.$name.' and you prefer '.$language.'.');
    });

Puoi testare questo comando con il seguente test:

test('console command', function () {
    $this->artisan('question')
         ->expectsQuestion('What is your name?', 'Taylor Otwell')
         ->expectsQuestion('Which language do you prefer?', 'PHP')
         ->expectsOutput('Your name is Taylor Otwell and you prefer PHP.')
         ->doesntExpectOutput('Your name is Taylor Otwell and you prefer Ruby.')
         ->assertExitCode(0);
});
/**
 * Test a console command.
 */
public function test_console_command(): void
{
    $this->artisan('question')
         ->expectsQuestion('What is your name?', 'Taylor Otwell')
         ->expectsQuestion('Which language do you prefer?', 'PHP')
         ->expectsOutput('Your name is Taylor Otwell and you prefer PHP.')
         ->doesntExpectOutput('Your name is Taylor Otwell and you prefer Ruby.')
         ->assertExitCode(0);
}

Se stai utilizzando le funzioni search o multisearch fornite da Laravel Prompts, puoi usare l’asserzione expectsSearch per simulare l’input dell’utente, i risultati della ricerca e la selezione:

test('console command', function () {
    $this->artisan('example')
         ->expectsSearch('What is your name?', search: 'Tay', answers: [
            'Taylor Otwell',
            'Taylor Swift',
            'Darian Taylor'
         ], answer: 'Taylor Otwell')
         ->assertExitCode(0);
});
/**
 * Test a console command.
 */
public function test_console_command(): void
{
    $this->artisan('example')
         ->expectsSearch('What is your name?', search: 'Tay', answers: [
            'Taylor Otwell',
            'Taylor Swift',
            'Darian Taylor'
         ], answer: 'Taylor Otwell')
         ->assertExitCode(0);
}

Puoi anche verificare che un comando della console non generi alcun output usando il metodo doesntExpectOutput:

test('console command', function () {
    $this->artisan('example')
         ->doesntExpectOutput()
         ->assertExitCode(0);
});
/**
 * Test a console command.
 */
public function test_console_command(): void
{
    $this->artisan('example')
            ->doesntExpectOutput()
            ->assertExitCode(0);
}

I metodi expectsOutputToContain e doesntExpectOutputToContain possono essere usati per fare asserzioni su una parte dell’output:

test('console command', function () {
    $this->artisan('example')
         ->expectsOutputToContain('Taylor')
         ->assertExitCode(0);
});
/**
 * Test a console command.
 */
public function test_console_command(): void
{
    $this->artisan('example')
            ->expectsOutputToContain('Taylor')
            ->assertExitCode(0);
}

Aspettative di Conferma

Quando scrivi un comando che richiede una conferma sotto forma di risposta "si" o "no", puoi utilizzare il metodo expectsConfirmation:

    $this->artisan('module:import')
        ->expectsConfirmation('Do you really wish to run this command?', 'no')
        ->assertExitCode(1);

Aspettative della Tabella

Se il tuo comando visualizza una tabella di informazioni usando il metodo table di Artisan, può essere complicato scrivere le aspettative di output per l’intera tabella. Invece, puoi usare il metodo expectsTable. Questo metodo accetta le intestazioni della tabella come primo argomento e i dati della tabella come secondo argomento:

$this->artisan('users:all')
    ->expectsTable([
        'ID',
        'Email',
    ], [
        [1, 'taylor@example.com'],
        [2, 'abigail@example.com'],
    ]);

Eventi della Console

Di default, gli eventi Illuminate\Console\Events\CommandStarting e Illuminate\Console\Events\CommandFinished non vengono inviati durante l’esecuzione dei test della tua applicazione. Tuttavia, puoi abilitare questi eventi per una determinata classe di test aggiungendo il trait Illuminate\Foundation\Testing\WithConsoleEvents alla classe:

<?php

use Illuminate\Foundation\Testing\WithConsoleEvents;

uses(WithConsoleEvents::class);

// ...
<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\WithConsoleEvents;
use Tests\TestCase;

class ConsoleEventTest extends TestCase
{
    use WithConsoleEvents;

    // ...
}
Lascia un commento

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *