Pressione enter para ver os resultados ou esc para cancelar.

Testando aplicações AngularJS com Protractor

É sempre importante fazer testes, e melhor ainda se podemos fazer os testes antes (TDD) e, em algumas situações, até mesmo escrever uma especificação executável, a chamada “documentação viva” do BDD (Behavior-driven development). Mas quando falamos de escrever os testes antes, podemos falar tanto de testes de unidade (unit tests), como de testes e2e (end-to-end).

Mas afinal, o que são testes e2e?

Os testes tipo end-to-end se propõem à automação da utilização da aplicação – como se fosse um usuário final interagindo com a mesma em fluxos do início ao fim, como o processo de login, o preenchimento e envio de um formulário de contato, a simples visita a uma página e muitos outros.

Nem sempre os testes serão utilizados como documentação para pessoas não-técnicas, como se propõe a prática do BDD, portanto nem sempre precisam ser escritos neste formato, mesmo quando sendo utilizados para testes de regressão, os quais se propõem a garantir que funcionalidades que já estavam funcionando não quebraram durante a entrada de novas funcionalidades, melhorias ou correções de bugs.

No caso em que o teste não precisa ser uma documentação que venha ser lida pelo cliente, ou uma pessoa não-técnica, o mesmo pode ser somente código, e se puder ser na linguagem que a equipe de desenvolvimento está acostumada, melhor ainda!

Usando Protractor em testes end-to-end

Meu foco aqui será no uso do Protractor, ferramenta para criação de testes e2e (em JS) para aplicações AngularJS.

Para instalar o Protractor em um ambiente Unix-based (no meu caso Mac OS X Maverick), utilize o comando demonstrado abaixo:

ATENÇÃO: Para realizar a instalação do Protractor é necessário que o NodeJS esteja instalado, e que esta instalação não tenha sido realizada com permissão de super usuário (sudo). Além disso, é necessário que o Java Development Kit (JDK) esteja instalado.

$ npm install -g protractor

Este comando irá instalar o Protractor e o webdriver-manager

Para verificar que o Protractor foi corretamente instalado, verifique a versão instalada, utilizando o comando abaixo:

$ protractor –version

Logo após, será necessário atualizar o webdriver-manager, o qual irá prover um selenium server rodando para dirigir o browser. Execute o comando abaixo:

$ webdriver-manager update

E então inicialize o servidor com o comando abaixo em um console o qual ficará rodando:

$ webdriver-manager start

Com o selenium server rodando, você está pronto para iniciar a criação de seu primeiro teste com o Protractor.

Inicialmente, vamos criar uma pasta para guardar nossos testes.

Dentro da pasta do projeto, crie uma pasta tests (ou utilize o nome que você preferir). Nesta pasta estarão localizados os dois arquivos essenciais para a execução de testes com o Protractor: o arquivo de configuração e o arquivo com os testes propriamente ditos.

Logo após, crie os arquivos conf.js e spec.js e salve-os na pasta tests criada.

Edite o arquivo conf.js no seu editor preferido (utilizei o Atom), e inclua a seguinte configuração (este arquivo especifica onde o selenium server estará rodando, e qual arquivo com a especificação dos testes será utilizado):

// conf.js
exports.config = {  
 seleniumAddress: ‘http://localhost:4444/wd/hub’,
 specs: [‘spec.js’]
}

Para fins de teste experimental, iremos utilizar uma aplicação AngularJS de exemplo, que chama-se todomvc.

Abra o arquivo spec.js criado e cole o seguinte código no mesmo:

// spec.js
describe(‘angularjs todo mvc homepage’, function() {  
 it(‘should have a title’, function() {
   browser.get(‘http://todomvc.com/examples/angularjs/#/’);

   expect(browser.getTitle()).toEqual(‘AngularJS • TodoMVC’);
  });
});

Executando de dentro da pasta tests o comando abaixo, com o *selenium server *rodando, você terá seu primeiro teste rodando (e passando)!

protractor conf.js  
$ protractor conf.js
Using the selenium server at http://localhost:4444/wd/hub  
.
Finished in 2.416 seconds  
1 test, 1 assertion, 0 failures`  

Interagindo com a aplicação

Agora, vamos interagir um pouco mais com a aplicação, visto que neste primeiro testes, somente acessamos a URL da aplicação exemplo, e verificamos seu título.

O plano agora é interagirmos com o campo de texto da aplicação, para simular um usuário real digitando neste campo.

Edite do arquivo spec.js, e adicione o seguinte teste:

it(‘should be able to type a text in the text field’, function() {  
 element(by.id(‘new-todo’)).sendKeys(‘Teste de digitação em campo texto’);
})

Execute novamente e verá seu novo teste rodando (e passando também!):

Finished in 5.956 seconds  
2 tests, 2 assertions, 0 failures

Agora vamos evoluir o teste criado acima, para que após a digitação do texto no campo, o mesmo seja submetido e então seu resultado seja verificado.

Podemos fazer isto da seguinte forma. Edite o arquivo spec.js, e modifique o teste criado acima, refatorado da seguinte forma:

it(‘should be able to type a text in the text field, press enter, and verify the result’, function() {

 var todoTextField = element(by.id(‘new-todo’));
 var todoLabel = element(by.className(‘ng-binding’));
 var text = ‘Teste de digitação em campo texto’

 todoTextField.sendKeys(text);
 todoTextField.sendKeys(protractor.Key.ENTER);

 expect(todoLabel.getText()).toEqual(text);
});

Após a execução do novo teste (refatorado), você deve perceber um aumento no tempo de execução, devido aos novos passos adicionados ao mesmo.

Finished in 6.974 seconds  
2 tests, 2 assertions, 0 failures  

Por fim, vamos deletar o registro criado no cenário acima após a submissão do campo texto, e validar que o mesmo não está mais disponível na lista. Veja o código abaixo.

it(‘should clean the items from the list and verify that no items are available in the list’,function() {

 var toogleAllCheckBox = element(by.id(‘toggle-all’));
 var clearCompletedButton = element(by.id(‘clear-completed’));
 var viewDiv = element(by.className(‘view’));

 toogleAllCheckBox.click();
 clearCompletedButton.click();

 expect(viewDiv.isPresent()).toBe(false);
});

Finished in 7.547 seconds  
3 tests, 3 assertions, 0 failures  

Pronto! Você já tem o conhecimento básico necessário para iniciar a criação de testes de sua aplicação AngularJS, utilizando o Protractor, e tendo a facilidade de desenvolver a aplicação como um todo, na mesma linguagem, inclusive nos testes.

Você também pode acessar no GitHub os arquivos gerados no desenvolvimento deste post.

Referência: Protractor

***

(Atualização – 26/02/16)

Gravamos um podcast conversando sobre atualidades do universo dos testes automatizados.
Coloque o fone de ouvido e venha conhecer a Taverna Taller!

Veja a lista com todos os programas | Taverna Taller no iTunes