Fork me on GitHub

Viagens, opiniões e afins

by Andre Fonseca


Jasmine BDD: Instalando e escrevendo primeiro teste

Para os que ficaram interessados devido aos posts anteriores em usar o Jasmine BDD para fazer (até começar a fazer) seus testes, esse será o primeiro de uma série de artigos que tentaram explicar o como usar, como escrever seus testes e coisas mais avançadas como assíncrono e stub.

Primeira coisa é que caso não esteja familiarizado em escrever testes ou está começando a programar, antes de mais nada aprender os conceitos básicos e procure um Dojo mais próximo de você. Independente de ser testes em javascript ou qualquer outra linguagem, escrever testes é uma forma de pensar e filosofia que deve ser aprendida. Senão, você ficará perdido, sem saber por onde começar e além disso, não conseguirá colher os benefícios que isso trará para seu produto.

Avisos paroquiais feitos vamos ao que interessa.

Antes de escrever a sua primeira linha de qualquer coisa é preciso que instale as coisas. Nesse momento, seguiremos do jeito mais simples e hard, sem uso de ferramentas, linhas de comando, etc. Vamos nos ater ao básico e mais simples.

O Jasmine BDD é uma biblioteca Javascript. (.js). Ele roda dentro de uma página com alguma markup que permite que ele coloque na tela a saída do resultado da tela. Sendo assim, acesso o site do produto (clique aqui). Na página principal escolhe a opção de standalone. (voce pode ir direto para esse link).

Ao descompactar o arquivo verá uma estrutura de arquivos e pastas, praticamente pronta para uso. Para rodar os testes basta carregar o SpecRunner.html no seu browser preferido.  Suas specs(js com testes). Devem ficar dentro da pasta spec (vejo o exemplo que vem junto). É costume chamar o nome do arquivo com o nome do que irá testar seguido de Spec.

 

Para incluir um novo teste ou um novo arquivo de dependencia (tipo jquery ou mootools) bastar colocar a chamada no SpecRunner.html

 

<html>
<head>
  <title>Jasmine Test Runner</title>
  <link rel="stylesheet" type="text/css" href="lib/jasmine-1.0.2/jasmine.css">
  <script type="text/javascript" src="lib/jasmine-1.0.2/jasmine.js"></script>
  <script type="text/javascript" src="lib/jasmine-1.0.2/jasmine-html.js"></script>

  <!-- include source files here... -->
  <script type="text/javascript" src="src/Player.js"></script>
  <script type="text/javascript" src="src/Song.js"></script>

  <!-- include spec files here... -->
  <script type="text/javascript" src="spec/SpecHelper.js"></script>
  <script type="text/javascript" src="spec/PlayerSpec.js"></script>

</head>
<body>

<script type="text/javascript">
  jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
  jasmine.getEnv().execute();
</script>

</body>
</html>

 
Só com isso, você já tem o seu framework de teste funcionando perfeitamente em sua máquina.

Seu arquivo de teste é composto por, basicamente, dois blocos – um dentro do outro. Num bloco você descreve ou define o contexto. Ele é definido pelo método describe. Assim todo teste jasmine deve começar por:

describe("contexto", function(){
//Aqui dentro as expectativas
});

&nbps;

Assim como o Rspec, no qual o Jasmine se inspirou, a idéia não é simplesmente pensar em testes unitários e sim criar expectativas, coisa que tem mais a ver com o BDD.

Assim se continuar nossos testes ficarão assim:

describe("contexto", function(){
  it("deve ser true", function(){
    expect(true).toBeTruthy();
  });
});

 

Pronto taí o seu primeiro teste com jasmine escrito. Onde, o it define o ponto de teste dentro daquele contexto. Ele contém uma frase que será exiba na execução do teste no HTMl e facilita o entendimento do objeto do teste. Os asserts são feitos usando um método expect que define oque será auditado e em seguida o que espera de resultado.

Ficamos por aqui. No próximo post, vou falar sobre os matcher e vamos avançar mais sobre jasmine.

Published by Andre, on outubro 2nd, 2011 at 8:00 pm. Filled under: atualidades,TDD Tags: , , , 1 Comment

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

Introdução de teste JavaScript com Jasmine

No dia 18 de junho vai rolar a primeira edição do evento FrontinRio. Ele foi primeiramente idealizado pelo Leonardo Balter(@leobalter), e foi organizado por diversas pessoas como Ramon Page, Rafael Tauí, Bernard de Luna, eu, etc. Esse evento é totalmente focado em desenvolvimento da parte cliente de aplicações web – conhecido pela galera como desenvolvimento Front ou Client.
Recomendo muito a galera ir. Vai ser um dia muito legal com gente altamente compartilhando suas experiências, trazendo novidades e como são seus dias a dias de projetos e empresa.
Eu serei um dos que irá apresentar nesse evento. O assunto será Jasmine. Jasmine é uma biblioteca de teste para JavaScript. Ele é mais focado no princípio de BDD (Behavior Driven Dev.) do que em TDD. Sendo assim apresenta uma sintaxe, que eu pessoalmente gosto muito, para escrever teste que fica bastante elegante poderoso. Além disso oferece suporte a testes assíncronos e spies (bibliotecas para “espionar” chamadas de métodos e fazer mock) de forma muito simples.
Para quem desenvolve com Ruby, verá a forma de escrever suas especificação é muito semelhante ao RSpec. Veja o exemplo abaixo:

