Por que eu devo ler este artigo: O código JavaScript geralmente é uma porção crucial de uma aplicação web e tende a se tornar um código confuso se não tivermos os devidos cuidados em sua escrita, sendo assim, este tema é útil a todo projeto web que faça uso de JavaScript, ajudando a manter a qualidade do código JavaScript e facilitando a sua manutenção.

Neste artigo veremos ferramentas e estratégias para a escrita de testes automatizados para códigos JavaScript. Para a escrita dos testes será utilizado um framework de desenvolvimento guiado por comportamento (BDD) chamado Jasmine. Além disso, veremos uma alternativa para a execução dos testes sem interface gráfica onde será explicada a utilização do Chutzpah, que é uma ferramenta open-source voltada para execução de testes JavaScript.


Guia do artigo:

Nos últimos anos a web tem evoluído cada vez mais e isso tem feito com que os usuários deste tipo de aplicação fique cada vez mais exigente, fazendo com que tenhamos que desenvolver aplicações cada vez mais rápidas e leves.

O JavaScript desempenha um grande papel nesse cenário, onde independente do que houver do lado do servidor, a linguagem ainda é a melhor e mais procurada solução para tratar das necessidades do lado do cliente.

Atualmente podemos desenvolver desde pequenas até grandes aplicações utilizando poucos recursos do lado do servidor, o que na maioria dos casos entendemos como Single Page Application.

O conceito de SPA envolve a utilização de recursos web em grande escala para o desenvolvimento de aplicações, sendo que o foco do desenvolvimento é manter a responsabilidade de manipulação de páginas e recursos de interface para o próprio lado do cliente (navegador) e mantermos do lado servidor apenas APIs RESTful ou Web Services fornecendo dados.

Em paralelo à evolução da web, a engenharia de software também seguiu evoluindo, e com ela a disciplina de testes também ganhou força em toda indústria de software. Por outro lado, é interessante observar que, como tradicionalmente as aplicações web tinham muito mais código no lado servidor, as linguagens com esta característica acabaram evoluindo mais rapidamente do que as linguagens do lado cliente. Porém, com a evolução da web o JavaScript acabou ficando em foco, sendo fundamental para toda a interação e leveza que temos nas aplicações web atuais.

Dado a utilização em larga escala de recursos web em aplicações desse tipo, começaram a surgir iniciativas para garantir a qualidade destas aplicações, e uma destas iniciativas é a prática de testes de JavaScript.

Testando seu JavaScript você terá uma maior segurança de que seu usuário estará livre de contratempos por conta de erros na aplicação.

Ferramentas

Apesar do teste de JavaScript ainda não ser muito difundido no mercado, já existem diversas ferramentas e bibliotecas que nos auxiliam na escrita deste tipo de testes, como por exemplo o QUnit e o Jasmine, que será tema deste artigo.

O Jasmine é um framework de testes JavaScript baseado na metodologia de desenvolvimento guiado por comportamento. O Jasmine foi desenvolvido em JavaScript puro sendo totalmente independente de qualquer outra framework javascript. Além disso, com o Jasmine podemos testar tanto a lógica quanto o comportamento de nosso código, sem a necessidade de utilização do DOM. A sintaxe utilizada na escrita dos testes é bastante clara e limpa o que ajuda na escrita dos mesmos, além disso, esta escrita possibilita fácil leitura do código, até mesmo por quem não possui conhecimento da linguagem ou tecnologia empregada.

O Jasmine conta com seu próprio script de execução de testes, que utiliza uma página web para exibir os resultados dos testes executados, o desenvolvedor só precisa se preocupar em referenciar na página os scripts de dependências para execução dos testes, os scripts de testes e as implementações a serem testadas. A utilização deste script é bem simples e pode ser encontrado na documentação da ferramenta.

Nota:
Desenvolvimento guiado por comportamento (BDD) é uma prática de desenvolvimento que envolve diretamente desenvolvedores e a área de negócio, com pessoas não técnicas. A ideia principal é trazer os testes ao nível de negócio, possibilitando a escrita de testes por meio de uma linguagem nativa, o que pode ser papel de pessoas não técnicas do time, e as implementações desses testes ficam a cargo dos desenvolvedores, utilizando uma linguagem de programação.

Nota:
DOM (Document Object Model) é uma interface independente de tecnologia e de linguagem, que permite aplicações e scripts acessarem e atualizarem o conteúdo, a estrutura e o estilo de documentos. Saiba mais sobre DOM.

