Front End

19 abr, 2013

Testes funcionais com Zombie.JS

Publicidade

Com o desenvolvimento de aplicações grandes, é um pouco desgastante ficar fazendo testes clicando aqui e ali pra saber se você não quebrou nada durante a implementação de alguma funcionalidade, e nem sempre conseguimos reproduzir todas as condições através de testes unitários.

Os testes funcionais vão te proporcionar um ganho de produtividade grande por economizar muito tempo automatizando este processo todo.

Por que fazer testes funcionais?

O próprio nome diz: testes de funcionalidade. Você faz este teste toda vez que desenvolve algo novo. É um teste para saber se aquilo que você desenvolveu está realmente funcionando.

Exemplo de teste funcional:

  1. Abra página inicial do site;
  2. Clique no link de login;
  3. Preencha os campo de e-mail e senha;
  4. Deve bloquear para credenciais inválidas;
  5. Deve permitir para credenciais corretas;
  6. Deve retornar a mensagem “Seja bem vindo!”.

Se você consegue automatizar este processo, você vai evitar muitas surpresas por fazer deploy de coisas bugadas.

Instalando o ambiente

A novidade é o Zombie.js, ele simula o lado cliente de sua aplicação sem precisar de um navegador e ele consegue ser mais rápido que outras ferramentas de testes, como o Selenium.

Para isso, acople ao seu cinto de utilidades os seguintes itens: Node.js, NPM, um compilador C++ e Python.

Não é difícil instalar. Vamos fazer o passo a passo usando o Ubuntu:

$ sudo apt-get install build-essential
$ sudo apt-get install python-software-properties
$ sudo add-apt-repository ppa:chris-lea/node.js
$ sudo apt-get update
$ sudo apt-get install nodejs nodejs-dev npm

Será que está funcionando?

$ node --version
v0.6.2
$ npm --version
1.0.106

Tudo certo! Agora vá para seu ambiente de trabalho e vamos instalar o Zombie.

$ cd /var/www
$ mkdir testes-funcionais
$ cd testes-funcionais
$ npm install zombie

Para testar o Zombie, crie arquivo chamado functional.js e insira:

browser = require('zombie');

Depois rode o arquivo; ele não deverá retornar nenhum erro:

$ node functional.js

Automatizando a navegação

Vamos visitar o Google e capturar o título da página. No arquivo anterior, insira:

Browser = require('zombie');

browser = new Browser()
browser.visit("http://www.google.com", function () {

 console.log(browser.text("title"));

});
$ node functional.js 
Google

Browser é o nosso simulador. Ele vai ter todos os métodos para manipular os elementos. Veja que o browser.visit() recebe como primeiro parâmetro a url e como segundo, o callback, que é a função que ele vai executar após visitar. O browser.text() serve para pegar o texto do elemento “title”.

Agora vamos para um exemplo mais completo:

var Browser = require("zombie");

browser = new Browser()
browser.visit("http://localhost/sistema", function () {

 browser.
 fill("#email", "userteste@example.com").
 fill("#password", "123456").
 pressButton("Login", function() {

 console.log(browser.text("title"));

 })

});

O exemplo é bem fácil de entender. Estou preenchendo dois campos e depois chamando o método pressButton, que também recebe outro callback.

O motivo do Zombie trabalhar tanto com callbacks é simples: ele precisa esperar para que as coisas aconteçam para seguir a sequência da navegação.

Integrando com um framework de testes

Até agora, aprendemos a fazer a navegação com o Zombie. Agora vamos integrá-lo com o Mocha, um framework de testes que vai ajudar a organizar nossos testes funcionais.

$ sudo npm install -g mocha

O seguinte teste, primeiro, verifica se vai logar no sistema com credenciais válidas, e depois ele deve bloquear para credenciais inválidas:

var Browser = require("zombie");
var assert = require("assert");
browser = new Browser()

describe("Deve fazer o login com credenciais válidas", function() {
    before(function(done) {
        browser.visit("http://localhost/sistema", function () {
            browser.
                fill("#email", "userteste@example.com").
                fill("#password", "123456").
                pressButton("Login", done)
        });
    });

    it("Deve redirecionar para a página de usuário", function() {
        assert.equal(browser.location.pathname, "/minha_conta");
    });
    it("Deve retornar mensagem de boas vindas", function() {
        assert.equal(browser.text(".wellcome"), "Seja bem vindo!");
    });
});

describe("Deve bloquear o login para credenciais inválidas", function() {
    before(function(done) {
        browser.visit("http://localhost/sistema", function () {
            browser.
                fill("#email", "blablabla").
                fill("#password", "blablabla").
                pressButton("Login", done)
        });
    });

    it("Deve continuar na página de login", function() {
        assert.equal(browser.location.pathname, "/login");
    });

    it("Deve retornar mensagem de alerta", function() {
        assert.equal(browser.text(".alert"), "Usuário e/ou senha inválida");
    });
});

Após passar o último método a ser executado pelo Zombie, por exemplo, o pressButton, precisamos passar done como callback, para o Mocha saber que o teste acabou. Caso ele não chame, o teste nunca vai finalizar e vai falhar por atingir o tempo limite para rodar os testes:

mocha --timeout 100000 --reporter spec functional.js

E o resultado:

Deve fazer o login com credenciais válidas
    ✓ Deve redirecionar para a página de usuário 
    ✓ Deve retornar mensagem de boas vindas 

  Deve redirecionar para a página de usuário
    ✓ Deve continuar na página de login 
    ✓ Deve retornar mensagem de alerta 

  4 tests complete (10 seconds)

Isso não é quase nada de tudo que você pode fazer com o Zombie e com o Mocha.

Vantagens:

  • Reduz consideravelmente os bugs pós deploy;
  • Quase elimina a necessidade de testes manuais;
  • Fácil de usar;
  • Documentação completa;
  • Rápido.

Desvantagens:

  • Pouco difundido por ser um projeto recente
  • Suporte somente através das issues do github

A documentação oficial tem praticamente tudo que você precisa e uma série de exemplos para tomar como base para iniciar seus testes. Seguem alguns links:

Depois dessa facilidade toda, não tem desculpas para não fazer testes!