Há tempos eu venho lendo sobre XP (eXtreme Programming), Scrum e Feature Driven Development (FDD). São metodologias ágeis de desenvolvimento de software. O engraçado é que praticamente, ao meu ver, fazem a mesma coisa, porém de forma diferente. E todas elas frizam a importância dos testes unitários e, mais especificadamente, testes unitários antes do desenvolvimento, o chamado TDD (Test Driven Development). Como nunca havia trabalhado desta forma, ainda não tinha uma opinião sobre isso. Apenas comentários e depoimentos de que usa. Somado a isso, veio aquele senso de desafio, de inovação e curiosidade.
Faz alguns meses, e decidimos, eu e o Emanuel Zabka, implantar o TDD no desenvolvimento na empresa em que trabalhamos. Academicamente é falado muito em refactoring e mudanças de requisitos, mas na prática, eu nunca havia notado a quantidade de modificações que um mesmo código/classe/arquivo é modificado num curto período de tempo e a longo prazo.
Os testes me ajudaram a enxergar, não só as dependências do sistema, como também, acoplamentos desnecessários; a qualidade dos códigos; do design do projeto; e, consequentemente, diminuiu muito os bugs mais corriqueiros, como validação de campos. Mesmo tendo várias coisas boas, há coisas ruins, como aumento do tempo de desenvolvimento – o que, apesar de nunca ter medido, diminui o retrabalho e tempo utilizado no futuro em correções de bugs -, aumento da complexidade da arquitetura – a fim de manter uma maior coesão com baixo acoplamento, entre outros menos relevantes.
Unit Test
The basic concept of unit testing is write more code which will test the main code we’ve written, by “throwing” sample data at it and examining what it gets back.
Harry Fuecks
Enfim, uma boa definição de testes unitários é esta supracitada. São escritos mais códigos para testar o código principal, utilizando dados de testes para analisar o comportamento e o retorno do código sendo testado.
CakePHP
- Framework de desenvolvimento rápido pra Web com PHP
- Utiliza padrões MVC e ORM
- Extensível para desenvolvimento, manutenção e deploying.
- OpenSource / Comunidade muito ativa e amigável
- Orientada a Objetos
- Mais detalhes sobre o CakePHP
SimpleTest
- Praticamente mesma coisa que JUnit, JMock e PHPUnit.
- Guiado através de asserções
- Possibilidade navegação em requisições HTTP para testar interface gerada (HTML)
- OpenSource
- Orientada a Objetos
- Mais detalhes sobre o SimpleTest
CakePHP e SimpleTest
- Startup (criação do arquivo, casos de testes básicos) dos testes unitários automaticamente
- Customizações no template de Report (Web com template padrão)
- Rápida execução de testes individualizados
- Rápida execução de grupos de testes (execução de vários testes unitários sequencialmente)
- Pode-se usar Mock para objetos internos do CakePHP ou da aplicação
- Pode-se testar aplicação toda (APP + Plugins)
- Pode-se testar somente a aplicação (APP)
- Pode-se testar plugins separadamente
- Pode-se testar em modo batch
- Integração dos dois frameworks
Convenções e Padrões
Para o SimpleTest não há padronização no nome dos arquivos, mas o CakePHP estabelece um a partir da convenção das classes utilizados por ele. Ex: respectivamente as classes de controller e model de um Post:
- O nome da classe contida no arquivo é derivado a partir do nome do mesmo.
- Esta classe deve extender a classe CakeTestCase ou CakeWebTestCase
- A assinatura dos métodos que contém asserções (métodos de teste) devem iniciar com “test”, como em testPostControllerAddPost().
- Métodos que são executados como eventos:
- start()
- Primeiro método chamado. Executado quando se iniciam os testes
- end()
- Último método chamado. Executado quando se concluí todos os casos testes
- startCase()
- Executado antes do caso de teste começar a ser testado (lembrando que um teste pode ser composto de um ou mais casos de teste)
- endCase()
- Executado depois que o caso de teste foi testado por completo
- before($method)
- Anuncia o início de um método de teste
- after($method)
- Anuncia o término de um método de teste
- startTest($method)
- Executado antes de um caso de teste iniciar
- endTest($method)
- Executado depois que um caso de teste termina
Mais detalhes sobre as convenções
Fixtures
Fixtures são uma forma de utilizar dados de teste. São matrizes de dados que correspondem à registros em um banco de dados.
Cada Model possui uma Fixture, que irá não só ter os dados como a representação dos campos que compõe a tabela do banco, pois a partir destes dados o framework irá:
- Criar uma tabela prefixada (por padrão) de “test_suite_” no banco de dados para cada fixture necessário (ou seja, cada model utilizado).
- Inserir os dados de teste na tabela de teste
- Executar os testes em cima destes registros
- Remover os dados da tabela de teste
- Remover a tabela no banco de dados.
Ou seja, assim é garantido que os dados serão sempre os mesmos e que não comprometerá a base de dados atual com sujeira, podendo-se executar
estes testes a qualquer momento atrás de problemas. Testes que envolvem banco de dados com índices únicos, chaves primárias ou outras constraints
estão livres de erros (erros não propositais) durante os testes.
Asserções
- assertTrue($x)
- assertFalse($x)
- assertNull($x)
- assertEqual($x, $y)
- assertIsA($object, ‘ClassName’)
- assertIdentical($x, $y)
- assertPattern(’/REGEX/’, $x)
- expectError();
Se você se interessou, para mais detalhes sobre os testes unitários no CakePHP, recomendo a leitura deste post da Debuggable: Unit Testing in CakePHP Part 1 – Introduction to Unit Testing
Agradecimentos especiais a André Leitzke e Viviane de Souza por terem me ajudado com a caracterização e descrição do framework!
0sem comentários ainda