PhpSpec?
Framework de BDD (Behavior-Driven Development) para o desenvolvimento e design de aplicações php orientadas por comportamento. Para conhecer melhor BDD leia o artigo http://www.urubatan.com.br/comparacao-entre-tdd-e-bdd-como-aprender-um-me-ajudou-com-o-outro/ do blog do Urubatan que é a fonte da imagem.
Instalar PhpSpec
O pacote do phpspec pode ser instalado pelo pear
$ sudo pear config-set preferred_state beta
$ sudo pear channel-discover pear.phpspec.net
$ sudo pear install --all-deps phpspec/PHPSpec
Criar estrutura inicial
Criar o diretório spec na rais do projeto com a seguinte estrutura para acomodar os arquivos de especificação.
Bootstrap da stack do Codeigniter
Criar o arquivo codeigniter-academic/spec/spec_helper.php que será importado a cada nova spec. A primeira linha do código inclui a stack do codeigniter utilizando o mesmo bootstrap customizado do CIUnit, isso possibilita a uitilização de qualquer bibliotecas do framework.
![]() |
photo.png |
Copiar uma imagem-fixture qualquer no diretório
codeigniter-academic/spec/fixtures/photo.png para validar os testes e verificar se a classe ResizeImageJob faz corretamente o redimensionamento de uma imagem.
Após cada exemplo de teste a classe de especificação deve limpar as imagens thumbs geradas para que não inflencie nos demais exemplos.
Refatorar o worker
O worker feito no post anterior foi refatorado para reutilizar as bibliotecas de manipulação de imagem do próprio Codeiginiter. Esta refatoração foi orientada por BDD com o uso do framework PhpSpec.
A classe ResizeImageJob:
- Cria novas imagens de thumbs a partir da original
- Preserva a imagem original
- Permite desfazer a tarefa executada
- Lança uma exception caso não receba um array com parametros
Criar o arquivo da especificação em codeigniter-academic/spec/ResizeImageJobSpec.php.
O código é bem simples, antes de cada exemplo é criado um array com parâmetros com o path para a imagem de fixture, um array com a especificação dos tamanhos dos novos thumbs a serem criados além de outros. Os dois métodos privados server apenas como auxiliares para diminuir a repetição de código e deixá-lo mais DRY.
Extrair a classe responsável pela tarefa
O código do worker (application/workers/resize_worker.php) do post anterior anterior possui mais de uma responsabilidade. Além de administrar o serviço do worker ele ainda manipula as imagens. O objetivo é extrair a responsabilidade de redimensionar as imagens para uma nova classe de job.
A nova classe application/workers/resize_image_job.php encapsula a única responsabilidade de redimensionar as imagens. Ela segue um pouco o design pattern command, recebendo parametros no construtor e executando a tarefa de sua responsabilidade no método execute(). Também possui um método undo() que reotrnar o estado antes da execução da sua tarefa.
Refatorar o script de inicialização do worker
Agora o scrip que inicializa o worker tem somente esta responsabilidade e a tarefa que o worker realiza pode ser feita alterando a classe ResizeImageJob sem a necessidade de parar e reiniciar o worker. O script refatorado application/workers/resize_image_worker.php
Convenção nos nomes de arquivo
Para facilitar a manutenção dos workers e o carregamento automático das classes de jobs do projeto foi criado um helper que carrega a classe de job de mesmo prefixo do arquivo worker inicializado. Assim um arquivo worker resize_image_worker.php inclui sua classe job resize_image_job.php. O arquivo application/workers/worker_helper.php deve ser incluido na primeira linha de cada novo worker.
Rodando a suite de specs
Rodar as specs a partir do diretório raiz do projeto
(gearman) $ phpspec spec/ --formatter documentation --color
O resultado deve ser o mesmo da próxima a imagem afirmando que todos os exemplos da specificação definida no início da refatoração estão passado (green).Referências:
http://www.phpspec.net
http://www.slideshare.net/marcello.duarte/phpspec-bdd-for-php
http://techportal.ibuildings.com/2011/07/21/outside-in-behaviour-driven-development-in-php
http://techportal.ibuildings.com/2011/08/03/outside-in-behaviour-driven-development-in-php-part-2
http://www.urubatan.com.br/comparacao-entre-tdd-e-bdd-como-aprender-um-me-ajudou-com-o-outro/