quinta-feira, 17 de novembro de 2011

Codeigniter 2 + Gearman + Phpspec


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
Fixture
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.phpO 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/

Nenhum comentário:

Postar um comentário