Skip to content

Capítulo 2.8: Teste de API

Tempo de estudo: 1 hora


1. Por que os testes são necessários?

Imagine que você construiu uma nave espacial. Antes de enviá-la para Marte, você realiza milhares de verificações na Terra. Testes em programação são a mesma coisa. Eles:

  • Dão confiança: Você pode alterar o código, e se os testes passarem — significa que você não quebrou nada.
  • Economizam tempo: Em vez de "clicar" manualmente em tudo no Postman após cada alteração, você executa um único comando, e ele verifica tudo para você em segundos.
  • Servem como documentação: Bons testes mostram como sua API deve funcionar.

2. Configurando o "Laboratório" de Teste

Laravel torna a configuração de testes incrivelmente simples. Por padrão, ele usa uma configuração separada para não afetar seu banco de dados principal.

Banco de dados para testes: Por padrão, Laravel usa um banco de dados em memória (:memory:). Esta é a maneira mais rápida, porque não há necessidade de escrever nada no disco. O banco de dados é criado antes dos testes e destruído depois deles. Nem precisamos configurar nada para isso!

Criação de arquivo de teste: Vamos criar um arquivo especial para testes relacionados a planetas.

php artisan make:test PlanetApiTest

Este comando criará o arquivo tests/Feature/PlanetApiTest.php. A palavra Feature significa que vamos testar a funcionalidade como um todo (por exemplo, "o usuário pode criar um planeta?"), e não uma pequena classe individual.


3. Anatomia de um teste: Preparação, Ação, Verificação

Abra tests/Feature/PlanetApiTest.php. Dentro dele, escreveremos nosso primeiro teste. Um bom teste sempre consiste em três partes (Arrange, Act, Assert).

<?php

namespace Tests\Feature;

use App\Models\Planet; // Não se esqueça de importar o modelo
use Illuminate\Foundation\Testing\RefreshDatabase; // Ferramenta crucial!
use Tests\TestCase;

class PlanetApiTest extends TestCase
{
    // Este trait "magicamente" limpa e recria
    // nosso banco de dados de teste antes de cada teste.
    // Isso garante que os testes não afetem uns aos outros.
    use RefreshDatabase;

    /**
     * Teste: o endpoint para obter a lista de planetas funciona corretamente.
     * Os nomes dos testes devem ser significativos!
     */
    public function test_can_get_all_planets(): void
    {
        // 1. PREPARAÇÃO (Arrange)
        // Criamos 3 planetas falsos em nosso banco de dados de teste
        // usando a factory que criamos anteriormente.
        Planet::factory()->count(3)->create();

        // 2. AÇÃO (Act)
        // Simulamos uma requisição GET real para nossa API.
        $response = $this->getJson('/api/planets');

        // 3. VERIFICAÇÃO (Assert)
        // Verificamos se tudo correu como deveria.
        $response->assertStatus(200); // Esperamos que o servidor responda "200 OK"
        $response->assertJsonCount(3); // Esperamos que haja exatamente 3 planetas na resposta
    }
}
Pontos-chave:

  • use RefreshDatabase: Este trait é seu melhor amigo. Ele garante que cada teste comece com uma "folha em branco", com um banco de dados vazio.
  • Planet::factory(): As factories são ideais para criar dados de teste.
  • $this->getJson(): Este é um método especial do Laravel para enviar requisições de API dentro dos testes.
  • assert...(): Estas são "asserções" ou "verificações". Se pelo menos uma delas não for satisfeita, o teste falhará.

4. Testando operações básicas (CRUD)

Vamos escrever testes para criar, atualizar e excluir planetas.

A. Teste para criação de planeta (POST)

<?php
public function test_can_create_a_planet(): void
{
    // 1. Preparação: preparamos os dados para o novo planeta
    $planetData = [
        'name' => 'Kepler-186f',
        'description' => 'Primeiro exoplaneta do tamanho da Terra na zona habitável.',
        'size_km' => 14000,
        'solar_system' => 'Kepler-186'
    ];

    // 2. Ação: enviamos uma requisição POST com os dados
    $response = $this->postJson('/api/planets', $planetData);

    // 3. Verificação
    $response->assertStatus(201); // Esperamos o status "201 Created"
    $response->assertJsonFragment(['name' => 'Kepler-186f']); // Verificamos se o nome criado está na resposta

    // A verificação mais importante: os dados realmente foram para o banco de dados?
    $this->assertDatabaseHas('planets', [
        'name' => 'Kepler-186f'
    ]);
}

B. Teste para exclusão de planeta (DELETE)

