ago 7 2008

Instalando PHPUnit e PHPSpec no Ubuntu Linux

Pear-ish Fall-ish Composition
UPDATE: Se está com problemas na instalação, fiz aqui um breve tutorial de como instalar o PHP-PEAR.

Olá, essa dica vai para quem tem Ubuntu ou que usa algum GNU/Linux Debian-like.

Vamos fazer os passos mais simples para instalar esses frameworks e para isso você deve ter o PHP-PEAR instalado, se não tiver, apenas abra o seu terminal linux favorito e digite:

sudo apt-get install php-pear

Difícil em? :D

Agora vamos instalar o PHPUnit, o primeiro passo é adicionar o canal do PHPUnit ao PEAR, e para isso, mais uma vez no terminal digite:

sudo pear channel-discover pear.phpunit.de

Esse comando serve para o PEAR reconhecer o host pear.phpunit.de como uma de suas fontes, agora vem a segunda parte:

sudo pear install phpunit/PHPUnit

Pronto, está instalado o PHPUnit, nesse mesmo terminal você pode rodar o comando:

cairo@angus:~$ phpunit -v
PHPUnit 3.2.21 by Sebastian Bergmann.

A versão pode mudar :P Ainda não uso a versão beta 1 do PHPUnit.

Para instalar o PHPSpec é a mesma coisa, você deve adicionar o canal e depois instalar:

sudo pear channel-discover pear.phpspec.org

sudo pear install phpspec/PHPSpec

Pronto, feito isso estará instalado PHPUnit e PHPSpec.

Até a próxima!


jul 19 2008

Futuro do PHPSpec

Olá, para quem não conhece, PHPSpec é um framework BDD para PHP.

Hoje o desenvolvedor do framework, Pádraic Brady, postou um email na lista phpspec-dev (phpspec-dev@googlegroups.com) e um artigo em seu blog sobre o futuro do PHPSpec.

A primeira e mais importante notícia, é que ele quer criar uma DSL decente (Sim, decente). Como ele citou no seu artigo, no Ruby, o BDD é sexy, mas em PHP é feito e chato. Por conta da sintaxe do PHP, a DSL acaba sendo uma coisa totalmente feia. Enquanto que no Ruby temos algo como “should score 0 for gutter game”, em PHP isso acaba virando um método:

    public function itShouldScore0ForGutterGame() {
        for ($i=1; $i<=20; $i++) {
            $this->_bowling->hit(0);
        }
        $this->spec($this->_bowling->score)->should->equal(0);
    }

Para desenvolvedores PHP isso é de fácil leitura, mas infelizmente, isso gera uma barreira enorme para pessoas que não sabem nada de PHP ou de programação, isso acaba fazendo ter um nível de explicação para o cliente ou para o interessado nesse comportamento, e isso vai diretamente contra o principio do BDD, onde todos os envolvidos tem que enteder realmente o que se está fazendo.

A outra notícia, é que ele está retomando a dianteira no desenvolvimento do Framework, desde fevereiro ele não vem dando dedicação necessária ao framework.

A primeira coisa é que ele está fazendo uma varredura nos bugs e liberar mais uma nova versão 0.2.x. Além disso ele fez uma chamada para quem quiser contribuir com alguma coisa para a versão 0.3 :).

Outra coisa importante é que anunciou que possivelmente em setembro ou outubro sairá a versão 5.3 do PHP, e pelo roadmap dele, a versão 0.5 já estará sobre o PHP 5.3 e afirmando que não fará esforços para que o framework funcione nas versões anteriores passando essa responsabilidade para a comunidade.

Agora é esperar até a DSL for sexy o suficiente para todos entender ;).

Até a próxima!


jul 11 2008

Integrando o PHPUnit e o PHPSpec ao CodeIgniter e ao Lumine Framework

Meu grande amigo português Ricardo Mestre me fez a seguinte pergunta esses dias:

Como faço para usar o PHPUnit no CodeIgniter?

O que vou mostrar aqui serve para esses dois frameworks (PHPUnit e PHPSpec) ou para qualquer um outro framework que necessite.