Imprevisões do JavaScript

Uma das motivações para a escrita dos testes para seu JavaScript é a imprevisibilidade que a linguagem pode apresentar. Na Figura 1 é utilizado a Ferramenta do Desenvolvedor do navegador (Internet Explorer 10) para demonstrar algumas das imprevisibilidades da linguagem JavaScript. Em algumas situações os testes irão gerar erros completamente inesperados.

Imprevisibilidade do JavaScript
Figura 1. Imprevisibilidade do JavaScript.

Como pode ser visto na Figura 1 temos algumas operações aritméticas. No primeiro caso é feito uma soma de dois Arrays que resulta uma string vazia e logo em seguida é feita a subtração dos mesmos tipos de elementos, resultando no valor zero. O previsível nestes cenários seria retornar algo do mesmo tipo dos elementos da operação, mas o JavaScript possui estas e outras imprevisibilidades, como por exemplo uma data tem os dígitos de seu mês representados na base zero, ou seja, o número zero representa janeiro e o número onze representa dezembro.

O exemplo utilizado para a cobertura de testes é o famoso FizzBuzz, por ser um exemplo tradicional e conhecido de muitos programadores, que consiste em um desafio de programação, geralmente utilizado em Coding Dojos. O contexto é: dado um número de entrada, a implementação deve retornar ‘Fizz’ caso o número seja divisível por 3, ‘Buzz’ caso o número seja divisível por 5 e ‘FizzBuzz’ caso o número seja divisível por 3 e por 5. Fora esses casos a implementação deve retornar o próprio número fornecido como entrada. Durante o desenvolvimento do nosso exemplo utilizaremos uma metodologia de desenvolvimento de software chamada desenvolvimento guiado por testes (TDD – Test Driven Development).

TDD é uma prática de desenvolvimento que consiste na escrita dos testes antes mesmo do código ser implementado. Ao contrário do que muita gente pensa, o TDD é uma prática muito mais de especificação do que de testes, isso porque a escrita dos testes antes do código implica em pensar nas necessidades que temos para resolver o problema, fazendo com que tenhamos que pensar na forma como nossas classes e métodos serão consumidos, nos auxiliando na especificação de nosso código. Após escrito o teste, o código é implementado e o teste é executado.

Escrevendo os primeiros testes

Como o Jasmine é uma bilioteca JavaScript, basta adicionarmos sua referência à página HTML onde estiver o código de teste para que tenhamos acesso às suas funções.

Seguindo a prática do TDD, vamos escrever primeiro nossos testes. Como ainda não existe código a ser testado, o teste irá falhar, mas isso é normal dentro do contexto do TDD. Nosso teste deverá cobrir todas as possibilidades de nosso algoritmo futuro, ou seja, deveremos testar se o valor é divisível por 3, por 5, por 3 e por 5, ou se não é divisível por nenhum dos dois números.

Basicamente o Jasmine funciona através de verificações (asserções) de determinados valores de forma a garantir que os mesmos atendam aquilo que era esperado. Na Listagem 1 nós temos o uso dos principais comandos do Jasmine para a criação de nosso teste JavaScript.

Listagem 1. Criação dos testes em JavaScript.
01 describe('Desafio FizzBuzz', function () {
  
      describe('Fizz', function () {
          it('Deve retornar Fizz quando a entrada for 3', function () {
              expect(FizzBuzz(3)).toBe('Fizz');
          });
          it('Deve retornar Fizz quando a entrada for 9', function () {
              expect(FizzBuzz(9)).toBe('Fizz');
          });
      });

      describe('Buzz', function () {
          it('Deve retornar Buzz quando a entrada for 5', function () {
              expect(FizzBuzz(5)).toBe('Buzz');
          });
          it('Deve retornar Buzz quando a entrada for 25', function () {
              expect(FizzBuzz(25)).toBe('Buzz');
          });
      });

      describe('FizzBuzz', function () {
          it('Deve retornar FizzBuzz quando a entrada for 15', function () {
              expect(FizzBuzz(15)).toBe('FizzBuzz');
          });
          it('Deve retornar FizzBuzz quando a entrada for 30', function () {
              expect(FizzBuzz(30)).toBe('FizzBuzz');
          });
      });

      describe('Não é divisível por 3 ou 5', function () {
          it('Deve retornar 2 quando a entrada for 2', function () {
              expect(FizzBuzz(2)).toBe(2);
          });
          it('Deve retornar 4 quando a entrada for 4', function () {
              expect(FizzBuzz(4)).toBe(4);
          });
      });
  });

