SlideShare une entreprise Scribd logo
1  sur  78
Télécharger pour lire hors ligne
Cucumber
Best practices
Karoline Leite
Karoline Leite
➔ Qualidade e Testes
Desde 2008
➔ Engineering team leader
Creditas
➔ Founder & Organizer
Test Girls
BDDBOAS
PRÁTICAS
Cucumber
CucumberBDD
CucumberBDD
BDD is a collaborative
approach to software
development that bridges
the communication gap
between business and IT.
BDD helps teams communicate
requirements with more
precision, discover defects
early and produce software that
remains maintainable over time.
Boa prática
Automação de
testes é um
sub-produto do
BDD
O melhor drive é
prevenir
desperdício o
quanto antes
BDD não é sobre
teste de software
maintainable softwaresafe discovery
los three
amigos
discovery
workshops
specification
by example
Boa prática
Não se empolgue.
Respeite a pirâmide
de testes
CucumberBDD
Cucumber can be used to
implement automated
tests based on scenarios
described in your Gherkin
feature files.
Imperativo: Muitos detalhes, passo a passo
Declarativo: Conciso, direto ao ponto, poucos passos
Nível de abstração
Nível de abstração
Imperativo
Dado que eu abra o browser
E navegue para o site https://store.ministryoftesting.com
E clique no campo ‘Search’
Quando eu digitar ‘MUG’
E clicar em buscar
Então verei a página de busca mostrando os detalhes das canecas
Nível de abstração
Declarativo
Dado que eu esteja no e-commerce do Ministry of Testing
Quando eu fizer uma busca por caneca
Então verei a página de busca mostrando os detalhes das canecas
Nível de abstração
Imperativo vs Declarativo
Nível de abstração
Imperativo vs Declarativo
Boa prática
Menos é mais.
Menos passos,
menos
manutenção.
Detalhes da
implementação,
como IDs não
fazem sentido.
Foco deve ser no
comportamento.
Não tem certo ou
errado.
Experimente e
aprenda em
conjunto com seu
time.
Data Tables
Dado o valor dos itens que comprei
| 3 |
| 6 |
| 233 |
Quando a conta for somada
Então o total cobrado deve ser 238
Data Tables
Dado que eu esteja no e-commerce do Ministry of Testing
Quando eu fizer uma busca por caneca
Então verei a página de busca mostrando os detalhes das
canecas
| posicao | nome | preco |
| 1 | Bug Mug | £12.49 |
| 2 | Mug - White | £12.49 |
Então("verei a página de busca mostrando os detalhes das canecas") do |table|
data = table.raw
end
Data Tables
data => [["posicao", "nome", "preco"], ["1", "Bug Mug", "£12.49"],
["2", "Mug - White", "£12.49"]]
Esquema do Cenário
O cenário é o mesmo, mas os dados mudam!
São necessários inputs diferentes.
Esquema do Cenário
Cenário 1 - Somar
Dado que eu acesse a calculadora
Quando eu adicionar o valor 1
E apertar o botão de somar
E eu adicionar o valor 1
Então será exibido 2 como resultado
Esquema do Cenário
Cenário 2 - Subtrair
Dado que eu acesse a calculadora
Quando eu adicionar o valor 2
E apertar o botão de subtrair
E eu adicionar o valor 1
Então será exibido 1 como resultado
Esquema do Cenário
Cenário 3 - Multiplicar
Dado que eu acesse a calculadora
Quando eu adicionar o valor 4
E apertar o botão de multiplicar
E eu adicionar o valor 3
Então será exibido 12 como resultado
Esquema do Cenário
Cenário 4 - Dividir
Dado que eu acesse a calculadora
Quando eu adicionar o valor 4
E apertar o botão de dividir
E eu adicionar o valor 2
Então será exibido 2 como resultado
Esquema do Cenário
Dado que eu acesse a calculadora
Quando eu adicionar o valor <first_value>
E apertar o botão de <operation>
E eu adicionar o valor <second_value>
Então será exibido <result> como resultado
Exemplos:
| first_value | second_value| operation | result |
| 1 | 1 | sum | 2 |
| 2 | 1 | subtraction | 1 |
| 4 | 3 | multiplication| 12 |
| 4 | 2 | divide | 2 |
Boa prática
Menos é mais.
Você realmente
precisa testar
com tantos dados
assim?
Quaisquer tipo de
tabela é difícil de
ler. Use com
parcimônia.
Não tenha receio
de reescrever se
perceber que a
tabela está ficando
grande.
Tags
Tags are a great way to organise your features and
scenarios.
Referenciar para execução de um grupo de cenários
“Escopar” os hooks a grupos de cenarios
Tags
Referenciar para execução de um grupo de cenários
@calculator @fast @ready
Cenário: Fazer soma na calculadora web
Dado que eu acesse a calculadora
Quando eu adicionar o valor 1
E apertar o botão de somar
E eu adicionar o valor 1
Então será exibido 2 como resultado
Referenciar para execução de um grupo de cenários
$ cucumber features/ --tags @calculator
Tags
Tags
Referenciar para execução de um grupo de cenários
@calculator
@wip and not @slow
@smoke and @fast
@calculator or @spreadsheet
Tags são herdadas pelos elementos filhos.
Tags que são colocadas na Funcionalidade serão
herdadas pelos Cenários, Esquemas de Cenário e
Exemplos.
Tags que são colocadas no Esquema do Cenário serão
herdadas pelos Exemplos.
Tags
Herança de tags
@calculadora
Funcionalidade: Calculadora online
@website_search @gui
Cenário: Buscar caneca no site
Dado que eu esteja no e-commerce do Ministry of Testing
Quando eu fizer uma busca por caneca
Então verei a página de busca mostrando os detalhes das canecas
Tags
Herança de tags
Tags
“Escopar” os hooks a grupos de cenarios?
Boa prática
Crie um sistema
de tags relevante
e use bastante.
Crie um glossário
de tags e
explique-o no
README.md do
projeto.
Hooks
Hooks are blocks of code that can run at various points
in the Cucumber execution cycle.
Before
After
Around
After|BeforeStep
Hooks
Before do
# Do something before each scenario
end
Hooks
After do |scenario|
if scenario.failed?
# tire um printscreen
end
end
Hooks
Around('@fast') do |scenario, block|
Timeout.timeout(0.5) do
block.call
end
end
Boa prática
Separe arquivos
diferentes por
tipo de hook.
after_hooks.rb
before_hooks.rb
Não dê muita
responsabilidade
para os hooks. Eles
são invisíveis na
execução.
Nested Steps
Invocar um ou mais steps dentro de outro é um recurso
interessante para reaproveitar código.
Nested Steps
Dado("que a usuária {string} exista") do |user|
###
end
Dado("que eu faça login como {string}") do |user|
###
end
Nested Steps
Dado("que {string} esteja logada") do |user|
end
steps %{
que a usuária #{user} exista
que eu faça login como #{user}
}
Boa prática
Use com cuidado.
O acoplamento
fica muito forte
entre os steps.
Nested steps é
um ótimo recurso
para um baixo
nível de
reaproveitamento
e legibilidade.
Reports
$ cucumber --format html --out reports.html
Reports
Reports
Reports
After do |scenario|
if scenario.failed?
print_name = "#{scenario.name}.png"
Capybara.page.save_screenshot("reports/#{print_name}")
embed("reports/#{print_name}", "image/png","#{scenario.name}")
end
end
Boa prática
Os reports são
uma ótima forma
de compartilhar
os resultados dos
testes. Faça deles
seus aliados.
Retry
Se você tem um cenário flaky, o ideal é investigar a causa
e corrigir o mais rápido possível.
Mas quando não for possível, é necessário lidar com ele
sem impactar sua suíte toda.
Retry
$ cucumber feature --retry 2
4 scenarios (2 failed, 1 flaky, 1 passed)
Boa prática
Quanto mais
tentativas você
colocar, mais o
resultado do teste
vai demorar em
caso de falhas.
Configure seu CI
para avisar
quando flaky
cenários
ocorrerem.
World object
In Ruby, Cucumber runs scenarios in a World.
You can add any behaviour to the World, like helper
methods, or logging, etc.
World object
module CPFHelper
def cpf_generator
# implemente aqui
end
end
World(CPFHelper)
Boa prática
Organize os
helpers em
arquivos e
módulos com
responsabilidades
claras.
Usar helpers ajuda
a manter o
desacoplado,
organizado e
reutilizável.
Page Objects
class Home < SitePrism::Page
set_url '/index.htm'
set_url_matcher(/google.com/?/)
element :search_field, 'input[name="q"]'
element :search_button, 'button[name="btnK"]'
end
Page Objects
The public methods represent the services that the page offers
Try not to expose the internals of the page
Generally don't make assertions
Methods return other PageObjects
Need not represent an entire page
Different results for the same action are modelled as different methods
Boa prática
Não faça
assertions nas
nas suas
PageObjects. Use
expectations a
seu favor.
Não retorne
PageObjects nos
métodos. O
Cucumber não vai
bem com esse
acoplamento.
Page Objects
class Home < SitePrism::Page
element :search_field, 'input[name="q"]'
def result_verify
# implementação, retorna true ou false
end
end
expect(@home.result_verify).to be true
Page Objects
class Home < SitePrism::Page
element :search_field, 'input[name="q"]'
def result_verify
# implementação, retorna true ou false
end
end
Page Objects
expect(@home.element.text).to eq(expected_text)
Page Objects
class Home < SitePrism::Page
def search_item(name)
search_field.set(name)
search_button.click
return SearchResultPage.new
end
end
Page Objects
Dado("que eu faça uma busca por {string}") do |name|
page = Home.new
@next_page = page.search_item(name)
end
Page Objects
API Testing
Sua API também tem comportamento
É possível e faz sentido
Boa prática
É muito mais
tentador, mas
foque no
comportamento
da sua API, não na
implementação.
Organize os
payloads em
arquivos
separados dos
steps.
Crie seu API
objects para lidar
com cada
endpoint.
API Testing
Dado que eu me autentique na API do MoT
Quando eu fizer um post no endpoint “event/create”
Então o evento será criado
E o status retornado será 200
API Testing
Dado que eu me autentique na API do MoT
Quando eu enviar a criação de um novo evento
Então o evento será criado com sucesso
API Testing
Quando(“eu enviar a criação de um novo evento”) do
body = {
"id": "4",
"createdAt": "2019-03-18T08:14:59.675Z",
"name": "Handcrafted",
"local": "local 4"
}
end
API Testing
Quando(“eu enviar a criação de um novo evento”) do
…
url = ‘https://mot-sp/events/create’
end
API Testing
Quando(“eu enviar a criação de um novo evento”) do
…
...
response = HTTParty.post(url, :body => body)
end
API Testing
class MinistryOfTestingEventsAPI
include HTTParty
base_uri “https://mot-sp/events”
def create(body)
self.class.post(‘/create’, :body => body)
end
end
API Testing
→ create_body.json
{
"id": "4",
"createdAt": "2019-03-18T08:14:59.675Z",
"name": "Handcrafted",
"local": "local 4"
}
API Testing
Quando(“eu enviar a criação de um novo evento”) do
body = File.read(‘create_body.json’)
api = MinistryOfTestingEventsAPI.new
response = api.create(body)
end
Dicas de ouro
Experimente
novas ideias e
abordagens.
Refatore seu
código sempre.
Comece simples
e pratique.
Compartilhe seus
aprendizados e
dúvidas com seu
time e com sua
comunidade.
THANKS!
@karolxavierleite
Twitter
@karolineleite
Blog
http://blog.howtotest.com.br/