<?php
public function test_can_delete_a_planet(): void
{
    // 1. Preparação: criamos o planeta que vamos excluir
    $planet = Planet::factory()->create();

    // 2. Ação: enviamos uma requisição DELETE
    $response = $this->deleteJson("/api/planets/{$planet->id}");

    // 3. Verificação
    $response->assertStatus(204); // Esperamos "204 No Content" - exclusão bem-sucedida

    // Verificamos se o registro realmente desapareceu do banco de dados
    $this->assertDatabaseMissing('planets', [
        'id' => $planet->id
    ]);
}


5. Testando cenários "ruins"

Testar casos de sucesso é bom. Mas é ainda mais importante testar erros!

A. Teste para erro de validação

<?php
public function test_creation_fails_with_invalid_data(): void
{
    // 2. Ação: enviamos dados intencionalmente incorretos
    $response = $this->postJson('/api/planets', ['name' => '']); // Nome vazio

    // 3. Verificação
    $response->assertStatus(422); // Esperamos "422 Unprocessable Entity"
    $response->assertJsonValidationErrors('name'); // Esperamos que o erro seja especificamente no campo 'name'
}

B. Teste para "não encontrado" (404)

<?php
public function test_returns_404_for_non_existent_planet(): void
{
    // 2. Ação: solicitamos um planeta com um ID inexistente
    $response = $this->getJson('/api/planets/99999');

    // 3. Verificação
    $response->assertStatus(404); // Esperamos "404 Not Found"
}


6. Executando os testes

Agora que os testes estão escritos, executá-los é muito simples. Execute no terminal:

php artisan test

Laravel encontrará todos os seus testes e os executará um por um. Se tudo ocorrer bem, você verá uma saída verde. Se algum teste falhar, você verá uma saída vermelha com uma descrição detalhada do erro, o que permitirá que você o corrija rapidamente.

Para executar apenas um arquivo específico:

php artisan test tests/Feature/PlanetApiTest.php


8. Cobertura de Código (Code Coverage)

Passo 1: Instalação do Xdebug

Para coletar informações de cobertura de código, a extensão PHP — Xdebug é necessária.

Envie seu php -i para o wizard e siga as instruções.

Passo 2: Configuração de phpunit.xml

<phpunit ... >
    <coverage processUncoveredFiles="true">
        <include>
            <directory suffix=".php">./app</directory>
        </include>
    </coverage>
</phpunit>

Passo 3: Execução com relatório

php artisan test --coverage-html=coverage
Relatório: Abra coverage/index.html no navegador


9. Integração com Postman

Automação via Newman:

  1. Exporte a coleção do Postman para tests/Postman/SpaceApi.postman_collection.json
  2. Instale o Newman:
    npm install -g newman
    
  3. Adicione o script em composer.json:
    "scripts": {
        "test:postman": "newman run tests/Postman/SpaceApi.postman_collection.json"
    }
    
  4. Execução:
    composer test:postman
    

Quiz para fixação

1. Comando para criar uma classe de teste:

2. O trait RefreshDatabase é usado para:

3. Método para verificar a estrutura JSON:

4. As factories no Laravel são necessárias para:

5. Ferramenta para executar coleções Postman a partir da CLI:

🚀 Resumo do Capítulo:

Você realizou um ciclo completo de testes de pré-voo! Agora seu API irá:

  • ✅ Configurar o ambiente de teste sem esforço extra
  • 🛡️ Escrever testes seguindo o princípio "Preparação-Ação-Verificação".
  • 📊 Testar tanto cenários de sucesso (CRUD) quanto erros (validação, 404).
  • 🔁 Executar testes com um único comando e ter confiança no seu código.

A nave espacial está pronta para o lançamento! Você concluiu a seção sobre a criação de API com Laravel.

📌 Verificação final:

  1. Execute php artisan test
  2. Certifique-se de que todos os testes passem (luz verde!)
  3. Verifique o relatório de cobertura

⚠️ Se os testes falharem:

  • Verifique o funcionamento da API via Postman
  • Certifique-se de que o BD de teste esteja configurado
  • Use dd($response->content()) para depuração

Parabéns pela conclusão do Capítulo 2! Você não apenas criou uma API, mas também construiu uma "nave espacial" confiável e testada, pronta para futuras missões.

🌌 Próximos passos:

  1. Configuração de autenticação (Sanctum)
  2. Documentação da API com Swagger
  3. Implantação no servidor (Forge, VPS)
  4. Desenvolvimento do frontend com Vue/React

Sucesso no lançamento da sua missão espacial! No próximo capítulo, exploraremos a escrita de uma API do zero 🚀