Na Listagem 1 temos a implementação dos nossos cenários de teste. Uma ótima opção do Jasmine é a possibilidade de separar os testes em contextos através da função describe (linha 1), que define um novo contexto para o teste. Esta função recebe um nome no primeiro parâmetro e outra função no segundo, sendo esta a função que contém o teste a ser executado.

Para a escrita dos testes o Jasmine nos fornece a função it (linha 4) que recebe um nome e uma função com a implementação do teste. Observe que nas linhas 4 e 7 nós usamos a função it, ou seja, estamos criando dois cenários de teste para validar que o retorno deve ser fizz. Para a asserção dos testes no Jasmine, utilizamos a função expect (linha 5) seguida de uma função apropriada para a verificação desejada, como por exemplo, a função toBe (linha 5) que verifica se o valor esperado é igual ao obtido. É possível fazer mais de uma asserção por teste, mas na maioria dos casos é recomendado que seja feita apenas uma, pois fazendo isso os possíveis erros serão indicados isoladamente e encontrados com mais facilidade.

Além do toBe, o Jasmine possui uma série de outros métodos para asserções, como mostrado abaixo:

  • toEqual: Serve para validar se o valor esperado é igual ao valor atual. Serve tanto para valores primitivos quanto para objetos.
  • toMatch : Serve para validar se o valor esperado atende a uma determinada expressão regular, passada como parâmetro.
  • toBeDefined : Serve para validar se o valor esperado é diferente de undefined.
  • toBeUndefined : Serve para validar se o valor esperado é igual a undefined.
  • toBeNull : Serve para comparar se o valor esperado é nulo.
  • toBeTruthy : Serve para comparar se o valor esperado é passível de sofrer cast para um valor boolean true.
  • toBeFalsy : Serve para comparar se o valor esperado é passível de sofrer cast para um valor boolean false.
  • toContain : Serve para validar se o valor esperado(sendo este um array) contém um item passado como parâmetro.
  • toBeLessThan : Serve para validar se o valor esperado é menor do que o valor passado como parâmetro.
  • toBeGreaterThan: Serve para validar se o valor esperado é maior do que o valor passado como parâmetro.
  • toBeCloseTo: Serve para realizar a comparação baseado na precisão de casas decimais.
  • toThrow: Serve para validar se uma função lança uma exception.

Observe que, como parâmetro do método expect(linhas 5 e 8), nós temos o método FizzBuzz. Este é o nosso método (que ainda não existe) que irá realizar a verificação do algoritmo de FizzBuzz. A implementação deste método pode ser vista na Listagem 2.

Listagem 2. Implementação JavaScript a ser testada.

 FizzBuzz = function (entrada) {
      if (entrada % 3 == 0 && entrada % 5 == 0) return 'FizzBuzz';
      if (entrada % 3 == 0) return 'Fizz';
      if (entrada % 5 == 0) return 'Buzz';
  
      return entrada;
  }

Na Listagem 2 temos uma primeira implementação para o nosso problema. Nosso método recebe um parâmetro de entrada (linha1) e verifica se o mesmo é divisível por 3 e por 5, gerando a resposta apropriada. Após a implementação de nossa função, já poderíamos executar nosso teste.

Durante a escrita de nossa solução podemos executar os testes e ter feedback imediato de quais cenários o nosso código está cobrindo. É necessária a criação de uma infraestrutura básica, e bem simples, para que os testes possam ser executados. Mais adiante veremos como prosseguir com a execução dos testes.

Por mais que a solução de um problema seja aceitável, geralmente temos diversas formas de chegar ao mesmo resultado. Possivelmente haverá uma forma mais elegante que o desenvolvedor possa encontrar, mas quais garantias que ele pode ter ao alterar um código de que o resultado realmente será o esperado, e de que nada tenha sido quebrado durante a refatoração? Há sempre a opção de executar testes manualmente, mas dependendo da complexidade do problema isso pode não ser viável. Com testes automatizados o desenvolvedor está a poucos cliques de distância para descobrir se tudo está funcionando como o esperado.

Listagem 3. Refactoring da implementação.

   FizzBuzz = function (entrada) {
     return (entrada % 3 ? '' : 'Fizz') + 
     ( entrdaa % 5 ? '' : 'Buzz') || entrada;
  }

