selenium - patron - ¿La vinculación del Modelo de Objetos de Página es compatible con el pepinillo de pepino?
pagefactory initelements selenium (3)
Con el Modelo de Objetos de Página de Test Automation, vinculamos páginas juntas de esta manera:
WebDriver driver = new WebDriver()
HomePage homePage = new HomePage(driver);
LoginPage loginPage = homePage.GoToLoginPage();
WelcomePage welcomePage = loginPage.Login();
etc
etc
El gran beneficio de esto es que si los desarrolladores cambian la página de inicio, por lo que ya no tiene enlaces a la página de inicio de sesión, puedo actualizar mi clase de página de inicio y ver todas las pruebas que necesito actualizar (con errores) incluso antes de ejecutar una prueba.
Sin embargo, con Gherkin, cada fila anterior formaría un ''Paso'' separado y, por lo tanto, un método separado. Por lo tanto, ¿cómo se puede hacer este enlace?
¿Es la única forma de colocar instancias de las clases de objeto de página (por ejemplo, homePage, loginPage, etc.) en un almacén persistente de declaración de cruz pepinillo (por ejemplo, como un POCO de especificación de flujo o ''Mundo'')?
Cuando se trata de la mayoría de los sitios web (donde se pueden usar las direcciones URL), en mi opinión, es una buena práctica simplemente usar la URL en lugar de una acción para llegar a esa misma URL.
Por ejemplo:
# Suggested by OP:
driver = Selenium::Webdriver.for :chrome, prefs: prefs
homepage = Homepage.new(driver)
login = homepage.go_to_login
welcome = login.log_in_as(''dave4429'')
# My Suggestion:
homepage = Url.new(''/'')
login = Url.new(''/login'')
welcome = Url.new(''/welcome'')
Esto significa que comienza desde una url en lugar de tener que comenzar en la página principal para cada prueba. Todavía tendría los métodos que sugirió, pero se usarían en otras áreas, para asegurarse de que el usuario pueda acceder a la página a través de otros medios que no sean la url.
Sin embargo, esta no es una solución de ventanilla única. Con las aplicaciones móviles y de escritorio, su única opción puede ser pasar por la pantalla de inicio, en cuyo caso, el método que sugirió es definitivamente el indicado.
"Los objetos de la página en sí mismos nunca deben hacer verificaciones o afirmaciones. Esto es parte de su prueba y siempre debe estar dentro del código de la prueba, nunca en un objeto de página". - Selenium HQ
El ejemplo que di fue muy básico, y lo más probable es que lo incluya en módulos y clases, para permitir la codificación de esta manera:
google = Project::Pages::Google.new
google.search_for(''Hello, World!'')
expect(google.found_result?).to_equal(true)
Editar
Además de esto, parece que tienes un concepto erróneo sobre cómo funciona Pepino con Gherkin.
Puede tener varias líneas de código por paso, ya que el paso en sí es una descripción de las acciones dentro del paso.
Por ejemplo:
Given I am logged in as "dave4429"
When I have submitted the "Contact Us" form with the following data:
| [email protected] | David McBlaine | I want to find out more about your Data Protection services, can I talk to a staff member or get a PDF? |
Then an email should be sent to "[email protected]" with the details specified
La definición del "Cuándo" puede verse así:
When(/^I have submitted the "Contact Us" form with the following data:$/) do |table|
rows = table.raw
row = rows[0]
contact_us.fill_form({email: row[0], username: row[1], message: row[2]})
contact_us.submit_message
expect(browser.title).to_equal("Message Sent!")
end
Todo depende de cuánto desgloses los pasos dentro de la definición.
Editar # 2
También me queda claro que quieres hacer un encadenamiento de métodos, algo en el camino de contact_us.fill_form({email: row[0], username: row[1], message: row[2]}).submit_message
, que de nuevo , no está descartado al usar las técnicas que estoy sugiriendo, pero la pregunta de si este encadenamiento debe ser para cada página individual, o si todo debe ser incluido en una clase o módulo, solo puede ser respondido por su necesariamente.
Es solo mi opinión que esto pondría demasiado en una sola clase, y que romper esa clase permitirá que se les dé más control a los evaluadores, y se escribirá menos código redundante.
De acuerdo, habiendo preguntado a numerosos expertos en automatización de desarrollo y prueba, parece que la solución es continuar enlazando [eg WelcomePage welcomePage = loginPage.loginWithValidUser(validUser)]
es el camino a seguir.
Para persistir la instancia de los objetos de la página en todos los pasos (por ejemplo, welcomePage en el ejemplo anterior) puede usar la herramienta de inyección de dependencias (creando una funcionalidad similar a las extensiones mundiales en la implementación del pepino de Ruby).
Aquí hay más información: https://cukes.info/docs/reference/java-di
Sin embargo, la mayoría de los proyectos se beneficiarán de un módulo de Inyección de Dependencia para organizar mejor su código y compartir el estado entre las Definiciones de Paso.
Más información de SpecFlow (la implementación oficial del pepino de .net):
http://specflow.org/getting-started/beyond-the-basics/
Y finalmente, he creado un blog completo alrededor de esta área que podría ayudar a la gente, ya que la interacción de objeto pepinillo / página es un tema de gran interés para mí:
http://www.seligmanventures.com/dev-blog/test-automation-page-object-model-with-gherkin
Después de mucha discusión sobre este tema, una alternativa igualmente plausible es no devolver instancias de páginas nuevas cuando se usa el patrón de objeto de página con pepinillo. Perderá el beneficio de vincular lo que normalmente obtiene con POM, pero el código posiblemente leerá mejor y será menos complejo. Publicando esta respuesta alternativa, para que como comunidad de prueba podamos votar qué método es la preferencia de las personas.