quarta-feira, 8 de fevereiro de 2012

Mocks e Stubs - algo mais legível que a biblioteca do PHPUnit

Ainda não usei, mas só por ter uma sintaxe mais limpa, vale a pena dar uma olhada.

https://github.com/mlively/Phake/wiki

sexta-feira, 13 de janeiro de 2012

Imprimindo entidades do Doctrine 2 - debug melhor que print_r

Por conta dos porxys que ficam nas entidades relacionadas, dar um print_r em um obj do doctrine 2 não é nada agradável. Na documentação tem pouca referência de como fazer isso, mas achei o seguinte:

\Doctrine\Common\Util\Debug::dump($entidade);

É muito útil.

terça-feira, 7 de dezembro de 2010

Degub de queries que não mostram erro no Doctrine 1

Se você estiver tendo problemas com uma query especifica que morre sem deixar vestigios, sem imprimir nada na tela, pode se beneficiar de mais informações registrando um listener generico para imprimir os eventos e também melhorando o flush para ele realmente mostrar algo. antes de fazer a query, registre o listener na conexão:

$conn = Doctrine_Manager::connection();
$conn->setListener(new MyDebugger());
$result = $query->execute();

E também declare ele e o flush melhorado:

class MyDebugger implements Doctrine_Overloadable
{
public function __call($methodName, $args)
{
echo $methodName . ' called !';
flush2();
}
}

function flush2 (){
echo(str_repeat(' ',256));
// check that buffer is actually set before flushing
if (ob_get_length()){
@ob_flush();
@flush();
@ob_end_flush();
}
@ob_start();
}

quinta-feira, 11 de novembro de 2010

Refactoring - é bom mesmo quando vira costume!

Neste artigo vou falar do refactoring, explicar porque fazer e dizer algumas regras fundamentais que aprendi com a experiência.

Quase todo bom costume que queremos colocar na vida da gente, no ínicio é uma peleja para conquistar. Mas também depois que vira um costume mesmo, aí fica difícil é de deixar de fazer. Uma coisa que desejo para todo programador é que ponha no seu dia a dia o custume de fazer faxina no código, o famoso "refactoring".

Como funciona isso? É simples, você vê um código bagunçado e arruma ele. Claro que não da pra arrumar todo o código bagunçado do mundo, mas ao menos podemos ir arrumando o código no qual vamos precisar trabalhar. A idéia é: Já que vamos mexer na sujeira, que seja para limpar logo de vez.

Se vamos começar a mexer em um código, seja quem foi que programou ele, até mesmo nós em um dia que estavamos com dor de barriga, precisamos entender aquele código. Se for um código confuso, daquelas "belezuras" com variáveis misteriosas e diversas estruturas aninhadas com breaks, continues e switchs, temos geralmente duas opções:

Opção #1 -
  • perder muito tempo tentando entender o código
  • perder muito tempo para cada modificação que queremos fazer
  • deixar uma bagunça maior para o próximo que for mexer naquele código.

Assim temos a seguinte equação:

muito tempo para entender +
muito tempo para mexer * número de modificações
----------------------------------------------------
muito tempo gasto, um código ainda pior e insatisfação


Opção #2 -
  • perder muito tempo tentando entender e já fazendo um refactoring
  • gastar pouco tempo para cada modificação
  • deixar um código bom para o próximo que for mexer (que pode ser inclusive eu mesmo).

Assim temos:

muito tempo para entender e fazer o refactoring
+ tempo razoável para mexer * número de modificações
--------------------------------------------------------
muito tempo gasto, código limpo e satisfação


O fato é que sempre que pegamos um código medonho, teremos que gastar muito tempo nele. E esse tempo geralmente aumenta proporcionalmente à idade daquele código. Quanto mais antigo, mais WTF, mais tempo gasto. Assim se vamos gastar mesmo muito tempo nele, façamos logo um refactoring nele.

O progra
mador preguiçoso, ou espertalhão, muitas vezes vê um código desses e acredita que vai fazer apenas uma gambiarrazinha, vai consertar o problema, e ainda vai fazer uma média com o gerente. Conheço esse tipo. Coitado, um dia a casa cai e ele descobre que não sabe programar, pq ficou sempre dando uma de esperto e não teve tempo para aprender a programar.

Bom, voltando ao refactoring, ele vale para todos os tipos de código. Não só os muito feios. Mesmo que o código seja razoável, ou bom, podemos ir melhorando ele para que fique cada vez mais simples e rápido de dar manutenção. Claro que tem hora que temos que pesar o preço daquela manutenção, mas isso depende de cada caso. Na maioria das vezes a merda fica quando pensamos em fazer algo apenas provisório, "só um protótipozinho", e aquele código fica em produção por muitos anos.

Mas na maior parte dos casos vale muito o esforço de fazer um refactoring. E com certeza isso não só contribui para o código como também para o desenvolvimento profissional do próprio programador. Como eu falei no início, a idéia é que isso vire um costume, uma virtude. A idéia é que seus dedos fiquem coçando para fazer um refactoring quando você olhar para qualquer código. Existem vários casos onde podemos fazer refactoring e até livros inteiros a respeito do assunto, não vou tratar tudo isso aqui, porque não cabe.

