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