Fork me on GitHub

Viagens, opiniões e afins

by Andre Fonseca


Jasmine testes: Usando o before e o after e testes assincronos.

Um dos pontos fortes que considero no Jasmine é seu “suporte” a execuções assíncronas para teste. Isso significa, que dado aquele seu código, que tem um chamada que tem duração de tempo, ocorre com callback, etc, você será capaz de testar isso com relativa facilidade com Jasmine.

 
Somente para lembrar, todo arquivo de teste do Jasmine é composto de um contexto onde temos diversas asserts que irão validar o funcionamento do nosso código:

describe("teste de algo", function(){
    it("deve acontecer algo e o valor ser outro", function(){
        expect(true).toBeTruthy();
    });
});

 

No código acima criamos o contexto com a função describe, que recebe um texto com a descrição e uma função a ser executada. Dentro do corpo da função a gente tem a chamada do it que também recebe um texto com descrição e um função.

Uma coisa legal é que como qualquer framework de teste, ele tem métodos para executar código antes e depois de cada teste (acertiva). Esse métodos são o beforeEach (para executar algo antes) e o afterEach(para executar o depois).
Essas funções recebem como argumento uma função cujo o corpo será executado. Veja o exemplo abaixo:

describe("teste algo com before e after", function(){
    var variavel;

    beforeEach(function(){
        variavel = true;
    });

    afterEach(function(){
        variavel = false;
    });

    it("teste", function(){
        expect(variavel).toBeTruthy();
    });
});

 
Mais isso não é o objetivo do artigo. O nosso objetivo é mostrar o quão é fácil colocar a rotina de espera para dentro do seu teste:

describe("teste algo com before e after", function(){
    var variavel;

    beforeEach(function(){
        variavel = true;
        setTimeout(function(){
            variavel = false;
        }, 100);

    });

    it("teste", function(){
        expect(variavel).toBeTruthy();
        waits(200);
        runs(function(){
            expect(variavel).toBeFalsy();
        });
    });
});

 
O método de waits que usamos acima, gerar uma espera para a execução de 200 milisegundos. Depois ele irá executar na ordem, o contéudo das funções runs que vierem em seguida. Com isso podemos ter testes para nossas animações ou até chamadas com callback. Para callback, ao invés de usarmos a função waits, devemos usar a a função waitFor que recebe uma função que retornará true ou false.

Bem ficamos por aqui. Leia a documentação do projeto e aguarde nosso próximo posts. Aguardo os comentários.

Published by Andre, on outubro 6th, 2011 at 7:30 pm. Filled under: agil,TDD Tags: , , , , , No Comments

Escolhendo minha ferramenta de TDD para Javascript

Seguindo dentro da temática de testes e javascript. Quero falar de frameworks de testes.  Como já disse em artigos anteriores me rendi a pouco tempo a usar TDD para escrever meus javascript  (mais precisamente meus códigos de front end).  No momento que resolvi, influenciado por alguns, amigos parti em busca de ferramentas e frameworks que tornassem essa tarefa mais simples e produtiva.

Nesse mesmo momento estava trabalhando com um projeto em Rails e usava o Rspec para fazer os testes de todo meu código server.  O Rspec possui uma forma, sintaxe, para escrita de código que considero elegante e funcional: facilita a leitura, a compreensão e a escrita pois tem um jeitão que meio que te leva a escrever seus teste de forma bem estruturada.

Essa estrutura é basicamente formado por um contexto, que pode ou não conter outros contextos, e dentro dele as suas especificações. Assim se temos um Model a ser testado posso quebrar meus testes em vários contextos, por exemplo:

describe "Model Aluno" do
  before :each do
    @aluno = Aluno.new
  end

  subject { @aluno.nome }

  it "Deve ser um model válido" do
    @aluno.should be_valid
  end
end

 
Note como fica claro o alvo e o objetivo do teste. Para quem precisar entender o sistema basta ler as especificações do sistema que conseguirá pegar bem o funcionamento das coisas.

Bem, após ter provado isso, queria algo igual para testar meu javascript. A princípio pensei em usar o QUnit, pois ele é o framework oficial do pessoal que dsenvolve o Jquery. Como sempre achei o Jquery legal, pensei que algo que eles usem deve ser bom. Meu primeiro contato não foi bom e achei que meus testes ficaram feios, ruim de entender e ainda tinha vários problemas de mock, stub e testes assíncronos.

Descobri então o Jasmine BDD. Ele é exatamente tudo que queria pois seus desenvolvedores se inspiraram no RSpec para fazê-lo. Logo os primeiros pré-requisitos foram atendidos. Outra parada killer – lembrando que estava trabalhando num projeto rails – é sua integração com a app. Basta uma gem e alguns yamls e tudo funciona perfeitamente. Basta um rake jasmine e seus teste rodam.

Outro ponto sensacional é o fato dele já trazer uma api maravilhosa que muito lembra o Mock do Rails, incluso. Para ver se alguma coisa foi chamada fica mais ou menos assim:

spyOn(minhaClasse, "meuMetodo")
...
it("ve se foi chamado", function(){
  minhaClasse.meuMetodo("qualquer string");
  expect(minhaClasse.meuMetodo).toHaveBeenCalledWith(jasmine.any(String));
});

 

Por fim a decisão final veio pelo suporte que a api tem para teste assíncronos. Ou seja, sabe toda aquelas coisas de callback que você tem ou testes de animação.. Fica muito simples de escrever:

//codigo de animaçao com tempo aqui
..
wait(500);
run(function(){
expect(elemento.style('display')).toEquals('none')
});

 

