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.shOs 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()elogout() - expor
$this->appcomo 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.phpBuilders
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:
| Builder | Entity |
|---|---|
AgentBuilder | Agent |
SpaceBuilder | Space |
EventBuilder | Event |
OpportunityBuilder | Opportunity |
RegistrationBuilder | Registration |
UserBuilder | User |
SealBuilder | Seal |
ProjectBuilder | Project |
EvaluationMethodSimpleBuilder | Simple evaluation method |
EvaluationMethodTechnicalBuilder | Technical evaluation method |
EvaluationMethodDocumentaryBuilder | Documentary evaluation method |
EvaluationMethodQualificationBuilder | Qualification evaluation method |
ValuerBuilder | Evaluator (valuer) |
QuotaBuilder | Evaluation 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étodo | Descriçã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.xmlOs 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 sufixoTest, comoOpportunityPhasesTest.php - nomes de métodos de teste começando com
testem camelCase, comotestRegistrationStatusChange - 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.