M

Manual Rede das Artes

Desenvolvimento

Testes

Escreva e execute testes com PHPUnit no Mapas Culturais: estrutura, classe base, builders, directors e exemplos práticos.

O Mapas Culturais usa PHPUnit 10 em sua suíte de testes. Como os testes exigem conexão com um banco real, eles precisam rodar dentro do contêiner Docker, ou em um ambiente equivalente com PostgreSQL e PostGIS disponíveis.

Executando testes

# Roda a suíte completa
docker compose exec mapas vendor/bin/phpunit tests/

# Roda um único arquivo de teste
docker compose exec mapas vendor/bin/phpunit tests/src/EntitiesTest.php

# Roda um único método de teste
docker compose exec mapas vendor/bin/phpunit tests/src/EntitiesTest.php --filter testAgentCreation

# Via script auxiliar
./scripts/run-tests-docker.sh

Os testes devem rodar dentro do contêiner. Executar vendor/bin/phpunit diretamente na máquina host vai falhar, porque o host não tem acesso às instâncias de PostgreSQL e Redis das quais a suíte depende.

O PHPUnit é configurado em phpunit.xml, na raiz do repositório. Por padrão, os testes rodam em ordem aleatória (executionOrder="random"), o que ajuda a expor cedo dependências ocultas entre testes.

Estrutura de testes

tests/
  src/
    Abstract/           → Classes base (`TestCase`, `Builder`, `Director`)
    Builders/           → Builders de entidades, com API fluente para montar dados de teste
    Directors/          → Directors de nível mais alto, compostos sobre builders
    Factories/          → Helpers de fábrica
    Traits/             → Traits compartilhadas (`Faker`, `AgentDirector` etc.)
    Fixtures.php        → Dados de fixture compartilhados
    fixtures/           → Arquivos de fixture (`JSON` etc.)
    EntitiesTest.php    → Arquivo de teste de exemplo
    OpportunityPhasesTest.php
    EvaluationMethodTechnicalTest.php
    ...

A classe base TestCase

Todos os testes estendem Tests\Abstract\TestCase, que por sua vez estende TestCase do PHPUnit. A classe base cuida de:

  • iniciar uma transação de banco em setUp()
  • desfazê-la em tearDown(), garantindo que cada teste deixe o banco limpo
  • oferecer helpers de login() e logout()
  • expor $this->app como singleton da aplicação
<?php

namespace Tests;

use Tests\Abstract\TestCase;

class MyFeatureTest extends TestCase
{
    public function testSomething(): void
    {
        // The database is in a transaction.
        // Any changes made here are rolled back after the test.

        $app = $this->app;

        // Create a user and log in
        $user = $this->userDirector->createUser();
        $this->login($user);

        // Your assertions here
        $this->assertTrue(true);
    }
}

Esse padrão de rollback permite escrever no banco livremente sem precisar limpar nada depois. Cada teste recebe um snapshot limpo.

Escrevendo um teste

Crie um arquivo em tests/src/ com nome relacionado à funcionalidade testada. A classe deve estender Tests\Abstract\TestCase.

<?php

namespace Tests;

use Tests\Abstract\TestCase;
use Tests\Traits\UserDirector;
use Tests\Traits\AgentDirector;

class MyFeatureTest extends TestCase
{
    use UserDirector, AgentDirector;
}

Builders oferecem uma API fluente para construir entidades. Directors encapsulam builders para criar cenários comuns em uma única chamada.

public function testAgentHasOwner(): void
{
    $user = $this->userDirector->createUser();
    $this->login($user);

    $agent = $this->agentDirector->createAgent($user->profile);

    $this->assertEquals($user->id, $agent->getOwnerUser()->id);
}

A classe base fornece helpers para simular requisições à API e fazer assertions sobre a resposta:

