Prev Next

Capítulo 1. Automatizando Testes

Mesmo bons programadores cometem erros. A diferença entre um bom programador e um mau programador é que o bom programador usa testes para detectar seus erros o mais cedo possível. Quanto antes você testar por um erro, maiores são suas chances de encontrá-lo e consertá-lo. Isso explica porque deixar os testes para um momento logo antes do lançamento do programa é tão problemático. A maioria dos erros nem sequer chega a ser encontrado, e o custo de consertar aqueles que você encontra é tão alto que você tem que fazer uma triagem com os erros porque você simplesmente não consegue consertar todos.

Testar com o PHPUnit não é uma atividade totalmente diferente do que você já costuma fazer. É apenas uma forma diferente de fazê-lo. A diferença está entre testar, isto é, verificar que seu programa se comporta como o esperado, e fazer uma bateria de testes, fragmentos de código executáveis que automaticamente testam se as partes (unidades) do programa estão corretas. Esses fragmentos de código executáveis são chamados de testes unitários.

Neste capítulo vamos de um simples código de teste baseado em printaté um teste totalmente automatizado. Imagine que nos peçam para testar um vetorembutido do PHP. Uma pequena funcionalidade a se testar é a função count(). Para um vetor criado recentemente esperamos que a função count() retorne 0. Após adicionarmos um elemento, count() deverá retornar 1. Exemplo 1.1 mostra o que queremos testar.

Exemplo 1.1: Testando operações de vetores

<?php
$componente = array();
// espera-se que $componente esteja vazio.

$componente[] = 'elemento';
// espera-se que $componente contenha um elemento.
?>

Um jeito bem simples de verificar se estamos obtendo os resultados que esperamos é imprimir o resultado de count() antes e depois de adicionar o elemento (veja Exemplo 1.2). Se obtivermos 0 e depois 1, array e count() se comportaram como esperado.

Exemplo 1.2: Usando print para testar operações de um vetor

<?php
$componente = array();
print count($componente) . "\n";

$componente[] = 'elemento';
print count($componente) . "\n";
?>
0
1

Agora gostaríamos de mudar de testes que exigem interpretação manual para testes que podem executar automaticamente. Em Exemplo 1.3, escrevemos a comparação do valor esperado e do real em nosso código de teste e imprimimos ok se os valores forem iguais. Se alguma vez virmos uma mensagem não ok saberemos que algo está errado.

Exemplo 1.3: Comparando os valores esperado e real para testar operações de vetores

<?php
$componente = array();
print count($componente) == 0 ? "ok\n" : "não ok\n";

$componente[] = 'elemento';
print count($componente) == 1 ? "ok\n" : "não ok\n";
?>
ok
ok

Agora fatoramos a saída de comparação dos valores esperado e real em uma função que gera uma Exceção (Exception) onde há uma discrepância (Exemplo 1.4). Isso nos traz dois benefícios: a escrita dos testes se torna mais fácil e só obteremos saída quando algo estiver errado.

Exemplo 1.4: Usando uma função de asserção para testar operações de vetores

<?php
$componente = array();
assertTrue(count($componente) == 0);

$componente[] = 'elemento';
assertTrue(count($componente) == 1);

function assertTrue($condicao)
{
if (!$condicao) {
throw new Exception('Asserção falhou.');
}
}
?>

O teste agora está totalmente automatizado. Em vez de apenas testar como fizemos em nossa primeira versão, com esta versão temos um teste automatizado.

O objetivo de usar testes automatizados é cometer menos erros. Ainda que seu código não fique perfeito, mesmo com testes excelentes, você perceberá uma redução dramática nos defeitos assim que começar a automatizar os testes. Testes automatizados darão a você uma justificada confiança em seu código. Você poderá usar essa confiança para atravessar barreiras mais difíceis de design (Refatoração), melhorar as relações com sua equipe (Testes Inter-Equipes) e clientes, além de voltar para casa toda noite com a prova de que seu sistema está melhor agora do que estava de manhã, graças aos seus esforços.

