ruby selenium webdriver selenium-webdriver pageobjects

ruby - modelo de objeto de página: ¿por qué no incluir aserciones en los métodos de página?



selenium webdriver (5)

@Matt reutilizando los modelos de dominio en el objeto de página puede ahorrarle tiempo, pero no es un Olor de prueba, la lógica de prueba debe estar bien separada del modelo de dominio (dependiendo de lo que intente lograr).

Volver a la pregunta original, si realmente debe hacer afirmaciones en el objeto de página, ¿por qué no utilizar el componente cargable de selenio <> donde puede usar el método isLoaded () o incluir su aserción personalizada en la clase <> de componente cargable? Esto mantendrá su objeto de página libre de aserciones. Pero puede hacer aserciones en el componente cargable. Ver el enlace a continuación ...

http://code.google.com/p/selenium/wiki/LoadableComponent

_El soñador

Póster por primera vez. He estado trabajando en la automatización de UI durante muchos años, pero recientemente me presentaron / se me instruyó para trabajar con el Modelo de objetos de página. La mayor parte es de sentido común e incluye técnicas que ya he usado, pero hay un punto en particular que no he podido justificar en mi mente, a pesar de buscar exhaustivamente una explicación bien razonada. Espero que alguien aquí me ilumine, ya que esta pregunta ha causado cierta consternación al intentar integrar el POM con mis mejores prácticas.

Desde http://code.google.com/p/selenium/wiki/PageObjects :

El código presentado arriba muestra un punto importante: las pruebas, no los PageObjects, deberían ser responsables de hacer afirmaciones sobre el estado de una página ... Por supuesto, como sucede con todas las directrices, existen excepciones ...

De http://seleniumhq.org/docs/06_test_design_considerations.html#chapter06-reference :

Hay mucha flexibilidad en cómo se pueden diseñar los objetos de la página, pero hay algunas reglas básicas para obtener la mantenibilidad deseada de su código de prueba. Los objetos de la página en sí mismos nunca deberían 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. El objeto de página contendrá la representación de la página y los servicios que la página proporciona a través de los métodos, pero ningún código relacionado con lo que se está probando debe estar dentro del objeto de la página.

Existe una única verificación que puede y debe estar dentro del objeto de la página y que consiste en verificar que la página, y posiblemente los elementos críticos de la página, se cargaron correctamente. Esta verificación debe hacerse al crear una instancia del objeto de la página.

Ambas "pautas" permiten posibles excepciones, pero no podría estar más en desacuerdo con la premisa básica. Estoy acostumbrado a hacer una cantidad considerable de verificación dentro de los "métodos de página", y creo que la presencia de verificación es una técnica poderosa para encontrar problemas en una variedad de contextos (es decir, la verificación ocurre cada vez que se llama el método) en lugar de que solo ocurre en el contexto limitado de pruebas particulares.

Por ejemplo, imaginemos que cuando inicia sesión en su AUT, aparece un texto que dice "inició sesión como USUARIO". Es apropiado que una única prueba lo valide específicamente, pero ¿por qué no desea verificarlo cada vez que se invoca el inicio de sesión? Este artefacto no está directamente relacionado con si la página "cargó correctamente" o no, y no está relacionado con "lo que se está probando" en general, por lo que de acuerdo con las pautas de POM anteriores, claramente NO DEBERÍA estar en un método de página. .. pero me parece que claramente DEBE estar allí, para maximizar el poder de la automatización al verificar artefactos importantes tan a menudo como sea posible, con la menor previsión posible. Poner el código de verificación en los métodos de página multiplica el poder de la automatización al permitirle obtener mucha verificación "gratis", sin tener que preocuparse por ello en sus pruebas, y dicha verificación frecuente en diferentes contextos a menudo encuentra problemas que NO encontraría si la verificación se limitó a, por ejemplo, una prueba única para ese artefacto.

En otras palabras, tiendo a distinguir entre la verificación específica de la prueba y la verificación "general", y creo que es perfectamente apropiado / deseable que esta última se incluya -extensivamente- en los métodos de la página. Esto promueve pruebas más delgadas y objetos de página más gruesos, lo que generalmente aumenta la capacidad de mantenimiento de la prueba al reutilizar más código, a pesar del argumento opuesto en estas pautas. ¿Me estoy perdiendo el punto? ¿Cuál es la lógica real para NO querer la verificación en los métodos de página? ¿Es la situación que describí en realidad una de las ''excepciones'' descritas en estas pautas, y por lo tanto, en realidad NO es inconsistente con el POM? Gracias de antemano por sus pensamientos. -jn-