public function testApiReturnsAgent(): void
{
    $user  = $this->userDirector->createUser();
    $agent = $this->agentDirector->createAgent($user->profile);

    $response = $this->request('GET', "/api/agent/{$agent->id}");

    $this->assertEquals(200, $response->getStatusCode());
}
docker compose exec mapas vendor/bin/phpunit tests/src/MyFeatureTest.php

Builders

Os builders em tests/src/Builders/ constroem instâncias de entidades com dados válidos. Eles usam FakerPHP para gerar dados fictícios realistas.

Builders disponíveis:

BuilderEntity
AgentBuilderAgent
SpaceBuilderSpace
EventBuilderEvent
OpportunityBuilderOpportunity
RegistrationBuilderRegistration
UserBuilderUser
SealBuilderSeal
ProjectBuilderProject
EvaluationMethodSimpleBuilderSimple evaluation method
EvaluationMethodTechnicalBuilderTechnical evaluation method
EvaluationMethodDocumentaryBuilderDocumentary evaluation method
EvaluationMethodQualificationBuilderQualification evaluation method
ValuerBuilderEvaluator (valuer)
QuotaBuilderEvaluation quota

Exemplo, usando AgentBuilder diretamente:

use Tests\Builders\AgentBuilder;

$user = $this->userDirector->createUser();
$this->login($user);

$agent = (new AgentBuilder())
    ->reset($user)
    ->fillRequiredProperties()
    ->build();

$this->assertNotNull($agent->id);

Directors

Os directors em tests/src/Directors/ compõem builders em helpers de nível mais alto, capazes de criar entidades completas e prontas para uso. Use directors para manter o setup dos testes enxuto.

// Cria uma oportunidade completa, com fases e método de avaliação
$opportunity = $this->opportunityDirector->createOpportunity($user->profile);

Os directors são incluídos nas classes de teste via traits:

use Tests\Traits\UserDirector;
use Tests\Traits\AgentDirector;
use Tests\Traits\SpaceDirector;
use Tests\Traits\OpportunityDirector;

FakerPHP

Os builders usam FakerPHP para gerar dados de teste realistas. A instância do faker fica disponível dentro dos builders pela trait Faker:

// Dentro de um builder
$this->instance->name             = $this->faker->name();
$this->instance->shortDescription = $this->faker->text(400);
$this->instance->document         = $this->faker->cpf();

Métodos auxiliares em TestCase

MétodoDescrição
$this->login(User $user)Autentica como o usuário informado
$this->logout()Limpa o usuário autenticado
$this->processJobs(string $date)Executa jobs pendentes até a data informada
$this->processPCache()Recria o cache de permissões

Gerando cobertura

A geração de cobertura exige a extensão pcov, já disponível no contêiner:

docker compose exec mapas \
  php -d pcov.enabled=1 \
      -d pcov.directory=/var/www/src \
      -d memory_limit=512M \
  vendor/bin/phpunit \
      --configuration phpunit.xml \
      --coverage-clover tests/coverage/clover.xml

Os caminhos de código-fonte cobertos são configurados em phpunit.xml, sob <source>. Expanda os diretórios incluídos conforme novos módulos passarem a ter testes.

Convenções para arquivos de teste

  • uma classe de teste por arquivo
  • nomes de arquivo e classe em PascalCase, com sufixo Test, como OpportunityPhasesTest.php
  • nomes de métodos de teste começando com test em camelCase, como testRegistrationStatusChange
  • use mensagens descritivas nas assertions, como último argumento do método
$this->assertEquals(
    $expected,
    $actual,
    'Registration status should be SELECTED after evaluation is complete'
);

Esse material é fruto do Programa de Difusão Nacional - Funarte Redes das Artes, realizado pelo Laboratório do Futuro (entidade vinculada à Universidade Federal do Ceará) no ano de 2025.

Felicilab
Mutirão
Lab do Futuro UFC
UFC
Rede das Artes Funarte
Funarte
MinC Governo Federal

On this page