Mas algumas regras importantes sempre se aplicam e vou concluir este artigo com elas:

1 - Sempre é bom fazer refactoring antes e depois de mexer no código. Nunca durante. Ou em outras palavras: ta fazendo refactoring, não muda o que o código faz. Essa regra, o espertão sempre acha que pode burlar, pegar um atalho. Muito cuidado! Há atalhos que dão um trabalho enorme para encontrar o caminho de volta.

2 - Escolha blocos pequenos para fazer refactoring. Teste para saber o que o código faz. Faça o refactoring e teste novamente. Dê passos pequenos. Cada coisa de uma vez. Por mais tentador que possa parecer alterar logo tudo que você sabe que precisa, isso geralmente da merda. Assim quando bater o impulso de alterar logo tudo, conte até dez e lembre-se: uma coisa de cada vez.

3 - Ao fazer refactoring, faça pensando na lógica do cliente, na linguagem do cliente. Vai nomear um método, pense como o cliente pensa, na linguagem dele. Vai nomear uma variável, pense na linguagem dele (na verdade o ideal é estabelecer um glossário e uma terminologia única entre cliente e equipe de desenvolvimento). Você deve estar pensando que em baixo nível, mexendo na API, isso não importa pq o cliente não conhece isso. Porém em baixo nível, o cliente não é o cliente do software, mas é o cliente da API: o desenvolvedor. Pense nele e se cabível, mantenha também a linguagem única do cliente do software.

Tem gente que me procura para saber como trabalhar com arquitetura de software, com componentes, herança, injeção de dependência e todas essas coisas. O fato é que a estrada começa sempre nestes pontos que falei neste artigo. Se um programador não desenvolve esses hábitos, dificilmente ele se tornará algo mais.

Em todas as áreas do desenvolvimento humano, é bom procurar as virtudes a serem desenvolvidas, e no desenvolvimento de software, fazer refactoring certamente é uma delas.

sexta-feira, 22 de outubro de 2010

PhpDescribe agora com mais documentação.

O PhpDescribe, ferramenta para escrever especificações ativas de software em uma filosofia semelhante ao do BDD, lançou seu novo site com informações a respeito da ferramenta de teste de software.

É uma ferramenta muito promissora para quem quer unir a escrita de especificação com a escrita dos testes de software. Além disso é um exemplo de código usando novas funcionalidades do php 5.3.

quarta-feira, 22 de setembro de 2010

Trees, forests and applications... please let´s turn tests in real specifications.

To understand the tree, you need to look at the forest. To understand a forest you need to look at the trees. Clients normaly want to see the forest, but developers like to develop trees. A big step taken by the agile process is to start moving the developers to see the forest, not only the trees that compose that forest.

When I was trying to learn how to draw, the good teachers kept telling me to do things from the outer to the inner. TDD and BDD brought a broader vision to this. But I still have a feeling that we need to start from a little bit before and we also need to have a beeter picture of the tree.

The standart bdd tools, using a strict grammar is nice. But, how do we see the results? Are they results at all?

No, they are the specifications. For tests we have results and for specification we have what? I think in examples and these can be working or not workin. So, how do I take a good look at the specifications and see what parts are working, incomplete, not working....

I have not seen yet this being addressed by any tool. Colored test results from a little piece of specification, as most tools will produce, won´t give me the forest view. Forest have leaves, flowers, stems and other important things to be noticed to understand the forest. I think we should think more in writing specs to be read and understood by humans than by continuous integration tools. They should be extremely easy to navigate, search and write. Images are essential in some place, they need to have a way to be added.

So I think there is a gap to be filled.... that´s why I´ve started PSpec.

terça-feira, 20 de julho de 2010

A simple symfony application deploy using shell script.

This is something that can be used to deploy an app to an staging environment. After that you can sync it somehow, but I prefer to export again to prod to keep the fidelity from the release launched with the repo release.

It´s nice to see how many things can be done with shell scritp without the need to configure those weird xmls (IMO, of course). It´s just more.... simple.

#!/bin/bash
die () {
echo >&2 "$@"
exit 1
}

// validate the parameters count....

[ "$#" -eq 1 ] || die "Voce precisa informar o nome da release para ser o nome do diretorio gerado dentro de prod_online"

// exports the code from a local repo. (if you need from a foreign with ssh, ask that I can publish some info also)

svn export --force file:///data/svn/reuni-on/trunk /data/web/reuni/prod_online/$1

// override the config file with one specific to prod environment.

cp /data/web/reuni/deploy_script/testesSincronia.conf.tmp /data/web/reuni/prod_online/$1/web/testesSincronia/conf.php

// create dirs that are not so good to be on the repo.

mkdir /data/web/reuni/prod_online/$1/cache
mkdir /data/web/reuni/prod_online/$1/log
mkdir /data/web/reuni/prod_online/$1/data/offlineParaDownload

//allow to write into this dirs ( here you will probably want a more restrictive permission)
chmod 777 -R /data/web/reuni/prod_online/$1/cache
chmod 777 -R /data/web/reuni/prod_online/$1/log
chmod 777 -R /data/web/reuni/prod_online/$1/data/offlineParaDownload

// clear symfony cache
php /data/web/reuni/prod_online/$1/symfony cc