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
toggleWatchedque, 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á!