[38º guru sp] automação de testes web em ruby com cucumber e webdriver
TRANSCRIPT
www.qualister.com.br
(48) 4052-9536 / 9540 [email protected]
Automação de Testes Web em Ruby com
Cucumber e Webdriver
por Júlio de Lima @juliodelimas
38º encontro do Guru-SP | São Paulo, 07 de novembro de 2015
Palestrante
Júlio de LimaEspecialista em teste de software com ênfase em automação de testes de software, possui formação em Tecnologia da Informação e certificações internacionais (CTFL e CTAL-TM pelo ISTQB) e nacional (CBTS pela ALATS) relacionada a testes de software além de ser certificado na ferramenta SoapUI Pro pela SmartBear Software. Atualmente é consultor de automação de testes e instrutor na Qualister e é professor de disciplina de teste de software em cursos de pós-graduação no Paraná e em Santa Catarina.
twitter.com/juliodelimasbr.linkedin.com/in/juliodelimas
goldtips.by/juliodelimas
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
3
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo CincoCucumber
Especificação dos Testes
Frameworks utilizados
4
Selenium Webdriver
Driver
RSpec Expectativas
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
Cucumber é um framework escrito em Ruby utilizado para automação de testes de aceitação. Testes escritos com Cucumber descrevem como a aplicação deve se comportar.
A descrição dos comportamentos da aplicação pode ser feitos em diversos idiomas, inclusive em Português. Cucumber é escrito em Ruby, mas pode ser utilizado em diversas linguagens de programação, como: Java, C# e Python.
A descrição dos comportamentos da aplicação é composta basicamente por Funcionalidade, Cenários e Passos do cenário. Esta descrição é feita utilizando Gherkin, um modelo de escrita compreendida pelo Cucumber.
Cucumber
5
Cucumber Especificação
dos Testes
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
O que o Cucumber pode fazer
▪ Escrever comportamentos do sistema em texto puro, em diversos idiomas ▪ Testar classes e métodos Ruby, Java, C# e Python ▪ Executar testes a partir de linha de comando ▪ Integrar-se com ferramentas de integração contínua ▪ Gerar documentação dos comportamentos da aplicação ▪ Gerar relatórios de execução dos testes
Cucumber
6
Cucumber Especificação
dos Testes
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
Gherkin é a sintaxe utilizada para escrever funcionalidades no Cucumber. É um domínio específico de linguagem para escrever regras de negócio de fácil leitura
Sintaxe criada para ser utilizada por usuário técnicos e não técnicos. Funcionalidades escritas no formato Gherkin também são usadas como documentação do sistema. Elas não detalham como a funcionalidade deverá ser implementada.
Cada linha da descrição da funcionalidade é iniciada por uma palavra chave e o escopo é definido utilizando indentação. Funcionalidades em Gherkin podem ser escritas em português ou em mais de 30 idiomas. Linhas podem ser comentadas utilizando “#” no início da linha
Gherkin
7
Gherkin DSL
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
Exemplo: # language: ptFuncionalidade: Descrição da funcionalidade desejada Sendo alguém que será beneficiado Posso utilizar uma funcionalidade do sistema Para que possa alcançar um benefício para o negócio Cenário: Uma situação de negócio Dado que tenho uma precondição Quando eu executo alguma ação E executo alguma outra ação Então recebo uma saída resultante das ações executadas Mas algo muda no estado atual do sistema
Gherkin
8
Gherkin DSL
Daniel Wildt e Rafael Helm - Histórias de Usuário 3a Ed.(www.wildtech.com.br/historias-de-usuario/)
Introducing BDD | Dan North & Associates (dannorth.net/introducing-bdd/)
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
Os arquivos são salvos com a extensão .feature.
Funcionalidades podem ter múltiplos cenários e cada cenário é iniciado pela palavra chave “Cenário”.
Cada cenário possui passos, sempre iniciados pelas palavras chave: Dado, Quando, Então, E e Mas.
Gherkin
9
Gherkin DSL
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
Selenium Webdriver é um framework de automação de testes originalmente escrito em Java, mas posteriormente disseminado em diversas linguagens de programação.
Possui uma biblioteca completa de simulação de ações do usuário sobre o browser, permitindo assim automatizar estas ações.
O WebDriver conversa diretamente com um browser real (Firefox, por padrão), por isso, há a necessidade de tê-lo instalado na máquina.
O que é?
10
Selenium Webdriver
Driver
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
O RSpec é um framework BDD (Behavior-Driven Development), escrito em Ruby, utilizado para estruturar os testes em ordem comportamental, utilizando escrita em linguagem natural.
Ele também possui uma potente biblioteca de expectativas e matchers, que é utilizada juntamente com outros diversos frameworks de validação de aplicações.
Usaremos ele em conjunto com os demais frameworks para validar nossas aplicações.
O que é?
11
RSpec Especificação
dos testes
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
12
Preparando o projeto
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
Preparando o projeto
1. Crie o diretório C:\GURUSP\Cucumber2. Crie o diretório C:\GURUSP\Cucumber\features3. Crie o diretório C:\GURUSP\Cucumber\features\step_definitions4. Crie o diretório C:\GURUSP\Cucumber\features\support5. Instale o Bundler, um gerenciador de dependências, com gem install bundler6. Execute o comando “bundle init” dentro do diretório Cucumber
Adicione as dependências ao Gemfile que foi gerado na raiz do projeto:# A sample Gemfile source "http://rubygems.org" # gem "rails" gem 'selenium-webdriver', '~> 2.48.1' gem 'rspec-expectations', '~> 3.3.1' gem 'cucumber', '~> 2.1.0'
8. Execute o comando "bundle install”9. E então veremos o status abaixo:Bundle complete! 3 Gemfile dependencies, 15 gems now installed. 13
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
14
Hands-on
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
15
Hands-on
Crie dentro do diretório “features” um arquivo chamado gerenciarMovimentacoes.feature” e adicione a ele o seguinte texto:# language: pt
Funcionalidade: Gerenciar Movimentações Sendo o administrador de uma loja Posso gerenciar movimentações Para que possa ver, de forma simples, as entradas e saídas de valores Cenário: Gerando uma movimentação de entrada Dado que eu esteja autenticado como administrador E que eu tenha acessado o menu "Movimentações" E clicado em "Nova movimentação” para inserir uma movimentação Quando informar "Entrada" como tipo de movimentação E informar "50,00" como valor da movimentação E Informar "PlayStation e XBox" como itens da movimentação E clicar em "Gravar" Então verei a mensagem "Sucesso ao inserir a movimentação" como sucesso da operação
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
16
Hands-on
Agora, execute o comando cucumber --color na raiz do projeto e então veremos como foi a execução dos cenários:
1 scenario (1 undefined)
8 steps (8 undefined)
0m0.062s
Serão gerados snippets de código para os cenários ainda não definidos, veja um exemplo:
You can implement step definitions for undefined steps with these snippets:
Dado(/^que eu esteja autenticado como administrador$/) do pending # Write code here end
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
17
Hands-on
O que faremos agora é criar um arquivo chamado "gerenciarMovimentacoes.rb" no diretório “step_definitions" e então cole o snippet de código que foi copiado do console:
# encoding: utf-8 Dado(/^que eu esteja autenticado como administrador$/) do pending # Write code here end
Este método propõe que façamos login na aplicação que desejamos testar, então, escreveremos comandos do Selenium Webdriver, que reproduzirão as ações do usuário, começando por abrir o navegador, maximizar a tela e determinar um tempo máximo de espera:
@navegador = Selenium::WebDriver.for :firefox @navegador.manage.window.maximize @navegador.manage.timeouts.implicit_wait = 5
O “@“ serve para fazer com que a variável possa navegar por todos os passos do nosso teste. Agora iremos navegar até a página inicial de nossa aplicação:
@navegador.get ‘http://localhost:4567/quickloja/'
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
18
Hands-on
E agora, preencher os campos do formulário de login e clicar no botão “Entrar" para ter acesso ao interior da aplicação, veja:
@navegador.find_element(:id, 'usuariologin').send_keys("teste") @navegador.find_element(:id, 'usuariosenha').send_keys("123") @navegador.find_element(:css, ‘button[type="submit"]').click
Ótimo, já escrevemos o primeiro passo, antes de executá-lo precisamos criar um arquivo “env.rb” no diretório “features/support" e adicionar a ele os requires para o RSpec, Cucumber e Webdriver:
# encoding: utf-8 require 'cucumber/formatter/unicode' require 'rspec/expectations' require ‘selenium-webdriver'
Agora executaremos os cenários novamente:
cucumber --color
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
19
Hands-on
O resultado será a apresentação do primeiro passo em verde:
Dado que eu esteja autenticado como administrador # features/step_definitions/gerenciarMovimentacoes.rb:3
E os demais em amarelo, uma vez que ainda não foram definidos. E o status geral demonstrará o seguinte resultado:
1 scenario (1 undefined) 8 steps (7 undefined, 1 passed) 0m7.539s
O próximo passo é copiar o segundo passo e automatizar os testes que demonstram que ele pode ser executado com sucesso, logo, copio o snippet para o arquivo “gerenciarMovimentacoes.rb" e crio a automação para ele, veja:
Dado(/^que eu tenha acessado o menu "([^"]*)"$/) do |arg1| pending # Write code here that turns the phrase above into concrete actions
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
20
Hands-on
Este passo tem duas características diferentes, uma expressão regular e uma variável que receberá o valor extraído por ela, veja:
Dado(/^que eu tenha acessado o menu "([^"]*)"$/) do |arg1| pending # Write code here end
Vamos renomear a variável “arg1" para “menu”. A variável menu possuirá o nome do menu a ser clicado, então nosso código ficará assim:
Dado(/^que eu tenha acessado o menu "([^"]*)"$/) do |menu| @navegador.find_element(:link_text, menu).click end
Ao executar o teste agora, veremos que dois casos já foram executados, restando agora 7 passos indefinidos, okay, vamos ao próximo:
Dado(/^clicado em "([^"]*)" para inserir uma movimentação$/) do |arg1| pending # Write code here end
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
21
Hands-on
Que ficará assim:
Dado(/^clicado em "([^"]*)" para inserir uma movimentação$/) do |botao| @navegador.find_element(:link_text, botao).click end
Agora restam 5 passos, vamos ao próximo:
Quando(/^informar "([^"]*)" como tipo de movimentação$/) do |arg1| pending # Write code here end
Que ficará assim:
Quando(/^informar "([^"]*)" como tipo de movimentação$/) do |tipo| movimentacaotipo = Selenium::WebDriver::Support::Select.new(@navegador.find_element(:name, "movimentacaotipo")) movimentacaotipo.select_by(:text, "Saída") # ou :index ou :value end
Agora restam 4 passos, o próximo é:
Quando(/^informar "([^"]*)" como valor da movimentaçao$/) do |arg1| pending # Write code here end
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
22
Hands-on
Que ficará assim:
Quando(/^informar "([^"]*)" como valor da movimentação$/) do |valor| @navegador.find_element(:name, "movimentacaovalor").send_keys(valor) end
Agora restam 3 passos, vamos ao próximo:
Quando(/^Informar "([^"]*)" como itens da movimentação$/) do |itens| pending # Write code here end
Que ficará assim:
Quando(/^Informar "([^"]*)" como itens da movimentação$/) do |itens| @navegador.find_element(:name, "movimentacaoitens").send_keys(itens) end
Agora restam 2 passos, o próximo é:
Quando(/^clicar em "([^"]*)"$/) do |arg1| pending # Write code here end
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
23
Hands-on
Que ficará assim:
Quando(/^clicar em "([^"]*)"$/) do |botao| @navegador.find_element(:css, ".btn.btn-primary").click end
Vamos ao último passo:
Entao(/^verei a mensagem "([^"]*)" como sucesso da operação$/) do |arg1| pending # Write code here end
Que ficará assim:
Entao(/^verei a mensagem "([^"]*)" como sucesso da operação$/) do |msg| expect(@navegador.find_element(:css, ".alert").text).to eq(msg) @navegador.quit end
Obs. Note que usamos o método “quit" para fechar o browser ao fim da execução, agora, ao executar o teste teremos o seguinte resultado:
1 scenario (1 passed) 8 steps (8 passed) 0m12.360s
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
24
Gerar um relatório de execução no formato HTML
cucumber --format html --out relatorio.html
Hands-on
Saída:
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
25
Links interessantes
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
26
Documentação da API do Cucumber
http://www.rubydoc.info/gems/cucumber/Cucumber
Documentação da API do Selenium WebDriver
http://www.rubydoc.info/gems/selenium-webdriver/0.0.28/Selenium/WebDriver
https://selenium.googlecode.com/svn/trunk/docs/api/rb/Selenium/WebDriver.html
Relatórios de execução
www.qualister.com.brwww.qualister.com.br
Texto do Título
• Nível de Corpo Um– Nível de Corpo Dois
• Nível de Corpo Três– Nível de Corpo Quatro
» Nível de Corpo Cinco
27
Slides: http://goo.gl/CgaaWo
Vídeo da palestra: https://youtu.be/-W6335X4jno