Como guía, las afirmaciones deben hacerse en pruebas y no en objetos de página. Por supuesto, hay momentos en que este no es un enfoque pragmático, pero esos momentos son lo suficientemente infrecuentes como para que la pauta anterior sea correcta. Aquí están las razones por las que no me gusta tener aserciones en los objetos de la página:

  1. Es bastante frustrante leer una prueba que solo llama a verify métodos donde las afirmaciones están ocultas en otros objetos de la página. Donde sea posible, debería ser obvio lo que afirma una prueba; esto se logra mejor cuando las aserciones están directamente en una prueba. Al ocultar las afirmaciones en algún lugar fuera de una prueba, la intención de la prueba no es tan clara.

  2. Las afirmaciones en las pruebas del navegador pueden ser costosas; realmente pueden desacelerar las pruebas. Cuando tiene cientos o miles de pruebas, se pueden agregar minutos / horas al tiempo de ejecución de la prueba; Esto es algo malo. Si mueve las aserciones solo a las pruebas que se preocupan por esas afirmaciones particulares, descubrirá que tendrá pruebas mucho más rápidas y que aún detectará los defectos relevantes. La pregunta incluyó lo siguiente:

    Al poner el código de verificación en los métodos de página, se multiplica el poder de la automatización al permitirle obtener mucha verificación "de forma gratuita".

    Bueno, "La libertad no es gratis" :) Lo que realmente estás multiplicando es el tiempo de ejecución de tu prueba.

  3. Tener afirmaciones por todos lados viola otra buena pauta; "One Assertion Per Test" ( http://blog.jayfields.com/2007/06/testing-one-assertion-per-test.html ). No me apego religiosamente a eso, pero trato de seguir el principio. Donde sea posible, una prueba debería interesarse en una sola cosa.

  4. El valor de las pruebas se reduce porque un error hará que fallen muchas pruebas, lo que les impide probar lo que deberían probar.

    Por ejemplo, imaginemos que cuando inicia sesión en su AUT, aparece un texto que dice "inició sesión como USUARIO". Es apropiado que una única prueba lo valide específicamente, pero ¿por qué no desea verificarlo cada vez que se invoca el inicio de sesión?

    Si tiene la aserción en la clase de objeto de página y el texto esperado cambia, todas las pruebas que inicien sesión fallarán. Si, por el contrario, la afirmación está en la prueba, solo fallará una prueba, la que específicamente prueba el mensaje correcto, dejando todas las otras pruebas para seguir funcionando y encontrar otros errores. No necesita 5.000 pruebas para informarle que el mensaje de inicio de sesión es incorrecto; 1 prueba hará;)

  5. Tener una clase que haga más de una cosa viola ''S'' en SOLID , es decir, '' Principio de Responsabilidad Individual '' ( SRP ). Una clase debe ser responsable de una cosa, y una sola cosa. En este caso, una clase de objeto de página debería ser responsable de modelar una página (o sección de la misma) y nada más. Si hace algo más que eso (por ejemplo, incluyendo aserciones), entonces está violando SRP.


El objeto de su página no debe realizar una afirmación porque el objeto de la página debe conocer su marco de prueba (a menos que esté usando aserciones de lenguaje integradas). Pero su página necesita saber su estado para ubicar elementos y realizar acciones.

La clave está en la declaración "Por supuesto, como sucede con todas las directrices, hay excepciones ..."

Su página debe arrojar excepciones, no realizar afirmaciones. De esta forma, su prueba puede detectar la afirmación y la libertad bajo fianza o actuar en consecuencia. Por ejemplo.

page = ProfilePage.open try page.ChangePassword(old, new) catch notLoggedIn page.Login(user, pass) assert page.contains "your password has been updated"

En este ejemplo limitado, debe verificar nuevamente (y de nuevo) para que no sea la mejor manera, pero entiende la idea. También puedes simplemente verificar el estado (dos veces)

if page.hasLoginDialog page.Login if page.hasLoginDialog //(again!) assert.fail("can''t login")

También puedes comprobar que tienes una página de perfil

try page = site.OpenProfilePage catch notOnProfilePage

o tiene los elementos que necesitas prueba profilepage.changePassword (old, new) catch elementNotFound

o sin lanzar una excepción

page = site.OpenProfilePage if ! page instanceof ProfilePage

o con control complejo

assert page.looksLikeAProfilePage

No es la forma en que lo haces lo que importa. Desea mantener la lógica en sus pruebas al mínimo, pero no desea que los objetos de su página estén vinculados a su marco de prueba; después de todo, puede usar los mismos objetos para raspar o generar datos, o con una prueba diferente. marco que tiene sus propias afirmaciones.

Si siente una necesidad, puede sacar sus afirmaciones de su caso de prueba para probar métodos de ayuda.

page = site.GoToProfilePage validate.looksLikeProfilePage(page)

que es una gran oportunidad para una mezcla si su idioma los admite, para que pueda tener sus objetos de página limpia y mezclar sus controles de cordura.


Esto me deja perplejo cuando veo que la misma afirmación se puede usar en múltiples métodos de prueba. Por ejemplo, escribir un método específico de afirmación -

public PaymentPage verifyOrderAmount(BigDecimal orderAmount) { Assertion.assertEquals(lblOrderAmount.getText(), orderAmount, "Order Amount is wrong on Payment details page"); return this; }

Ahora puedo reutilizarlo en todas las pruebas que necesito. En lugar de repetir la misma declaración de aserción en múltiples pruebas que tratan con múltiples escenarios. No hace falta decir que puedo encadenar múltiples aserciones en un método que depende de la prueba, es decir,

.verifyOrderAmount(itemPrice) .verifyBankAmount(discountedItemPrice) .verifyCouponCode(flatDiscountCode.getCouponCode())

Cuando se supone que el objeto de la página representa los servicios ofrecidos por la página, ¿no es el punto de afirmación también un servicio proporcionado por la página?


Yo también he luchado a veces con esta recomendación. Creo que la razón detrás de esta guía es mantener los objetos de su página reutilizables, y poner afirmaciones dentro de los objetos de su página podría limitar su capacidad para ser reutilizados por una gran cantidad de pruebas no relacionadas. Dicho esto, he puesto ciertos métodos de verificación en mis objetos de página, como probar el título de un encabezado; en mi experiencia, esa es una mejor manera de encapsular lógica de prueba para los elementos de una página que no cambian.

Otra nota: he visto aplicaciones MVC que tienen modelos de dominio reutilizados como objetos de página. Cuando se hace correctamente, esto puede reducir significativamente el código redundante en su biblioteca de pruebas. Con este patrón, los modelos de vista no hacen referencia a un marco de prueba, por lo tanto, obviamente, no podría poner ningún aserto en ellos.