Testes automatizados de JavaScript com Jasmine

Post on 05-Jul-2015

419 views 5 download

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 of Testes automatizados de JavaScript com Jasmine

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”

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