Contenu connexe

Tendances

Microsoft solution framework_(msf)_expo
Microsoft solution framework_(msf)_expoMicrosoft solution framework_(msf)_expo
Microsoft solution framework_(msf)_expo
urumisama
 
Arquitectura dirigida a eventos
Arquitectura dirigida a eventosArquitectura dirigida a eventos
Arquitectura dirigida a eventos
rehoscript
 
Cascada con subproyectos
Cascada con subproyectosCascada con subproyectos
Cascada con subproyectos
Diego Porras
 
Metodología xp
Metodología xpMetodología xp
Metodología xp
Piskamen
 

Tendances (20)

Agile - What? Why? How?
Agile - What? Why? How?Agile - What? Why? How?
Agile - What? Why? How?
 
Rational unified process (rup)
Rational unified process (rup)Rational unified process (rup)
Rational unified process (rup)
 
Modelo V - Desenvolvimento de Software
Modelo V - Desenvolvimento de SoftwareModelo V - Desenvolvimento de Software
Modelo V - Desenvolvimento de Software
 
Microsoft solution framework_(msf)_expo
Microsoft solution framework_(msf)_expoMicrosoft solution framework_(msf)_expo
Microsoft solution framework_(msf)_expo
 
RUP - Rational Unified Process
RUP - Rational Unified ProcessRUP - Rational Unified Process
RUP - Rational Unified Process
 
