Reutilizar los pasos de pepino
Pregunta
Quiero volver a usar algunos pasos de pepino, pero parece que no puede encontrar la manera correcta.
Quiero escribir un paso como:
Given /^I login with (.*) credentials$/ |type|
# do stuff with type being one of "invalid" or "valid"
end
Pero luego tener otro paso como:
Given /^I login successfully$
# call "Given I login with valid credentials"
end
Así que en las pruebas de autenticación de usuario que pueda usar los antiguos, pero la mayoría de los otros lugares, puedo utilizar este último, y en realidad no tiene que codificar repro.
¿Hay una manera de llamar a ese otro paso, o sólo debo poner la lógica en un método de ayuda, y la llamada de dicho procedimiento de cada tarea (básicamente una refactorización extracción método, que, después de leer mi pregunta me hace creer que en realidad la mejor manera de todos modos)?
Solución
Actualizar : El método descrito a continuación se ha desaprobado. El método recomendado para llamar a un paso desde el interior de otro paso ahora se ve así:
Given /^I login successfully$/
step "I login with valid credentials"
end
antiguo, obsoleto método (para referencia):
Puede llamar a pasos de otras medidas como esta:
Given /^I login successfully$/
Given "I login with valid credentials"
Then "I should be logged in"
end
Si todos los escenarios dentro de una característica requieren este (u otras medidas), también puede agregar un fondo a cada uno características, con los pasos comunes, así:
Background:
Given I log in with valid credentials
Scenario: Change my password
Given I am on the account page
Otros consejos
Tenga en cuenta que el método para llamar pasos dentro pasos ha cambiado en las últimas versiones de pepino, que verá si se obtiene un error como "ADVERTENCIA: El uso de 'Dada / cuando / luego' en las definiciones de paso está en desuso, el uso ' paso 'para llamar a otros pasos en su lugar: /path/to/step_definitions/foo_steps.rb: 631: en `bloque en' ". Consulte la pepino wiki para más detalles.
La esencia de este cambio es que ahora debería utilizar los métodos step
o steps
.
When /^I make all my stuff shiny$/
step "I polish my first thing"
end
When /^I make all my stuff shiny$/
steps %Q{
When I polish my first thing
When I shine my second thing
}
end
Llamar a pasos de las definiciones paso es una mala práctica y tiene algunas desventajas :
- Si escenario se producirá un error y hay invocaciones paso anidados, obtendrá sólo la última definición de paso invocado en el seguimiento de la pila. Puede ser difícil de encontrar en qué lugar la última stepdef se llama
- Llamar a stepdef que a veces difíciles de encontrar y leer que el método de rubí
- métodos de Ruby le dan más poder que llamar a pasos de defs paso
Aslak Hellesøy recomienda para extraer las acciones populares a Mundial en lugar de pasos reutilización. Se aísla esas acciones en un solo lugar, hace que este código sea más fácil de encontrar. Puede extraer código para las clases de Ruby habituales o módulos así.
#/support/world_extensions.rb
module KnowsUser
def login
visit('/login')
fill_in('User name', with: user.name)
fill_in('Password', with: user.password)
click_button('Log in')
end
def user
@user ||= User.create!(:name => 'Aslak', :password => 'xyz')
end
end
World(KnowsUser)
#/step_definitions/authentication_steps.rb
When /^I login$/ do
login
end
Given /^a logged in user$/ do
login
end
Aquí está una discusión útil sobre el tema en la lista de correo Pepino - enlace
Mejor envoltura de sus pasos en% {} en lugar de comillas. Entonces, no es necesario para escapar comillas dobles que se necesita para utilizar con frecuencia:.
Given /^I login successfully$
step %{I login with valid credentials}
end
Given /^I login with (.*) credentials$/ |type|
# do stuff with type being one of "invalid" or "valid"
end
palabras clave reutilización en función de archivo que proporcionarán la reutilización del código.
Es altamente recomendable NO llamar defs paso dentro defs paso.
Me gustaría escribir mi archivo característica de esta manera,
Scenario Outline: To check login functionality
Given I login with "<username>" and "<password>"
Then I "<may or may not>" login successfully
Examples:
|username|password|may or may not|
|paul |123$ |may |
|dave |1111 |may not |
En mi definición de paso, (Esto es Java)
@Given(I login with \"([^\"]*)\" and \"([^\"]*)\"$)
public void I_login_with_and(String username, String password){
//login with username and password
}
@Then(I \"([^\"]*)\" login successfully$)
public void I_login_successully_if(String validity){
if(validity.equals("may")){
//assert for valid login
}
else
if(validity.equals("may not")){
//assert for invalid login
}
}
De este modo, hay una gran cantidad de reutilización de código. Su misma dado y entonces maneja ambos escenarios válidos y no válidos. Al mismo tiempo, el archivo de función tiene sentido para los lectores.