Na Listagem 3 temos a refatoração de nossa solução. Observe que o código ficou muito mais enxuto, reduzido a apenas uma linha.

Jasmine e jQuery

Existem diversas extensões para o Jasmine sendo que a mais utilizada é a jasmine-jquery, que provê diversas novas opções para asserções de elementos do DOM utilizando seletores do jQuery. Como é possível imaginar, a extensão depende da biblioteca jQuery, ou seja, ela também deve estar referenciada no executor dos testes.

Na Listagem 4 podemos ver a utilização desta extensão com nosso exemplo de FizzBuzz. Vamos testar o cenário em que nossa aplicação exibe o resultado em um elemento da página, aplicando uma classe css dependendo do resultado da função.

Listagem 4. Testando manimulações no DOM.

 describe('Fizz', function () {
      beforeEach(function () {
          FizzBuzzNaTela(3);
      });
  
      afterEach(function () {
          $('#resultado').text('').removeClass();
      });
  
      it('Deve imprimir na tela', function () {
          expect($('#resultado')).toHaveText('Fizz');
      });
  
      it('O resultado deve ter uma característica visual única',
               function () {
          expect($('#resultado')).toHaveClass('fizz');
      });
  });

Na Listagem 4 podemos ver o uso de dois novos métodos do Jasmine. Na linha 2 temos o beforeEach, onde podemos definir uma rotina para ser executada antes de cada teste e na linha 6 temos o afterEach que nos permite definir uma função para ser executada após cada teste. Estes métodos são muito úteis para definirmos configurações iniciais de teste e para limparmos o ambiente, para que um teste não impacte no outro.

Com isso, antes de cada teste desse contexto ser executado, é chamada a função FizzBuzzNaTela para imprimir o resultado em um elemento do DOM, e logo após cada teste é feita uma limpeza no elemento, removendo o possível texto e possíveis classes CSS (linha 7).

No primeiro teste (linha 10) é verificado se após a execução da implementação o elemento com id resultado possui o texto ‘Fizz’. E no segundo teste (linha 14) é verificado no mesmo elemento se o ele possui a classe CSS ‘Fizz’.

Spies

Uma das características mais importantes de uma ferramenta de testes é a possibilidade de simular o comportamento de parte do nosso código a fim de criar um teste de unidade. O teste de unidade tem a responsabilidade de testar uma porção do código isolada de qualquer dependência externa, por exemplo, ao testar uma função que possui uma dependência de um código externo deve-se simular o comportamento deste código durante o teste a fim de isolar a porção a ser testada.

Tanto para a simulação de comportamento como para verificação de quando um código deveria ser utilizado, é possível utilizar a função spyOn do Jasmine.

Os testes da Listagem 5 foram escritos baseados em uma página web que recebe um valor numérico em uma caixa de texto, que ao clicar em um botão de submissão, tem o valor digitado enviado para o servidor e processado com um algoritmo com as mesmas regras do desafio FizzBuzz, que foram utilizadas nos exemplos anteriores, resultando na impressão do resultado na página.

Listagem 5. Espiando e substituindo comportamento.

 describe('FizzBuzz do servidor', function () {

      var fizzBuzzDoServidor = null;
  
      beforeEach(function () {
          fizzBuzzDoServidor = new FizzBuzzDoServidor();
      });
  
      describe('Fizz', function () {
          it('Deve exibir na página o resultado retornado do
                   servidor', function () {
              spyOn(fizzBuzzDoServidor, 'obterResultado').andReturn('Fizz');
  
              fizzBuzzDoServidor.renderizarResultado();
  
              expect($('#resultado')).toHaveText('Fizz');
          });
      });
  
      it('Deve buscar resultado no servidor ao clicar no botão de
                busca', function () {
          spyOn(fizzBuzzDoServidor, 'obterResultado');
  
          $('button#obter_resultado').click();
  
          expect(fizzBuzzDoServidor.obterResultado).toHaveBeenCalled();
      });
  });

Como pode ser visto no primeiro teste da Listagem 5, dentro do contexto de Fizz (linha 9), o comportamento da função obterResultado do objeto fizzBuzzDoServidor é substituído por apenas um retorno utilizando a função andReturn do spyOn, como mostrado na linha 11. Dado esse retorno fixo, dentro da função renderizarResultado é utilizado a função obterResultado. Com isso podemos verificar se dado um valor retornado do servidor o mesmo é exibido na página corretamente.