Agora tudo isso parece que só é para código javascript que você escreve para o seu client side. Mas se você gosto do javascript no server side saiba que a biblioteca também pode e deve ser usado. Existem excelente pacotes para Node e outras plataformas (V8, Java – Rhino, etc).

Fiquem ligado no blog que em breve vou colocar uns tutoriais de coisas do Jasmine para você que ficou interessado mergulhar de cabeça nessa também.

Published by Andre, on setembro 30th, 2011 at 4:36 pm. Filled under: agil,codigo,TDD Tags: , , , , 2 Comments

Respondendo uma pergunta sobre TDD

No post que anterior, no qual falei sobre TDD, recebi um comentário perguntando dentro de algumas situações se O TDD se encaixava ou não.  Como a dúvida é recorrente e o tema é bastante controverso, resolvi, ao invés de responder o comentário dele, escrever um post.

A primeira coisa, em minha opinião, que tem que ficar clara, que TDD é um metodologia de desenvolvimento e não de projeto. Usamos TDD para gerar código melhor e com isso aumentar a qualidade do que estamos fazendo.  Testar antes não é garantia de zero bugs, mas ajuda a construir uma solução melhor pensada, simples, concisa,  e, sim, com testes automatizados que irão evitar muitos bugs.

TDD é uma forma de trabalho que se encaixa em qualquer modelo de equipe/projeto.  Se o seu time está em algo mais ágil ou waterfall, não faz a mínima diferença. Sem o seu time, irá entregar complexidade, pontos por caso de uso ou pontos de função isso também não faz diferença.  Pois, como já disse, TDD é um filosofia de desenvolvimento e não de gestão.

Ela trabalha em cima de ciclos pequenos onde a gente escreve o teste com a necessidade; após escrevemos o código para atender a necessidade e fazer o teste passar e por fim revistamos a solução para melhorá-la buscando princípios de Clean Code ( SOLID).  Se no final desse ciclo temos uma história entrega (por exemplo uso de quadros – Kanban, etc) ou se temos um ponto de função, observe que não faz diferença.  O que pode acontecer, no caso de pf é que deverá prever isso ( eu acho – nunca trabalhei com pontos de função).

Uma boa dica é que procure um DOJO (acesse o site do DojoRio) e veja na prática isso acontecer e como ela não tem relação com a gestão.

Se quer entender mais sobre TDD leia o livro do Kent Beck. Existe uma infinidade de outros livros sobre tão bons, mas acredito que seja legal começar pelo início. Depois a medida que for se sentindo mais confortável …

Assim, sem mais rodeios vamos a resposta a pergunta que me fizeram:

1. Posso usar TDD com um projeto que me exija entregar 4 a 40Pf ou qualquer outra coisas?

SIM ! Se acha que estou exagerando, procure o Alex Gomes da SEA Tecnologias. Seu maior cliente é o governo federal.  Existem outros exemplos como por exemplo

2. Código legado ?

Sim dá para usar TDD. Para te ajudar recomendo a leitura do livro Working Effectively with Legacy Code do Michael Feathers. Ele é uma excelente forma de ver como você pode testar o seu código legado.

Por fim espero ter te ajudado. E caso tenham dúvidas podem comentar que irei responder.

 

Published by Andre, on setembro 28th, 2011 at 9:40 am. Filled under: atualidades,codigo,TDD Tags: , , , No Comments

TDD no FrontEnd

Sou um adepto de TDD e por isso sempre procurei uma forma de aplicar tudo que aplicava no meu código “server side, no meu código “client side”. Muitas vezes, essa solução era usar alguma ferramenta (ou biblioteca) que simulava a navegação do cliente pela página. Embora isso seja excelente, não era exatamente o que queria. Queria algo que me permitisse construir todo o javascript usando a filosofia de TDD ( e com isso conseguir um código limpo).

Os ditos desenvolvedores FrontEnd hão de concordar comigo que muitas vezes o código Javascript fica uma verdadeira bagunça. São poucos que procuram organizar as coisas, criar componentes e funções para os comportamentos repetidos e etc. Fica a dica de ver a palestra do LeoBalter – WTF Javascript.

Na grande maioria dos projetos que acompanhei (trabalhei ou vi) as coisa cresciam de maneira muito orgânica e com isso, nunca via uma preocupação com nomes de métodos, separação, DRY e outros princípios de “Clean Code”.

TDD, na minha visão, é muito mais para ajudar nesse sentido do que simplesmente criar teste automatizados. Quando escrevemos os teste antes, estamos ali “verbalizando” a forma que gostaria que nossas apis seja consumidas … estamos na posição de quem irá usar um dia aquilo. Só nisso a diferença é mostruosa: já começamos a ver coisas repetidas; nomes de métodos; coisas que deveriam estar em classes e etc.

Um exemplo seria quantas vezes não buscamos um mesmo elemento no mesmo script? Sabia que isso é perda de processamento? Muitas vezes bastava que fizesse isso e guardasse a referência numa variável. Isso, ao escrever os testes antes, fica bem evidente. Tente você mesmo e me diga.

$("algo").hide();
...
$("algo).click(function(){ ...
//Poderiamos ter algo mais assim e os testes irão mostrar isso - famosos smells
var algo = $("
algo")
algo.hide()
algo.click(...

Outra coisa que vem com o uso de TDD na escrita de javascript é que você começa a ter uma rede de proteção que quando for necessário alterar algo fará com fique mais tranquilo quanto a introduzir um bug ou quebrar um comportamento já existente.
Num próximo artigo irei falar de bibliotecas de teste de Javascript e qual estou usando.

Published by Andre, on setembro 27th, 2011 at 6:07 pm. Filled under: agil,TDD Tags: , , , , 1 Comment