Melhorando a expressividade dos testes unitários com JUnitXtension – Parte 1

23.outubro.2009
Qual dos códigos é mais simples de ler?

Código A

assertFalse(foo.equals(bar));

assertFalse(foobar == 2);

Código B

assertNotEquals(foo, bar);

assertNotEquals(foobar, 2);

Inicialmente criado apenas como um projeto para me auxiliar no trabalho a escrever testes mais simples de ler, resolvi compartilhar no Google Code a biblioteca, atualmente na versão 0.1.1.

A principal motivação foi de criar novas asserções que melhorem a expressividade, mesmo que redundantes, para que o desenvolvedor não tenha que escrever códigos auxiliares limitados à API padrão do JUnit.

Internamente o próprio JUnit trabalha dessa maneira. Praticamente todas as demais asserções são abstrações sobre assertTrue, no máximo adicionando alguma formatação diferenciada para que o resultado e um teste falho seja legível.

Ao invés de, por exemplo, escrevermos assertFalse(0 == 1), podemos escrever assertNotFalse(0, 1). Ao invés de assertTrue(x > 0), podemos simplesmente escrever assertGreaterThanZero(x) e assim por diante.

Outra vantagem diz respeito à cobertura de testes. Em alguns casos, quando se usa assertFalse(x == 0), o algoritmo que calcula a cobertura vai informar que essa linha foi apenas parcialmente testada. Na verdade queremos apenas testar se x é igual a zero, mas se você persegue os 100% de cobertura, esse tipo de problema obriga a criar código extra apenas para manter a cobertura do código satisfatória. Utilizando assertNotEquals(0, x), ou o teste passa ou não passa, reduzindo para apenas duas as opções possíveis, limpando o código e aumentando automagicamente a cobertura.

Se interessou pela idéia? Você encontra os mesmos problemas e quer conhecer mais? A biblioteca está na versão 0.1.1 e pode ser encontrada no Google Code. Críticas construtivas são sempre bem vindas.

Keep testing 😉

P.S.: Agradecimentos públicos à minha esposa e ao Fábio Serra pelas revisões nesse post

Anúncios

RESTful Rails automático

02.julho.2009
Solução OO para fazer sua aplicação Rails trabalhar de modo RESTful:

application_controller.rb:

  def index
    begin
      if request.post?
        create
      elsif request.get?
        read
      elsif request.put?
        update
      elsif request.delete?
        delete
      end
    rescue NameError
      respond_to do |format|
        format.html {render :text => "<h1>Forbidden</h1>", :status => 403}
      end
    end
  end

E no arquivo routes.rb:

  map.connect ':controller/:id'
  # map.connect ':controller/:action/:id'

Como funciona?

Uma aplicaçao Rails RESTful funciona, basicamente, utilizando o método HTTP como verbo e a URI como substantivo.

Ao invés de algo do tipo http://application:3000/user/view/1, com REST você usa http://application:3000/user/1 para pegar os dados, atualizar ou apagar, mudando apenas o método HTTP da chamada.

Porém, por padrão, o Rails entende as requisições como sendo /controller/action/id, por isso a alteração no arquivo routes.rb, para fazer com que o segundo parâmetro seja o ID, já que quem define a action é o próprio método HTTP.

Dependendo do método utilizado, será executada uma action padronizada que será escrita no seu próprio controller, usando o conceito de sobrescrita de métodos. Caso você não escreva qualquer uma das actions, será exibida uma mensagem de erro padrão, permitindo que você foque somente no desenvolvimento do que for necessário.


Rated R

26.maio.2009

“Fazer refactoring sem testes é o mesmo que pegar puta no calçadão e depois dizer ‘eu não sabia’ quando as coisas não saem como esperado.”

Pensamento antigo, mas válido.


Testes unitários – you’re doing it wrong

14.maio.2009
Se você:
– Precisa de um método public static void Main(String[] args) para executar seus testes
– Depende de uma ordem pré-determinada para executá-los
– Caso um teste falhe, todos falham na seqüência
– Dependa de um banco de dados, de uma conexão ou de qualquer recurso externo para executar o teste
– Precise rodar os testes na mão toda vez que quiser saber se estão passando
– Escreve testes sem assert com freqüência

Sinto dizer, mas você não está usando testes unitários.