Conceptos basicos calidad software
Conceptos basicos calidad softwareConceptos basicos calidad software
Conceptos basicos calidad software
 
Programación Extrema (XP)
Programación Extrema (XP)Programación Extrema (XP)
Programación Extrema (XP)
 
Principios diseño del software
Principios diseño del software Principios diseño del software
Principios diseño del software
 
An Overview of RUP methodology
An Overview of RUP methodologyAn Overview of RUP methodology
An Overview of RUP methodology
 
Sikuli for Mobile Testing
Sikuli for Mobile TestingSikuli for Mobile Testing
Sikuli for Mobile Testing
 
Modelos de Ciclos de Vida
Modelos de Ciclos de VidaModelos de Ciclos de Vida
Modelos de Ciclos de Vida
 
Design de Interação - Capítulo 8 - Design, Prototipação e Construção -
Design de Interação - Capítulo 8 - Design, Prototipação e Construção - Design de Interação - Capítulo 8 - Design, Prototipação e Construção -
Design de Interação - Capítulo 8 - Design, Prototipação e Construção -
 
Agile Methodologies And Extreme Programming
Agile Methodologies And Extreme ProgrammingAgile Methodologies And Extreme Programming
Agile Methodologies And Extreme Programming
 
Arquitectura dirigida a eventos
Arquitectura dirigida a eventosArquitectura dirigida a eventos
Arquitectura dirigida a eventos
 