describe("Aqui vai uma descricao", function(){
  it ("linha de teste", function(){
    expect(true).toBeTrue();
  }
}

Outra coisa legal dessa biblioteca é que ela não precisa de um DOM (simplificando seria que ela não precisa de uma página) para executar. E é totalmente auto-contida: só precisa dela mesma para funcionar e nenhuma outra biblioteca.
Se você quiser usar ainda dentro de um projeto Ruby(com rake), o próprio projeto possui uma gem para instalar que torna o processo ainda mais suave e fácil de ser feito.
Jaba feito fica agora o convite para ver minha palestra no dia 18 de junho para conhecerem o restante do Jasmine.

Published by Andre, on junho 2nd, 2011 at 2:54 pm. Filled under: ruby,TDD Tags: , , , , , No Comments

Você realmente está testando?

Na maioria dos livros que li nos últimos tempos do mais diversos assuntos ligados a engenharia de software, testes automatizados, e mais especificamente, TDD (test driven development) e BDD (behavior driven development) são dominantes. É certo que, atualmente, se desejamos ter qualidade e velocidade de entrega nos nosso produtos precisamos de testes automatizados. E vou além: digo que abordagens como TDD e BDD auxiliam o desenvolvedor a escrever código melhor e mais focado no valor para o cliente.

A questão é que se estabeleceu axiomas – verdades absolutas – onde para ser bom o projeto precisa ter 100% de cobertura de código e  ter testes unitários e testes de integração e testes de aceitação (tela e feature), etc. Isso nem sempre é verdade e pode ser um verdadeiro “tiro no pé”. Antes de mais nada é preciso entender a real função do teste. E qual será a melhor forma de utilizá-lo. Não estou discutindo aqui abordagens e sim se estamos usando de forma inteligente e consciente os testes.

Em uma conversa recente com Bernardo Heynemann, vimos, que, por exemplo, em alguns casos testes de aceitação que usavam Cucumber ou Pyccuracy, estavamos testando mais o navegador que a funcionalidade em si. Quando falamos de cobertura temos outro ponto interessante: 100% não é garantia de nada. Já ouvi falar  de sistemas com 100% de cobertura que quando foram fazer refactoring – confiando na cobertura de testes,  ”quebrou” tudo ao colocar em produção pois vários detalhes escaparam.  Isso porque, provavelmente existiam diversos testes que faziam “nada” e que ali estavam apenas para garantir a cobertura mínima.

Novamente citando Bernardo Heynemann, ele me disse que para os que estão começando, é importante seguir uma fórmula:  testes unitários, testes de integração, testes de aceitação, etc. Isso porque ainda estão formando sua base de experiência e tem pouco discernimento para saber quais seriam os pontos críticos a serem testados para termos a garantia de qualidade.  Mas a medida que for ganhando bagagem e aguçando seu senso crítico, é importante se questionar o que testar, como testar, etc.

Uma coisa que sempre falo é que testar da trabalho. Por mais que possa trazer benefícios, ainda é mais trabalho. Se falamos de testes automatizados – programáticos – é mais linha de código. Por exemplo, tiveram coisas que levei mais tempo escrevendo os testes do que implementando.  Teste onera sim.

Antes de mais nada quero esclarecer que não sou contra testes. Muito pelo contrário, acredito que não existe a possibilidade de fazer algo bem sem usar TDD ou BDD. A questão que levanto é o quanto estamos realmente testando nossos sistemas e o quanto estamos apenas “inventando” para cumprir com regras pré-definidas que ninguém de fato entendeu para que servem.

Um exemplo disso que estou falando é quando temos diversos níveis de teste em nossa aplicação … E testamos a mesma coisa em todos eles. Sabe aquele teste que você fica criando o Model, colocando os dados  no banco, acessando o banco, etc? Isso mesmo. É um bom smell disso que estou falando.

Uma coisa que faço é primeiro me concentrar no objetivo que quero atingir com aquele teste. Tudo mais é superfluo e logo pode ser ignorado(entenda mock e outras tecnicas).  Logo, se quero testar as chamadas do controller de minha aplicação, eu não preciso, nem quero me preocupar com que está acontecendo dentro do Model associado.   Outro ponto é se já testei algo em algum ponto, evito ficar testando novamente… Se por acaso isso for necessário é sinal que preciso fazer um refactoring no meu código.

Em futuro artigos pretendo trazer o assunto e ir mais fundo inclusive trazendo exemplos, trechos de código, etc.  Até a próxima.

 

 

 

Published by Andre, on abril 20th, 2011 at 7:21 pm. Filled under: codigo,TDD Tags: , , , 5 Comments