Testes

Testes são um processo indispensável do desenvolvimento de software. Estando conscientes disso ou não, nós conduzimos testes o tempo todo enquanto desenvolvemos uma aplicação Web. Por exemplo, quando escrevemos uma classe em PHP, podemos usar algum comando echo ou die para mostrar que implementamos um método corretamente; quando implementamos uma página da Web contendo um formulário HTML complexo, nós podemos tentar digitar alguns dados de teste para termos certeza de que a página interage conosco da maneira esperada. Desenvolvedores mais avançados escreveriam algum código para automatizar esse processo de testes de modo que toda vez que precisarmos testar alguma coisa, só precisamos chamar o código e deixar que o computador realize os testes por nós. Isso é conhecido como testes automatizados, que é o assunto principal deste capítulo.

O suporte a testes fornecido pelo Yii inclui testes unitários e testes funcionais.

Um teste unitário verifica que uma única unidade de código está funcionando conforme o esperado. Na programação orientada a objetos, a unidade de código mais básica é uma classe. Desta forma, um teste unitário precisa principalmente verificar que cada um dos métodos da interface da classe funcionam adequadamente. Ou seja, dados diferentes parâmetros de entrada, o teste verifica se o método retorna os resultados esperados. Testes unitários geralmente são desenvolvidos pelas pessoas que escrevem as classes sendo testadas.

Um teste funcional verifica que uma funcionalidade (por exemplo, gerenciamento de posts em um sistema de blog) está funcionando conforme o esperado. Comparado com um teste unitário, um teste funcional está em um nível superior, porque uma funcionalidade sendo testada frequentemente envolve múltiplas classes. Testes funcionais geralmente são desenvolvidos por pessoas que conhecem muito bem os requisitos do sistema (elas poderiam ser tanto desenvolvedores quanto engenheiros de qualidade).

1. Desenvolvimento Orientado a Testes

A seguir mostramos os ciclos de desenvolvimento no assim chamado desenvolvimento orientado a testes (TDD):

  1. Crie um novo teste que cubra uma funcionalidade que será implementada. Espera-se que o teste falhe em sua primeira execução, porque a funcionalidade ainda precisa ser implementada.
  2. Rode todos os testes e certifique-se de que o novo teste falha.
  3. Escreva código para fazer o novo teste passar.
  4. Rode todos os testes e certifique-se de que todos passam.
  5. Refatore o código que foi recém-escrito e certifique-se de que todos os testes ainda passam.

Repita os passos de 1 a 5 para avançar na implementação de funcionalidades.

2. Configuração do Ambiente de Teste

Os testes suportados fornecidos pelo Yii requerem PHPUnit 3.5+ e Selenium Remote Control 1.0+. Por favor, consulte as suas documentações sobre como instalar o PHPUnit e o Selenium Remote Control.

Quando usamos o comando de console yiic webapp para criar uma nova aplicação Yii, ele gerará automaticamente os seguintes arquivos e diretórios para nós, para escrevermos e realizarmos novos testes:

testdrive/
   protected/                contendo arquivos da aplicação protegidos
      tests/                 contendo testes para a aplicação
         fixtures/           contendo fixtures do banco de dados
         functional/         contendo testes funcionais
         unit/               contendo testes unitários
         report/             contendo relatórios de cobertura
         bootstrap.php       o script executado logo no início
         phpunit.xml         o arquivo de configuração do PHPUnit
         WebTestCase.php     a classe base para testes funcionais baseados na Web

Conforme mostrado acima, nosso código de testes será posto principalmente em três diretórios: fixtures, functional e unit, e o diretório report será usado para armazenar os relatórios de cobertura do código gerados.

Para executar os testes (sejam testes unitários ou funcionais), podemos executar os seguintes comandos na janela do console:

% cd testdrive/protected/tests
% phpunit functional/PostTest.php    // executa um teste individual
% phpunit --verbose functional       // executa todos os testes em 'functional'
% phpunit --coverage-html ./report unit

O último dos comandos acima executará todos os testes que estão no diretório unit e gerará um relatório de cobertura de código no diretório report. Note que a extensão xdebug precisa estar instalada e ativa para gerar relatórios de cobertura de código.

3. Script de Inicialização dos Testes

Vamos observar o que deve haver no arquivo bootstrap.php. Este arquivo é tão especial porque ele é como o script de entrada e é o ponto de partida quando executamos um conjunto de testes.

$yiit='path/to/yii/framework/yiit.php';
$config=dirname(__FILE__).'/../config/test.php';
require_once($yiit);
require_once(dirname(__FILE__).'/WebTestCase.php');
Yii::createWebApplication($config);

No código acima, primeiro incluímos o arquivo yiit.php do framework Yii, que inicializa algumas constantes globais e inclui todas as classes-mãe de teste necessárias. Então criamos uma instância da aplicação Web usando o arquivo de configuração test.php. Se checarmos o test.php, descobriremos que ele herda do arquivo de configuração main.php e adiciona um componente de aplicação fixture cuja classe é CDbFixtureManager. Nós descreveremos as fixtures em dealhes na próxima seção.

return CMap::mergeArray(
    require(dirname(__FILE__).'/main.php'),
    array(
        'components'=>array(
            'fixture'=>array(
                'class'=>'system.test.CDbFixtureManager',
            ),
            /* descomente o seguinte para prover uma conexão com o banco de dados de teste
            'db'=>array(
                'connectionString'=>'DSN do banco de dados de teste',
            ),
            */
        ),
    )
);

Quando rodamos testes que envolvem o banco de dados, devemos fornecer um banco de dados de teste, de modo que a execução do teste não interfira com as atividades normais do desenvolvimento ou da produção. Para fazê-lo, só precisamos descomentar a configuração db no trecho acima e preencher a propriedade connectionString com o DSN (nome da fonte de dados) do banco de dados de testes.

Com esse script de inicialização, quando rodamos os testes unitários, teremos uma instância da aplicação que é aproximadamente a mesma que responde às requisições Web. A diferença principal é que ela tem o gerenciador de fixtures e está usando o banco de dados de testes.

$Id$

Be the first person to leave a comment

Please to leave your comment.