Scrum
ScrumScrum
Scrum
 
Cascada con subproyectos
Cascada con subproyectosCascada con subproyectos
Cascada con subproyectos
 
Agile Practices - eXtreme Programming
Agile Practices - eXtreme ProgrammingAgile Practices - eXtreme Programming
Agile Practices - eXtreme Programming
 
Ch04
Ch04Ch04
Ch04
 
Programación Extrema - XP
Programación Extrema - XPProgramación Extrema - XP
Programación Extrema - XP
 
Metodología xp
Metodología xpMetodología xp
Metodología xp
 

Similaire à Cucumber Best Practices

Testes automatizados
Testes automatizadosTestes automatizados
Testes automatizados
Rodrigo Maia
 
Grails parte 1 - introdução
Grails   parte 1 - introduçãoGrails   parte 1 - introdução
Grails parte 1 - introdução
Josino Rodrigues
 
Automação no ambientAutomação no ambiente de desenvolvimento com Maven e ANT
Automação no ambientAutomação no ambiente de desenvolvimento com Maven e ANTAutomação no ambientAutomação no ambiente de desenvolvimento com Maven e ANT
Automação no ambientAutomação no ambiente de desenvolvimento com Maven e ANT
elliando dias
 
Desenvolvimento em .Net - Estruturas Basicas
Desenvolvimento em .Net - Estruturas BasicasDesenvolvimento em .Net - Estruturas Basicas
Desenvolvimento em .Net - Estruturas Basicas
Vitor Silva
 

Similaire à Cucumber Best Practices (20)

Cucumber e melhores práticas
Cucumber e melhores práticasCucumber e melhores práticas
Cucumber e melhores práticas
 
Cucumber-QA_Night
Cucumber-QA_NightCucumber-QA_Night
Cucumber-QA_Night
 
Cucumber
CucumberCucumber
Cucumber
 
Testes automatizados
Testes automatizadosTestes automatizados
Testes automatizados
 
Boas práticas de Automação de Testes
Boas práticas de Automação de TestesBoas práticas de Automação de Testes
Boas práticas de Automação de Testes
 
Demoiselle Behave - Visão Geral
Demoiselle Behave - Visão GeralDemoiselle Behave - Visão Geral
Demoiselle Behave - Visão Geral
 
Google apps script - Parte - 1
Google apps script - Parte - 1Google apps script - Parte - 1
Google apps script - Parte - 1
 
Hello vue
Hello vueHello vue
Hello vue
 
Grails parte 1 - introdução
Grails   parte 1 - introduçãoGrails   parte 1 - introdução
Grails parte 1 - introdução
 