No segundo teste (linha 19) que está dentro do contexto principal, é verificada se uma função é chamada ao clicar em um botão da página. Essa verificação é feita através da função toHaveBeenCalled, chamada a partir do wrapper expect da função espiada.

Cenários assíncronos

Muitas vezes caímos em cenários onde nossas operações não são imediatas, ou seja, são assíncronas. Temos um cenário assim geralmente quando precisamos, por exemplo, realizar um processamento demorado no servidor e não queremos que o cliente tenha seu navegador travado durante este processamento, ou para que não seja feito o postback da página (quando uma página inteira e todo o seu conteúdo são enviados para o servidor para que ele a processe e retorne uma nova página inteira para ser carregada no cliente).

Como podemos ver nas Listagem 6 e 7, é possível testar esses cenários utilizando o Jasmine.

Listagem 6. Simulação de cenário assíncrono.

   DelayFizzBuzzAsync = function (num) {
     var valor;
   
     setTimeout(function () {
       this.valor = FizzBuzz(num);
     }, 1000);
  
     return this.valor;
   }

Na Listagem 6 podemos ver o código que será testado na Listagem 7. Trata-se de uma chamada a função FizzBuzz(), que já escrevemos em cenários passados, adicionando um tempo de retorno. Haverá uma espera de 1000 milissegundos até que a função seja executada, dando a sensação de uma chamada mais demorada.

Listagem 7. Testando cenários assíncronos.

   describe('FizzBuzz assíncrono', function () {
  
     beforeEach(function () {
       var executado = false;
       var valor = '';
   
       runs(function () {
         this.valor = DelayFizzBuzzAsync(10);
  
           setTimeout(function () {
             return executado = this.valor != '';
           }, 3000);
         });
  
         waitsFor(function () {
           return executado;
         });
       });
  
       it('Função assíncrona retornou o 
         resultado esperado', function () {
         expect(valor).toBe('Buzz');
       });
     });

Na Listagem 7 utilizamos a função runs (linha 07) para executar o código assíncrono que desejamos testar e para esperá-lo utilizamos a função waitsFor (linha 15). Neste cenário estamos esperando até que o valor da variável valor (linha 05) seja diferente de seu valor padrão. Na função waitsFor também é possível passar uma mensagem de erro e tempo máximo de espera como parâmetro, caso esses parâmetros sejam passados e caso a execução esperada pela função não seja executada, o teste falhará e exibirá a mensagem que foi passada para a função. O erro padrão para os casos de testes que não passem é uma mensagem informando que o tempo máximo de espera (5000 milissegundos é o padrão) foi atingido e nada aconteceu durante a espera.

Pode-se notar durante os testes que a espera dada para cada teste é de tempo real, ou seja, para cada teste é esperado o tempo necessário para a execução assíncrona do cenário, então é recomendado que os testes assíncronos sejam executados por último, para caso queira ter um feedback mais rápido dos testes de cenários síncronos.

Apesar de ser um ótimo framework de BDD, a escrita de testes para cenários assíncronos com o Jasmine é de certa forma custosa devido à preparação necessária para a escrita do teste. Para tirar proveito dessa funcionalidade do framework de maneira menos custosa, existe um projeto open-source chamado jasmine.async, que estende o framework para ajudar na escrita de testes com este tipo de cenário.

Executando os testes

Os testes podem ser executados utilizando os scripts de execução da própria ferramenta, para isso é necessário utilizar uma página web, como pode ser visto na Listagem 8. Nessa página é necessário conter as dependências do executor de testes da ferramenta, a referência dos scripts de testes (linha 11) e dos scripts de implementação (linha 13), além disso, é necessário um script de execução (linha 17) no final da tag head que é disponibilizado na documentação da própria ferramenta.

Listagem 8. Execução dos testes via script em uma página HTML.

      <!DOCTYPE html>
      <html>
      <head>
        <title>Jasmine Spec Runner</title>
        <meta http-equiv="Content-Type" 
             content="text/html; charset=UTF-8"/>
        <link rel="stylesheet" href="lib/jasmine-1.2.0/
              jasmine.css">
        <script src="lib/jasmine-1.2.0/jasmine.js"></script>
        <script src="lib/jasmine-1.2.0/jasmine-html.js"
          ></script>
      
        <!-- Script de testes -->
        <script src="FizzBuzzSpec.js"></script>
      
        <!-- Script de implementações -->
        <script src="FizzBuzz.js"></script>  
      
        <script type="text/javascript">
            (function () {
                var jasmineEnv = jasmine.getEnv();
                jasmineEnv.updateInterval = 1000;
      
                var htmlReporter = new jasmine.HtmlReporter();
      
                jasmineEnv.addReporter(htmlReporter);
      
                jasmineEnv.specFilter = function (spec) {
                    return htmlReporter.specFilter(spec);
                };
      
                var currentWindowOnload = window.onload;
      
                window.onload = function () {
                    if (currentWindowOnload) {
                        currentWindowOnload();
                    }
                    execJasmine();
                };
      
                function execJasmine() {
                    jasmineEnv.execute();
                }
            })();
        </script>
      </head>
      <body></body>
      </html>

