Oi,
recentemente estou trabalhando com testes de aceitação do Cucumber. No começo não fiquei tão surpreso, pois assistia a algumas palestras e apresentações, e estava acostumada a trabalhar com Capivara e Bife.
Mas a situação é que meu projeto atual foi iniciado há algum tempo e agora estou me familiarizando com seus testes de aceitação.
A primeira coisa que me preocupou foi o número de consultas em cada etapa. Isso significa que quase todas as etapas recebem um parâmetro com os valores a serem buscados no banco de dados. Por exemplo:
Scenario: A registered user should be able to edit its profile
Given that I'm a registered user with email "my@email.com" and password "123123"
And I'm signed in with email "my@email.com" and password "123123"
When I access the user with email "my@email.com" profile page
And I click on "edit" link
Then I should see the profile edition form
Este é um exemplo simples / hipotético, mas pode ser muito possível para um novato em Pepino. As etapas da web para isso foram mais ou menos assim:
Given(/^that I'm a registered user with email "(.*?)" and password "(.*?)"$/) do |email, pw|
User.create(email: email, password: password)
end
Given(/^I'm signed in with email "(.*?)" and password "(.*?)"$/) do |email, pw|
user = User.where("email = ? AND password = ?", email, pw)
visit sign_in_path
fill_in "user_email", :with => email
fill_in "user_password", :with => pw
click_button "Sign in"
end
When(/^I access the user with email "(.*?)" profile page$/) do |email|
user = User.find_by_email(email)
visit user_path(user)
end
And(/^I click on "(.*?)" link$/) do |link|
click_link link
end
And(/^I should see the profile edition form$/) do
page.should have_selector('#user-profile-edit')
end
O problema e o foco desta dica, são as linhas com o User.where e User.find por email . Essas linhas denotam que toda vez que eu precisar fazer algo com o usuário, sujeito do cenário, vou buscar no banco de dados.
Eu estava lutando com várias etapas usando esse tipo de abordagem, e constantemente me sentindo mal, com problemas de desempenho em meus testes do Cucumber e falta de clareza.
Pesquisando um pouco, encontrei este pequeno artigo https://github.com/cucumber/cucumber/wiki/A-Whole-New-World que mostra como fazer ajudantes usando o objeto Mundo. O seguinte foi extraído do artigo:
Qualquer @instance_variable instanciada em uma Definição de Etapa será atribuída ao Mundo e pode ser acessada em outras Definições de Etapa.
Isso significa que você pode usar @instance_variables em todo o cenário, evitando consultas constantes ao banco de dados, informações que podem estar na memória. Além disso, você pode limpar as etapas do Pepino e escrevê-las de maneira mais clara.
Scenario: A registered user should be able to edit its profile
Given that I'm a registered user
And I'm signed in
When I access my profile page
And I click on "edit" link
Then I should see the profile edition form
Para mim, isso é muito claro e compreensível que o outro. Agora, as etapas se parecem com isto:
Given(/^that I'm a registered user"$/) do
@user = User.create(email: "my@email.com", password: "123123")
end
And(/^I'm signed in"$/) do
visit sign_in_path
fill_in "user_email", :with => @user.email
fill_in "user_password", :with => @user.password
click_button "Sign in"
end
When(/^I access the user with email "(.*?)" profile page$/) do |email|
visit user_path(@user)
end
And(/^I click on "(.*?)" link$/) do |link|
click_link link
end
And(/^I should see the profile edition form$/) do
page.should have_selector('#user-profile-edit')
end
Durante a execução dos cenários, uma instância do mundo é criada e cada @instance_variable é compartilhada entre o plano de fundo e as etapas usadas para esse cenário. Ao final da execução do cenário, essas variáveis são descartadas, um novo cenário é iniciado e assim por diante.
Para mim, esta foi uma grande descoberta, e espero que possa ajudá-lo a escrever melhores cenários do Pepino.
Não se envergonhe de deixar um comentário.