Na segunda parte da nossa série sobre testes automatizados e TDD mostraremos alguns exemplos práticos de testes automatizados utilizando PHP. Escolhi PHP por ser a linguagem que tenho maior domínio, mas ressalto que os conceitos aqui apresentados podem ser aplicados a qualquer linguagem de programação e ferramenta (com algumas adaptações, é claro).
Planejar testes
Antes de partirmos para o código, vale lembrar que em uma situação real nem sempre conseguiremos automatizar todos os testes, nesses casos, é necessário, fazer uma análise criteriosa de quais casos de teste devem ser automatizados. Alguns critérios de escolha são:
- Funcionalidades importantes do sistema;
- Funcionalidades utilizadas com frequência;
- Casos de teste que envolvem riscos para o Negócio.
Nessa etapa são planejados o ambiente de teste utilizado, cronograma de execução, entregáveis gerados com a execução, equipe envolvida, escopo de automação, entre outros.
Tá na hora do código
Um pouco de contexto: imagine uma aplicação bem simples que consiste em um catálogo de programas (filmes/séries etc.) onde o usuário deve ser capaz de marcar como assistido/não assistido.
O programa (filme/série) tem as seguintes propriedades: id, nome, resumo e assistido. Nossa classe Movie.php
ficou assim:
OBS: já estou utilizando alguns recursos novos do PHP 8, como propriedades nomeadas, mas nada impediria de extrair as propriedades de um array ou em parâmetros separados no construtor.
<?php
declare(strict_types=1);
class Movie
{
private $watched = false;
public function __construct(
private string $id,
private string $name,
private string $summary
) {}
public function toggleWatched() {
$this->watched = !$this->watched;
}
public function isWatched() {
return $this->watched;
}
}
Vamos ao teste
Nosso primeiro teste será bem simples: o usuário deve poder marcar um filme como assistido/não assistido. Faremos esse teste de duas maneiras (com e sem o auxílio de uma ferramenta - no caso o PHPUnit), ou seja, queremos se o método toggleWatched
funciona conforme o esperado.
Nosso objetivo com esse primeiro teste é demonstrar o conceito conhecido como AAA (Arrange, Act, Assert) que consiste em uma divisão lógica do código em 3 etapas:
- Arrange: o setup inicial do teste, é aqui que definimos tudo que o teste utilizará;
- Act: é nessa etapa que executamos de fato o que queremos testar;
- Assert: por fim verificamos se o resultado da execução é o resultado esperado.
Nosso arquivo test.php
ficou da seguinte maneira:
<?php
declare(strict_types=1);
require 'Movie.php';
// Arrange
// Instanciamos o objeto $movie
$movie = new Movie(
id: '1',
name: 'Brooklyn 99',
summary: ''
);
// Act
$movie->toggleWatched();
// Assert
if ($movie->isWatched() === true) {
echo "PASSED".PHP_EOL;
} else {
echo "FAIL".PHP_EOL;
}
Vejamos os 3 A's em ação:
- Arrange: nessa etapa instanciamos um novo objeto da classe
Movie
; - Act: nessa etapa chamamos o método
toggleWatched
que, conforme definimos, inverte o valor da propriedade$watched
, que inicia comofalse
; - Assert: por fim verificamos se o resultado é o esperado, em caso de sucesso imprime no terminal
PASSED
, em caso de falha mostraFAIL
.
Para executar esse teste basta executar o comando php test.php
.

Como vimos, é perfeitamente possível realizar testes automatizados sem o auxílio de nenhuma ferramenta, porém à medida que os testes crescem e ficam mais complexos sua programação também ficará mais complexa.
Além disso as ferramentas possuem uma interface mais amigável, facilitando a visualização de quais erros passaram e quais falharam.
Utilizando o PHPUnit
Primeiramente precisamos instalar o phpunit, utilizaremos o composer para isso com o comando sugerido pela documentação oficial composer require --dev phpunit/phpunit ^9.5
.
Por convenção o PHPUnit procura algumas condições específicas para executar os testes, são elas:
- O arquivo da classe de teste deve terminar em Test - é recomendado utilizar [nomeDaClasseTestada]Test;
- Os métodos da classe de teste devem iniciar com test - exemplo : testMetodoIsTrueDeveRetornarTrue
- Os métodos de teste devem ter pelo menos um
assert
. - A classe de teste deve extender de
PHPUnit\Framework\TestCase
.
NOTA: Lembrando que todas essas convenções podem ser configuradas no arquivo phpunit.xml
, mas não entraremos nesse nível detalhe nesse momento.
A seguir vamos alterar nosso arquivo test.php
seguindo as convenções do PHPUnit, sendo assim renomeamos o arquivo para MovieTest.php
e seu conteúdo ficou assim:
<?php declare(strict_types=1);
require 'Movie.php';
use PHPUnit\Framework\TestCase;
class MovieTest extends TestCase
{
public function testToggleWatched()
{
// Arrange
// Instanciamos o objeto $movie
$movie = new Movie(
id: '1',
name: 'Brooklyn 99',
summary: ''
);
// Act
$movie->toggleWatched();
// Assert
$this->assertTrue($movie->isWatched());
}
}
Perceba que mantivemos a estratégia dos 3 A's apenas ajustamos os métodos para que o PHPUnit encontrasse os testes para execução. Quando executamos o comando php vendor/bin/phpunit MovieTest.php
temos o seguinte resultado:

O resultado do teste nos mostra que 1 teste foi executado e 1 assertion passou. Se utilizarmos o parâmetro --colors
temos um resultado mais amigável:

Em caso de falha o PHPUnit também nos mostra qual classe / assertion a falha ocorreu:

Dessa forma fica muito mais fácil e rápido identificar qual teste falhou.
Conclusão
Nessa parte vimos mais alguns conceitos sobre testes automatizados, a importância de planejar os testes, como compor e escrever um teste, com e sem o auxílio de ferramentas. Também vimos as facilidades que a utilização de ferramentas especializadas em testes automatizados nos conferem, tanto na visualização, quanto na execução dos testes.
Apesar de utilizarmos PHP e o PHPUnit nos exemplos esses conceitos podem ser aplicados em qualquer framework ou linguagem.
Na próxima parte entraremos em conceitos um pouco mais avançados no mundos dos testes: dublês de teste. Falaremos sobre os tipos de dublês de testes e traremos exemplos de como utilizá-los no PHPUnit. Nos vemos lá!