Update: Estou amadurecendo melhor a idéia, mas relendo isso aqui, e conversando com alguns desenvolvedores, fiquei pensando: “OK, você está fazendo errado. Então como é o certo? Por que está errado?”. Fiquei em dívida com vocês. Mas pretendo publicar algo mais decente sobre isso em breve.


Cuide bem do seu Ubuntu

12.maio.2009
Criei um script para atualizar automaticamente o Ubuntu do meu servidor. Se manter o Linux atualizado é uma tarefa chata e repetitiva, por que não automatizá-la?

Vamos utilizar o crontab, que é o gerenciador de tarefas agendadas do *ux (Linux, Unix e parentes).

Crie um arquivo com o conteúdo a seguir:
sudo -i
nano ~/update.sh

#! /bin/sh
apt-get update
apt-get upgrade -y

Salve e feche com F2. Para testar, digite:
chmod +x ~/update.sh
~/update.sh >> ~/update.log
tail ~/update.log

Agora, dê permissão ao seu usuário para que ele execute o crontab:
nano /etc/cron.allow

Dentro do arquivo, insira os usuários que terão acesso ao cron, um por linha, incluindo o root se precisar.

Teste com crontab -e. Possivelmente irá aparecer um arquivo com a linha abaixo:
# m h dom mon dow command

Adicione no arquivo:
0 0 * * * ~/update.sh >> ~/update.log

Novamente F2 para salvar e fechar e pronto. Você tem um agendamento para que todo dia a meia noite o Ubuntu atualize sua lista de pacotes e execute um upgrade automático. Nem o Windows Update faz melhor, hein?

Caso você queira saber se ocorreu algum problema, basta olhar o arquivo update.log. Ele contém todas as informações do que aconteceu. E caso você queira que ele mantenha somente a última execução, basta substituir o >> por > no agendamento do crontab.

That’s all, geeks.

Update as 21h00: Meu script acabou de rodar (é meia noite no servidor). Funcionou \o/.


ActiveScaffold

30.março.2009

Não use.

Simples assim.


Sobre garrafas d’água e janelas quebradas

27.março.2009
Há semanas eu queria publicar isso, mas a correria e a avalanche de viagens atrasou um pouco a coisa por aqui. A boa é que meu plano de milhagens ficou mais gordinho depois do último mês.

No escritório em que trabalho há um frigobar. No frigobar há uma garrafa d’água cuja função (duh) é fornecer água gelada aos funcionários e visitantes. Sem dúvida, nesses tempos de calor excessivo, um copo bem servido de água gelada é muito bem vindo.

O problema é que todo mundo gosta de tomar aquele copão de água refrescante, mas ninguém gosta de encher a garrafa de volta e, aquele que pega essa tarefa, gasta bons minutos enchendo uma garrafa vazia e bebendo água morna.

E o que você tem a ver com o que acontece no escritório?

Pense que a garrafa é um software. Você chegou da rua, com calor e suado e quer água gelada. Você foi jogado num projeto e quer código limpo,claro e que funcione, certo?

Só que, sinto dizer, as chances de você encontrar isso no seu novo projeto é ainda menor do que as chances de encontrar água gelada, e o motivo é bem simples: maioria das pessoas quer simplesmente se livrar do problema, pular para a próxima tarefa, correr logo para casa e/ou mostrar produtividade para a chefia. Poucos percebem que isso vai criando uma bola de neve, ou de fezes, que só cresce, e afoga o próximo que tiver que meter a mão no lodo.

“Não tenho tempo”, “o próximo que se dane” ou simplesmente “não reparei que estava fazendo isso” são as desculpas mais comuns e, infelizmente, tentar convencer essas pessoas do contrário é tão produtivo quanto lavar burro com xampu anticaspa.

Alguém um dia disse que, se quisermos um mundo melhor, temos que começar a limpar nosso próprio quintal. Se eu quero ter sempre água gelada, eu completo o que acabei de beber. Se eu quero um código limpo, eu corrijo, dentro do possível, o código em que estou trabalhando, e faço o possível para deixar código limpo para quem vier depois. E não compensa esperar que as outras pessoas mudem de comportamento, por mais que os cursos por aí preguem o contrário.

Conserte as janelas quebradas, escreva testes, não jogue papel na rua, limpe os pés antes de entrar e, pelo amor da sua divindade preferida, encha a porra da garrafa d’água depois de se servir.

E bom fim de semana.