Na Figura 2 pode ser visto o resultado da execução dos testes utilizando o código apresentado na Listagem 8. Assim como os testes são separados por contextos diferentes, eles também podem ser executados separadamente, tanto por contexto como por unidade, para isto basta clicar no título do contexto ou no próprio teste. No canto superior direito é indicado em segundos o tempo decorrido na execução dos testes.

Executando os testes via script em uma página HTML
Figura 2. Executando os testes via script em uma página HTML.

Caso algum teste falhe, será gerado um relatório com a stack trace do erro ou o teste indicará que um resultado esperado foi diferente do obtido. Na Figura 3 podemos ver um exemplo desses dois cenários, onde um dos testes obtêm um resultado diferente do esperado e no outro ocorre um erro na utilização do código implementado.

Exemplo
de falha na execução dos testes
Figura 3. Exemplo de falha na execução dos testes.

Nas Figuras 2 e 3 nós vimos como executar os testes pela interface gráfica da página HTML que criamos. No entanto, estes testes poderiam ser executados automaticamente, dentro de um processo de build ou de integração contínua por exemplo. Nestes casos não teríamos interface gráfica para disparar os testes.

Uma das alternativas para executar os testes sem precisar abrir o navegador é utilizar o Chutzpah. Essa é uma ferramenta de execução de testes que faz uso de um headless WebKit chamado PhantomJS, que soluciona um grande problema que desenvolvedores podem enfrentar na utilização de navegadores comuns para a execução de seus testes, o cache. Todos devem prestar bastante atenção com o cache dos navegadores, porque assim como isto pode ser um problema durante o desenvolvimento, também pode gerar grandes dores de cabeça durante a execução dos testes.

A grande desvantagem de utilizar esse executor é a opção de depuração do código que é perdida, então quando houver a necessidade de depurar o código é recomendado que seja utilizado o navegador.

Na Figura 4 podemos ver o resultado dos testes executados pelo prompt de comando do Windows. Como podemos notar, os testes foram executados em menos tempo, que é uma das vantagens da utilização desse executor.

Com a utilização dessa ferramenta se torna mais fácil incluir os testes de JavaScript ao seu servidor de build ou a um servidor de integração contínua.

Listagem 9. Comando para execução do Chutzpah.

"%~dp0\lib\chutzpah.2.1.0\chutzpah.console.exe" 
"%~dp0executor.html"

Na Listagem 9 podemos ver como é simples a utilização do Chutzpah, podemos executá-lo direto do prompt de comando utilizando o comando da Listagem 9, que é composto pelo caminho do executor da ferramenta, e o caminho do executor do Jasmine. A execução dos testes não necessita do executor do Jasmine, mas já que o temos, vamos aproveitá-lo. Para não termos que escrever a linha de comando todas as vezes que quisermos executar os testes, basta apenas criar um arquivo de comando (Executor.cmd), colar essa linha da Listagem 9, e executá-lo via prompt como demonstrado na Figura 4.

Executando os testes com o Chutzpah
Figura 4. Executando os testes com o Chutzpah.

Headless WebKit, também conhecido como headless browser, é a engine utilizada por trás de um navegador. Em outras palavras é um navegador sem interface gráfica. É geralmente utilizado para fornecer informações de páginas web para outras aplicações, no nosso caso, para o Chutzpah.

Conclusão

Conhecemos aqui a estrutura e execução de testes com a ferramenta Jasmine, mas também há diversas outras disponíveis, como o QUnit que foi desenvolvido para testar o código do jQuery.

Além disso, podemos combinar o uso de ferramentas de teste com ferramentas que medem a cobertura dos mesmos, como por exemplo, o JSCoverage.

Com essas ferramentas em mãos podemos criar códigos JavaScript muito confiáveis e estáveis, escolha a ferramenta que se sinta mais confortável e faça bom proveito.

Confira também