Angular 2 em 60 minutos
Angular 2 em 60 minutosAngular 2 em 60 minutos
Angular 2 em 60 minutos
 
Gsp007
Gsp007Gsp007
Gsp007
 
BDD: Cucumber + Selenium + Java
BDD: Cucumber + Selenium + JavaBDD: Cucumber + Selenium + Java
BDD: Cucumber + Selenium + Java
 
Automação no ambientAutomação no ambiente de desenvolvimento com Maven e ANT
Automação no ambientAutomação no ambiente de desenvolvimento com Maven e ANTAutomação no ambientAutomação no ambiente de desenvolvimento com Maven e ANT
Automação no ambientAutomação no ambiente de desenvolvimento com Maven e ANT
 
Evento Front End SP - Organizando o Javascript
 Evento Front End SP - Organizando o Javascript Evento Front End SP - Organizando o Javascript
Evento Front End SP - Organizando o Javascript
 
Ganhando tempo com casos de testes
Ganhando tempo com casos de testesGanhando tempo com casos de testes
Ganhando tempo com casos de testes
 
BDD com Cucumber
BDD com CucumberBDD com Cucumber
BDD com Cucumber
 
Desenvolvimento em .Net - Estruturas Basicas
Desenvolvimento em .Net - Estruturas BasicasDesenvolvimento em .Net - Estruturas Basicas
Desenvolvimento em .Net - Estruturas Basicas
 
Devfest Cerrado: Angular 2
Devfest Cerrado: Angular 2 Devfest Cerrado: Angular 2
Devfest Cerrado: Angular 2
 
Automação de Testes com SoapUI v1
Automação de Testes com SoapUI v1Automação de Testes com SoapUI v1
Automação de Testes com SoapUI v1
 
Framework de testes cecom
Framework de testes cecomFramework de testes cecom
Framework de testes cecom
 