Seguinte, o CodeIgniter possui sua configuração de acesso no index.php, só que na penúltima linha, ele faz chamada ao arquivo BASEPATH.’codeigniter/CodeIgniter.php’;. Quando é requisitado, ele faz a requisição aos arquivos de inicialização e executa o método index da classe default dentro do arquivo system/application/config/routes.php. (UPDATE: o arquivo que define do controlador default a ser chamado assim que a aplicação funcina é em routes.php)

Aí, para usarmos os controladores do CI é necessário utilizar esse arquivo de configuração por conta das contantes que o CI utiliza. Para evitar de quando executarmos nossas classes de testes, elas não venham a executar por conta da saída do CI.

Então, é necessário fazer um arquivo com o mesmo contéudo do index.php, exceto da linha BASEPATH.’codeigniter/CodeIgniter.php’;. Ao fazermos isso é necessário chamar as bibliotecas básicas do CodeIgniter manualmente que estão dentro da pasta /system/codeigniter/. As bibliotecas são BaseN.php (4 para o PHP 4 e 5 para o PHP 5). Common.php e como vamos fazer teste dos controladores, é necessário importar a classe Controlller.php que está dentro da pasta /system/libraries/.

Após isso é só incluir esse arquivo criado dentro das classes de testes.

Resumindo:

  1. Criar arquivo com contéudo do index.php excluindo a penúltima linha que faz chamada ao BASEPATH.’codeigniter/CodeIgniter.php’;
  2. Incluir dentro desse arquivo chamada para /system/codeigniter/BaseN.php (N = 4 ou N = 5);
  3. Incluir dentro desse arquivo chamada para /system/codeigniter/Common.php;
  4. Incluir dentro desse arquivo chamada para /system/libraries/Controller.php;

Bom, agora para utilizar os Models do Lumine, é apenas necessário fazer chamada ao arquivo com as configurações de acesso do Lumine. A critério de convenção, podemos criar um novo arquivo de configuração apenas alterando o nome do banco de dados, assim não prejudicando seu banco de dados.

Depois disso tudo podemos testar nossos controladores e os modelos do Lumine com o PHPUnit, PHPSpec ou qualquer outro framework de testes.

Até a próxima!


jun 18 2008

Behavior Driven Development em PHP com PHPSpec

Comecei a ler muito sobre TDD, depois na comunidade rails-br descobri o BDD li e me pareceu mais simples do que TDD.

Para fazer TDD no rails é bem mais simples do que parece, é só executar os scripts de criação de models, controllers e views que o framework já cria os arquivos básicos para fazer TDD, bastando apenas escrever os casos de testes e executar o comando rake para tudo funcionar.

Para fazer BDD em rails é necessário a instalação de um plugin chamado RSPec, esse plugin é responsável pela criação das especificações em BDD.

Em rails é muito simples fazer TDD e BDD, já que o próprio ambiente te prepara para desenvolver se utilizando dessas técnicas, diferente dos frameworks PHP que poucos deles possuem facilidades como rails (Na sua última versão, o CodeIgniter introduziu TDD em seu core, ainda não tive tempo para dar uma olhada de como funciona. No cakePHP, pelo que eu vi na comunidade, é capaz de se fazer TDD).

Para se fazer TDD e BDD no PHP é necessário a instalação de frameworks para o mesmo, no meu caso eu escolhi o PHPUnit para testes unitários e para BDD eu escolhi o PHPSpec. Só que essa escolha foi por livre e espontânea pressão, é que somente existe esse framework para se trabalhar com BDD em PHP.

Ele foi escrito após o desenvolvedor (Pádraic Brady) ter se aventurado por Ruby e Rails e conhecido RSpec, ele resolveu desenvolver o “RSpec” para PHP e o batizou de PHPSpec.

A documentação é bastante simples e fácil de ler, usei algumas horas e li toda a documentação, e agora estou planejando para utiliza-los nos projetos que faço parte.

Agora vou explicar um pouco de como funciona com um exemplo.

Primeiro, antes da gente começar, devemos especificar o problema, no caso, como um usuário irá fazer um comentário.

Usuário deverá colocar seu nome, depois ele deverá colocar seu email.

Se o usuário tiver um site, poderá coloca-lo.