Prev Next
1. Automatizando Testes
2. Objetivos do PHPUnit
3. Instalando o PHPUnit
PEAR
Composer
PHP Archive (PHAR)
Pacotes opcionais
Atualizando
4. Escrevendo Testes para o PHPUnit
Dependências de Testes
Provedores de Dados
Testando Exceções
Testando Erros PHP
Testando Saídas
Asserções
assertArrayHasKey()
assertClassHasAttribute()
assertClassHasStaticAttribute()
assertContains()
assertContainsOnly()
assertContainsOnlyInstancesOf()
assertCount()
assertEmpty()
assertEqualXMLStructure()
assertEquals()
assertFalse()
assertFileEquals()
assertFileExists()
assertGreaterThan()
assertGreaterThanOrEqual()
assertInstanceOf()
assertInternalType()
assertJsonFileEqualsJsonFile()
assertJsonStringEqualsJsonFile()
assertJsonStringEqualsJsonString()
assertLessThan()
assertLessThanOrEqual()
assertNull()
assertObjectHasAttribute()
assertRegExp()
assertStringMatchesFormat()
assertStringMatchesFormatFile()
assertSame()
assertSelectCount()
assertSelectEquals()
assertSelectRegExp()
assertStringEndsWith()
assertStringEqualsFile()
assertStringStartsWith()
assertTag()
assertThat()
assertTrue()
assertXmlFileEqualsXmlFile()
assertXmlStringEqualsXmlFile()
assertXmlStringEqualsXmlString()
Saída de Erro
Casos Extremos
5. O executor de testes em linha-de-comando
Comutadores de linha-de-comando
6. Ambientes
Mais setUp() que tearDown()
Variantes
Compartilhando Ambientes
Estado Global
7. Organizando Testes
Compondo uma Suíte de Testes usando o Sistema de Arquivos
Compondo uma Suíte de Testes Usando uma Configuração XML
8. Testando Bancos de Dados
Fornecedores Suportados para Testes de Banco de Dados
Dificuldades em Testes de Bancos de Dados
Os quatro estágios dos testes com banco de dados
1. Limpar o Banco de Dados
2. Configurar o ambiente
3–5. Executar Teste, Verificar saída e Teardown
Configuração de Caso de Teste de Banco de Dados do PHPUnit
Implementando getConnection()
Implementando getDataSet()
E quanto ao Esquema do Banco de Dados (DDL)?
Dica: Use seu próprio Caso Abstrato de Teste de Banco de Dados
Entendendo Conjunto de Dados e Tabelas de Dados
Implementações disponíveis
Cuidado com Chaves Estrangeiras
Implementando seus próprios Conjuntos de Dados/ Tabelas de Dados
A API de Conexão
API de Asserções de Banco de Dados
Assertando a contagem de linhas de uma Tabela
Assertando o Estado de uma Tabela
Assertando o Resultado de uma Query
Assertando o Estado de Múltiplas Tabelas
Perguntas Mais Frequentes
O PHPUnit vai (re)criar o esquema do banco de dados para cada teste?
Sou forçado a usar PDO em minha aplicação para que a Extensão para Banco de Dados funcione?
O que posso fazer quando recebo um Erro Too much Connections?
Como lidar com NULL usando Conjuntos de Dados XML Plano / CSV?
9. Testes Incompletos e Pulados
Testes Incompletos
Pulando Testes
Pulando Testes usando @requires
10. Dublês de Testes
Esboços (stubs)
Objetos Falsos
Esboçando e Falsificando Serviços Web
Esboçando o Sistema de Arquivos
11. Práticas de Teste
Durante o Desenvolvimento
Durante a Depuração
12. Desenvolvimento Guiado por Testes
Exemplo da Conta Bancária
13. Desenvolvimento Guiado por Comportamento
Exemplo do Jogo de Boliche
14. Análise de Cobertura de Código
Especificando métodos cobertos
Ignorando Blocos de Código
Incluindo e Excluindo Arquivos
Casos Extremos
15. Outros Usos para Testes
Documentação Ágil
Testes Inter-Equipes
16. Gerador de Esqueleto
Gerando um Esqueleto de Classe de Caso de Teste
Gerando uma Classe Esqueleto de uma Classe de Caso de Teste
17. PHPUnit e Selenium
Servidor Selenium
Instalação
PHPUnit_Extensions_Selenium2TestCase
PHPUnit_Extensions_SeleniumTestCase
18. Registrando
Resultados de Teste (XML)
Resultados de Teste (TAP)
Resultados de Teste (JSON)
Cobertura de Código (XML)
Cobertura de Código (TEXTO)
19. Estendendo o PHPUnit
Subclasse PHPUnit_Framework_TestCase
Escreva asserções personalizadas
Implementando PHPUnit_Framework_TestListener
Subclasse PHPUnit_Extensions_TestDecorator
Implementando PHPUnit_Framework_Test
A. Assertions
B. Anotações
@author
@backupGlobals
@backupStaticAttributes
@codeCoverageIgnore*
@covers
@coversNothing
@dataProvider
@depends
@expectedException
@expectedExceptionCode
@expectedExceptionMessage
@group
@outputBuffering
@requires
@runTestsInSeparateProcesses
@runInSeparateProcess
@test
@testdox
@ticket
C. O arquivo de configuração XML
PHPUnit
Suítes de Teste
Grupos
Incluindo e Excluindo Arquivos para Cobertura de Código
Registrando
Ouvintes de Teste
Setting PHP INI settings, Constants and Global Variables
Configurando Navegadores para Selenium RC
D. Índice
E. Bibliografia
F. Copyright