Cucumber Best Practices

  • 2. Karoline Leite ➔ Qualidade e Testes Desde 2008 ➔ Engineering team leader Creditas ➔ Founder & Organizer Test Girls
  • 6. BDD is a collaborative approach to software development that bridges the communication gap between business and IT.
  • 7. BDD helps teams communicate requirements with more precision, discover defects early and produce software that remains maintainable over time.
  • 8. Boa prática Automação de testes é um sub-produto do BDD O melhor drive é prevenir desperdício o quanto antes BDD não é sobre teste de software
  • 9.
  • 10. maintainable softwaresafe discovery los three amigos discovery workshops specification by example
  • 11. Boa prática Não se empolgue. Respeite a pirâmide de testes
  • 13. Cucumber can be used to implement automated tests based on scenarios described in your Gherkin feature files.
  • 14. Imperativo: Muitos detalhes, passo a passo Declarativo: Conciso, direto ao ponto, poucos passos Nível de abstração
  • 15. Nível de abstração Imperativo Dado que eu abra o browser E navegue para o site https://store.ministryoftesting.com E clique no campo ‘Search’ Quando eu digitar ‘MUG’ E clicar em buscar Então verei a página de busca mostrando os detalhes das canecas
  • 16. Nível de abstração Declarativo Dado que eu esteja no e-commerce do Ministry of Testing Quando eu fizer uma busca por caneca Então verei a página de busca mostrando os detalhes das canecas
  • 19. Boa prática Menos é mais. Menos passos, menos manutenção. Detalhes da implementação, como IDs não fazem sentido. Foco deve ser no comportamento. Não tem certo ou errado. Experimente e aprenda em conjunto com seu time.
  • 20. Data Tables Dado o valor dos itens que comprei | 3 | | 6 | | 233 | Quando a conta for somada Então o total cobrado deve ser 238
  • 21. Data Tables Dado que eu esteja no e-commerce do Ministry of Testing Quando eu fizer uma busca por caneca Então verei a página de busca mostrando os detalhes das canecas | posicao | nome | preco | | 1 | Bug Mug | £12.49 | | 2 | Mug - White | £12.49 |
  • 22. Então("verei a página de busca mostrando os detalhes das canecas") do |table| data = table.raw end Data Tables data => [["posicao", "nome", "preco"], ["1", "Bug Mug", "£12.49"], ["2", "Mug - White", "£12.49"]]
  • 23. Esquema do Cenário O cenário é o mesmo, mas os dados mudam! São necessários inputs diferentes.
  • 24. Esquema do Cenário Cenário 1 - Somar Dado que eu acesse a calculadora Quando eu adicionar o valor 1 E apertar o botão de somar E eu adicionar o valor 1 Então será exibido 2 como resultado
  • 25. Esquema do Cenário Cenário 2 - Subtrair Dado que eu acesse a calculadora Quando eu adicionar o valor 2 E apertar o botão de subtrair E eu adicionar o valor 1 Então será exibido 1 como resultado
  • 26. Esquema do Cenário Cenário 3 - Multiplicar Dado que eu acesse a calculadora Quando eu adicionar o valor 4 E apertar o botão de multiplicar E eu adicionar o valor 3 Então será exibido 12 como resultado
  • 27. Esquema do Cenário Cenário 4 - Dividir Dado que eu acesse a calculadora Quando eu adicionar o valor 4 E apertar o botão de dividir E eu adicionar o valor 2 Então será exibido 2 como resultado
  • 28. Esquema do Cenário Dado que eu acesse a calculadora Quando eu adicionar o valor <first_value> E apertar o botão de <operation> E eu adicionar o valor <second_value> Então será exibido <result> como resultado Exemplos: | first_value | second_value| operation | result | | 1 | 1 | sum | 2 | | 2 | 1 | subtraction | 1 | | 4 | 3 | multiplication| 12 | | 4 | 2 | divide | 2 |
  • 29. Boa prática Menos é mais. Você realmente precisa testar com tantos dados assim? Quaisquer tipo de tabela é difícil de ler. Use com parcimônia. Não tenha receio de reescrever se perceber que a tabela está ficando grande.
  • 30. Tags Tags are a great way to organise your features and scenarios. Referenciar para execução de um grupo de cenários “Escopar” os hooks a grupos de cenarios
  • 31. Tags Referenciar para execução de um grupo de cenários @calculator @fast @ready Cenário: Fazer soma na calculadora web Dado que eu acesse a calculadora Quando eu adicionar o valor 1 E apertar o botão de somar E eu adicionar o valor 1 Então será exibido 2 como resultado
  • 32. Referenciar para execução de um grupo de cenários $ cucumber features/ --tags @calculator Tags
  • 33. Tags Referenciar para execução de um grupo de cenários @calculator @wip and not @slow @smoke and @fast @calculator or @spreadsheet
  • 34. Tags são herdadas pelos elementos filhos. Tags que são colocadas na Funcionalidade serão herdadas pelos Cenários, Esquemas de Cenário e Exemplos. Tags que são colocadas no Esquema do Cenário serão herdadas pelos Exemplos. Tags Herança de tags
  • 35. @calculadora Funcionalidade: Calculadora online @website_search @gui Cenário: Buscar caneca no site Dado que eu esteja no e-commerce do Ministry of Testing Quando eu fizer uma busca por caneca Então verei a página de busca mostrando os detalhes das canecas Tags Herança de tags
  • 36. Tags “Escopar” os hooks a grupos de cenarios?
  • 37. Boa prática Crie um sistema de tags relevante e use bastante. Crie um glossário de tags e explique-o no README.md do projeto.
  • 38. Hooks Hooks are blocks of code that can run at various points in the Cucumber execution cycle. Before After Around After|BeforeStep
  • 39. Hooks Before do # Do something before each scenario end
  • 40. Hooks After do |scenario| if scenario.failed? # tire um printscreen end end
  • 41. Hooks Around('@fast') do |scenario, block| Timeout.timeout(0.5) do block.call end end
  • 42. Boa prática Separe arquivos diferentes por tipo de hook. after_hooks.rb before_hooks.rb Não dê muita responsabilidade para os hooks. Eles são invisíveis na execução.
  • 43. Nested Steps Invocar um ou mais steps dentro de outro é um recurso interessante para reaproveitar código.
  • 44. Nested Steps Dado("que a usuária {string} exista") do |user| ### end Dado("que eu faça login como {string}") do |user| ### end
  • 45. Nested Steps Dado("que {string} esteja logada") do |user| end steps %{ que a usuária #{user} exista que eu faça login como #{user} }
  • 46. Boa prática Use com cuidado. O acoplamento fica muito forte entre os steps. Nested steps é um ótimo recurso para um baixo nível de reaproveitamento e legibilidade.
  • 47. Reports $ cucumber --format html --out reports.html
  • 50. Reports After do |scenario| if scenario.failed? print_name = "#{scenario.name}.png" Capybara.page.save_screenshot("reports/#{print_name}") embed("reports/#{print_name}", "image/png","#{scenario.name}") end end
  • 51. Boa prática Os reports são uma ótima forma de compartilhar os resultados dos testes. Faça deles seus aliados.
  • 52. Retry Se você tem um cenário flaky, o ideal é investigar a causa e corrigir o mais rápido possível. Mas quando não for possível, é necessário lidar com ele sem impactar sua suíte toda.
  • 53. Retry $ cucumber feature --retry 2 4 scenarios (2 failed, 1 flaky, 1 passed)
  • 54. Boa prática Quanto mais tentativas você colocar, mais o resultado do teste vai demorar em caso de falhas. Configure seu CI para avisar quando flaky cenários ocorrerem.
  • 55. World object In Ruby, Cucumber runs scenarios in a World. You can add any behaviour to the World, like helper methods, or logging, etc.
  • 56. World object module CPFHelper def cpf_generator # implemente aqui end end World(CPFHelper)
  • 57. Boa prática Organize os helpers em arquivos e módulos com responsabilidades claras. Usar helpers ajuda a manter o desacoplado, organizado e reutilizável.
  • 58. Page Objects class Home < SitePrism::Page set_url '/index.htm' set_url_matcher(/google.com/?/) element :search_field, 'input[name="q"]' element :search_button, 'button[name="btnK"]' end
  • 59. Page Objects The public methods represent the services that the page offers Try not to expose the internals of the page Generally don't make assertions Methods return other PageObjects Need not represent an entire page Different results for the same action are modelled as different methods
  • 60. Boa prática Não faça assertions nas nas suas PageObjects. Use expectations a seu favor. Não retorne PageObjects nos métodos. O Cucumber não vai bem com esse acoplamento.
  • 61. Page Objects class Home < SitePrism::Page element :search_field, 'input[name="q"]' def result_verify # implementação, retorna true ou false end end
  • 63. class Home < SitePrism::Page element :search_field, 'input[name="q"]' def result_verify # implementação, retorna true ou false end end Page Objects
  • 65. class Home < SitePrism::Page def search_item(name) search_field.set(name) search_button.click return SearchResultPage.new end end Page Objects
  • 66. Dado("que eu faça uma busca por {string}") do |name| page = Home.new @next_page = page.search_item(name) end Page Objects
  • 67. API Testing Sua API também tem comportamento É possível e faz sentido
  • 68. Boa prática É muito mais tentador, mas foque no comportamento da sua API, não na implementação. Organize os payloads em arquivos separados dos steps. Crie seu API objects para lidar com cada endpoint.
  • 69. API Testing Dado que eu me autentique na API do MoT Quando eu fizer um post no endpoint “event/create” Então o evento será criado E o status retornado será 200
  • 70. API Testing Dado que eu me autentique na API do MoT Quando eu enviar a criação de um novo evento Então o evento será criado com sucesso
  • 71. API Testing Quando(“eu enviar a criação de um novo evento”) do body = { "id": "4", "createdAt": "2019-03-18T08:14:59.675Z", "name": "Handcrafted", "local": "local 4" } end
  • 72. API Testing Quando(“eu enviar a criação de um novo evento”) do … url = ‘https://mot-sp/events/create’ end
  • 73. API Testing Quando(“eu enviar a criação de um novo evento”) do … ... response = HTTParty.post(url, :body => body) end
  • 74. API Testing class MinistryOfTestingEventsAPI include HTTParty base_uri “https://mot-sp/events” def create(body) self.class.post(‘/create’, :body => body) end end
  • 75. API Testing → create_body.json { "id": "4", "createdAt": "2019-03-18T08:14:59.675Z", "name": "Handcrafted", "local": "local 4" }
  • 76. API Testing Quando(“eu enviar a criação de um novo evento”) do body = File.read(‘create_body.json’) api = MinistryOfTestingEventsAPI.new response = api.create(body) end
  • 77. Dicas de ouro Experimente novas ideias e abordagens. Refatore seu código sempre. Comece simples e pratique. Compartilhe seus aprendizados e dúvidas com seu time e com sua comunidade.