Então depois o usuário coloca o conteúdo do comentário e clica em enviar.

Agora que temos a especificação, vamos criar nosso primeiro exemplo:

require_once "Post.php";

class DescribeNewPostInBlog extends PHPSpec_Context {

	private $post = null;

	public function before() {
		$this->post = new Post;
	}

	public function itShouldSetName() {
		$this->post->setName("Cairo Noleto");
		$this->spec($this->post->getName())->should->beEqualTo("Cairo Noleto");
	}

	public function itShouldSetEmail() {
		$this->post->setEmail("caironoleto@gmail.com");
		$this->spec($this->post->getEmail())->should->beEqualTo("caironoleto@gmail.com");
	}

	public function itShouldSetWebSite() {
		if ("user set as website") {
			$this->post->setWebSite("http://www.caironoleto.com/");
		}

		$this->spec($this->post->getWebSite())->should->beEmpty();
	}

	public function itShouldSetContent() {
		$this->post->setContent("Aqui vai o comentário do post :P");
		$this->spec($this->post->getContent())->should->be("Aqui vai o comentário do post :P");
	}
}

Se rodarmos no terminal, teremos o resultado:
cairo@angus:~/BDDonPHP$ phpspec DescribeNewPostInBlog
E
Fatal error: Call to undefined method Post::setName() in /home/cairo/BDDonPHP/DescribeNewPostInBlog.php on line 15

Da erro por que nossa classe Post não contém o método setName, e vai da erro a cada um dos métodos que não funciona, então irei cria-los:

class Post {

	private $name;
	private $email;
	private $website;
	private $content;

	public function setName($name) {
		$this->name = $name;
	}

	public function setEmail ($email) {
		$this->email = $email;
	}

	public function setWebSite($website) {
		$this->website = $website;
	}

	public function setContent($content) {
		$this->content = $content;
	}

	public function getName() {
		return $this->name;
	}

	public function getEmail() {
		return $this->email;
	}

	public function getWebSite() {
		return $this->website;
	}

	public function getContent() {
		return $this->content;
	}
}

Agora rode mais uma o código e veja tudo rodando perfeitinho :D

Algumas considerações:

A primeira e mais importante é que o framework está na versão 0.2.3 e ainda não saiu nenhuma versão release, todas as versões são betas.

Por ser beta, falta alguns métodos (Como os “Matchers” beAnInstaceOf, beString, beOfType). Por assinar a lista, foi resolvido hoje e inserido o método beString, ainda não sei como faço pra pegar a versão do SVN que seria bem mais interessante, vou colocar um email na lista perguntando como faço e blogo aqui.

O Framework como está funcionando já da pra escrever muita especificação, então é bola pra frente.

Até a próxima!


jun 11 2008

Diferença entre TDD e BDD

TDD é um acronimo para Test-Driven Development, que significa desenvolvimento orientado a testes, e BDD é um acronimo para Behavior Driven Development, que significa desenvolvimento orientando a comportamentos.

TDD e BDD são técnicas de desenvolvimento que priorizam os testes de código, integração continua e desenvolvimento ágil.

Essas técnicas são para desenvolvimento a testes. Mas tem uma pequena diferença, em TDD você escreve os testes e os valida de forma que eles funcionem. Já em BDD, você escreve como deve se comportar seu problema.

Além disso, em BDD é mais humano os testes. Existe um framework em ruby chamado RSpec que você deve ser bom em inglês, já que você praticamente “fala” com o framework e diz como vai se comportar as coisas. Em php, foi criado um framework chamado PHPSpec, que é uma “versão” do RSpec para PHP.

BDD foi originalmente criado para suprir a necessidade que começou a ser criada em TDD. E também, por que escrever orientado a testes é mais chato, principalmente para quem não tem experiência com testes, ou tem muita experiência.

Quando se programa em TDD, com o passar do tempo, o seus testes se tornam o comportamento que você quer na sua aplicação, algumas pessoas consideram o BDD uma evolução natural do TDD.

Independente de usar técnicas ou não, é necessário que a aplicação seja testada. E testes devem ser automáticos, manuais, documentados e validados.

Até a próxima!