testes automatizados de javascript com jasmine
DESCRIPTION
Palestra sobre Testes automatizados de Javascript com Jasmine realizada no primeiro ciclo do Plano de Geração de Conhecimento realizado em outubro de 2013, no LEMAF - Universidade Federal de Lavras.TRANSCRIPT
Testes automatizados de Javascript com Jasmine
Maykel Melo da Silva Aline Couto Oliveira
Citações “Teste de programa pode ser usado para mostrar a presença de erros, mas nunca para mostrar a sua ausência.”
Edsger W. Dijkstra
“Sempre que você se sentir tentado a escrever algo em uma declaração impressa ou uma expressão depurador, escrevê-lo como um teste de vez.” Martin Fowler
"Qualquer recurso do programa sem um teste automatizado simplesmente não existe.“
Kent Beck
Jasmine
• Jasmine é um framework de desenvolvimento orientado por comportamento (BDD) para testes de Javascript. Ele não depende de nenhum outro framework de Javascript, nem mesmo requer um DOM (Document Object Model). E possui uma sintaxe óbvia e limpa para escrever testes facilmente.
“http://pivotal.github.io/jasmine/”
Arquivos do framework
• jasmine_favicon.png
• jasmine.css
• jasmine.js
• jasmine-html.js
• SpecRunner.html
• Download: http://pivotal.github.io/jasmine/
SpecRunner.html <!DOCTYPE ...>
<html>
<head>
<title>Jasmine Spec Runner</title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine-1.3.1/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="lib/jasmine-1.3.1/jasmine.css">
<script type="text/javascript" src="lib/jasmine-1.3.1/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-1.3.1/jasmine-html.js"></script>
<!-- include source files here... -->
Arquivos fonte incluídos aqui
<!-- include spec files here... -->
Arquivos de teste incluídos aqui
<Código do Jasmine para execução e criação do relatório de testes>
Estrutura dos testes
Os testes são estruturados da seguinte maneira:
• Suite: Agrupa um conjunto de testes
• Spec: Descreve um caso de teste
• Expectation: Descreve um retorno esperado dentro de um teste
Exemplo no Jasmine
describe("Primeiro agrupamento de testes", function () {
it("Descricao do primeiro teste.", function () {
expect(true).toBeTruthy();
});
it("Descricao do segundo teste.", function () {
expect(false).not.toBeTruthy();
expect(1+1).toEqual(2);
});
});
Suite
Spec
Spec
Expectation
Expectation
Expectation
Resultado da execução
Especificações são funções describe(“Um agrupamento é uma função", function() { var a,
b;
it(“assim como uma especificação", function() {
a = true;
b = 1 + 2 + 3;
expect(a).toBe(true);
expect(b).toBeGreaterThan(5);
});
});
Matchers
• toBe(x)
• toEqual(x)
• toMatch(x)
• toBeDefined()
• toBeUndefined()
• toBeNull()
• toBeTruthy()
• toBeFalsy()
• toContain(x)
• toBeLessThan(x)
• toBeGreaterThan(x)
• toBeCloseTo(x, y)
Setup e Teardown describe("A spec (with setup and tear-down)", function() { var foo; beforeEach(function() { foo = 0; foo += 1; }); afterEach(function() { foo = 0; }); it("is just a function, so it can contain any code", function() { expect(foo).toEqual(1); foo = foo + 5; }); it("can have more than one expectation", function() { expect(foo).toEqual(1); expect(true).toEqual(true); }); });
Spies describe("A spy", function() {
var foo,
bar = null;
beforeEach(function() {
foo = {
setBar: function(value) { bar = value; } };
spyOn(foo, 'setBar');
foo.setBar(123);
foo.setBar(456, 'another param');
});
it("tracks that the spy was called", function() { expect(foo.setBar).toHaveBeenCalled();
});
it("tracks its number of calls", function() { expect(foo.setBar.calls.length).toEqual(2);
});
});
Proposta de trabalho
• Implementar um hipotético cadastro de currículos que fará validações de preenchimento de campos obrigatórios.
• Implementar testes automatizados para as classes envolvidas.
Interface do cadastro
Classes envolvidas
CadastroCurriculo
Curriculo
Pessoa Endereco Habilidade
Utils
Estrutura do projeto Cadastro de
curriculo/
images/
lib/
jasmine-query/
jasmine-standalone-1.3.1/
Jquery-1.10.0
style/
test/
PessoaSpec.js
Endereco.js
HabilidadeSpec.js
UtilsSpec.js
CurriculoSpec.js
CadastroCurriculoSpec.js
src/
Pessoa.js
Endereco.js
Habilidade.js
Utils.js
testesCadastroCurriculo.html (SpecRunner.html) <tags de definição do html>
<link rel="shortcut icon" type="image/png" href="lib/jasmine-1.3.1/jasmine_favicon.png"> <link rel="stylesheet" type="text/css" href="lib/jasmine-standalone-1.3.1/jasmine.css"> <script type="text/javascript" src="lib/jasmine-standalone-1.3.1/jasmine.js"></script> <script type="text/javascript" src="lib/jasmine-standalone-1.3.1/jasmine-html.js"></script> <script type="text/javascript" src="lib/jquery-1.10.0/jquery-1.10.0.js"></script> <script type="text/javascript" src="lib/jasmine-jquery/jasmine-jquery.js"></script> <!-- include source files here... --> <script type="text/javascript" src="src/Utils.js"></script> <script type="text/javascript" src="src/Pessoa.js"></script> <script type="text/javascript" src="src/Endereco.js"></script> <script type="text/javascript" src="src/Habilidade.js"></script> <script type="text/javascript" src="src/Curriculo.js"></script> <!-- include spec files here... --> <script type="text/javascript" src="test/UtilsSpec.js"></script> <script type="text/javascript" src="test/PessoaSpec.js"></script> <script type="text/javascript" src="test/EnderecoSpec.js"></script> <script type="text/javascript" src="test/HabilidadeSpec.js"></script> <script type="text/javascript" src="test/CurriculoSpec.js"></script> <script type="text/javascript" src="test/CadastroCurriculoSpec.js"></script>
Especificações de testes
• CurriculoSpec – Para testes da classe Curriculo
• EnderecoSpec – Para testes da classe Endereco
• HabilidadeSpec – Para testes da classe Habilidade
• PessoaSpec – Para testes da classe Pessoa
• UtilsSpec – Para testes da classe Utils
Exemplo de especificação describe("Utils ", function(){
it("deve validar corretamente um cpf correto", function(){
expect(Utils.validarCPF("05969548677")).toBeTruthy();
});
it("deve validar corretamente um cpf incorreto", function(){
expect(Utils.validarCPF("05969548678")).toBeFalsy();
});
it("deve validar corretamente um inteiro (1) valido", function(){
expect(Utils.validarInt(1)).toBeTruthy();
});
it("deve validar corretamente um caracter inteiro ('1') valido", function(){
expect(Utils.validarInt('1')).toBeTruthy();
});
it("deve validar corretamente um caracter nao inteiro ('m')", function(){
expect(Utils.validarInt('m')).toBeFalsy();
});
it("deve validar corretamente um cep correto", function(){
expect(Utils.validarCep("37.200-000")).toBeTruthy();
});
it("deve validar corretamente um cep incorreto", function(){
expect(Utils.validarCep("37200-000")).toBeFalsy();
});
});
Resultado dos testes
Jasmine-jQuery Jasmine-jQuery oferece duas extensões para o framework de teste para JavaSript, o Jasmine:
• um conjunto de matchers personalizados para framework jQuery
• uma API para lidar com HTML, CSS, JSON e fixtures em suas especificações.
“https://github.com/velesin/jasmine-jquery”
Arquivo do framework
• jasmim-jquery.js
• Download: https://raw.github.com/velesin/jasmine-jquery/master/lib/jasmine-jquery.js
Matchers jQuery • toBe(x)
• toBeChecked()
• toBeEmpty()
• toBeHidden()
• toHaveCss(x)
• toBeSelected()
• toBeVisible()
• toContain(x)
• toBeMatchedBy(x)
• toExist()
• toHaveAttr(x, y)
• toHaveProp(x, y)
• toHaveBeenTriggeredOn(x)
• toHaveBeenTriggered()
• toHaveBeenTriggeredOnAndWith(x, y)
• toHaveBeenPreventedOn(x)
• toHaveBeenPrevented()
• toHaveClass()
• toHaveData(x, y)
• toHaveHtml(x)
• toContainHtml(x)
• toContainText(x)
• toHaveId(x)
• toHaveText(x)
• toHaveValue(x)
• toHaveLength (x)
• toBeDisabled()
• toBeFocused()
• toHandle(x)
• toHandleWith(x, y)
Exemplo de especificação describe("Interface Cadastro de Currículo ", function () {
beforeEach(function () {
jasmine.getFixtures().fixturesPath = ".";
loadFixtures("cadastroCurriculo.html");
});
it("deve exibir campo de ajuda se nome for deixado em branco", function () {
var campoNome = document.getElementById("idNome"), campoSobrenome = document.getElementById("idSobrenome");
campoNome.focus();
campoSobrenome.focus();
expect($("#idAjudaCampoNome").text()).toEqual("Os campos nome e sobrenome são obrigatórios");
});
Resultado dos testes
TESTE O TEMPO TODO!
Referências
• http://pivotal.github.io/jasmine/
• http://blog.tarsisazevedo.com/post/16900846471/teste-javascript-jasmine
• http://evanhahn.com/how-do-i-jasmine/
• https://github.com/velesin/jasmine-jquery
• https://raw.github.com/velesin/jasmine-jquery/master/lib/jasmine-jquery.js
• http://www.goodreads.com/quotes/506689-program-testing-can-be-used-to-show-the-presence-of
• http://junit.sourceforge.net/doc/testinfected/testing.htm