5

Actualmente estoy trabajando en la construcción de un conjunto de pruebas funcionales automatizadas/aceptación para un proyecto, pero no tengo mucha experiencia escribiendo este tipo de pruebas, así que quería conseguir algo entrada en la estructuración adecuada de ellos. Específicamente, estoy trabajando con la extensión Graphene de Arquillian.estructura funcional apropiado de/Pruebas de aceptación

Por ejemplo, decir que tengo 3 pruebas, A, B, y C.

Testa: Pruebas de Inicio de sesión en una cuenta en la aplicación. Por lo tanto, si la prueba es exitosa, el navegador debe estar en la página de inicio/información de la cuenta.

TestB: Pruebas que modifican la contraseña de una cuenta. Esto requeriría iniciar sesión en la cuenta y luego probar la funcionalidad de cambio de contraseña.

TestC: Pruebas que modifican el correo electrónico de una cuenta. Esto nuevamente requeriría iniciar sesión en la cuenta y luego probar la funcionalidad de cambio de correo electrónico.

Si Testa falla debido a un problema con el código de inicio de sesión, obviamente TestB y TestC deben fallar, así, ya que requieren estando conectado a una cuenta.

Pregunta: ¿Las pruebas funcionales/de aceptación automatizadas deben duplicar cada uno de los procesos necesarios para completar lo que la prueba está verificando? En este caso, TestB y TestC necesitan iniciar sesión en la cuenta antes de hacer cualquier otra cosa. En caso de que cada prueba llamar explícitamente a algo como:

/* ...initial test setup code here */ 
LoginPage.login(username, password); 
assertTrue(onCorrectAccountPage); 
AccountModification.changePassword(newPassword); 

O debería usar alguna forma de burlarse de una cuenta en la sesión que puede ser utilizado por pruebas B y C para que no fallan, incluso si Testa (el actual prueba de inicio de sesión) ¿no?

Dado que estas son pruebas de aceptación del usuario, pensé que deberían hacer exactamente lo que el usuario haría e iniciar sesión siempre que fuera necesario, pero no estoy seguro si esto es una duplicación innecesaria que debe manejarse de manera diferente (es decir, tratados como unidades de funcionalidad, similar a una prueba de unidad estándar) y quería recibir retroalimentación de alguien con más experiencia en esta área.

Gracias de antemano. Espero que mi pregunta no sea demasiado complicada. :)

Respuesta

4

Yo personalmente lo he hecho para que cada caso de prueba se replica la acción usuarios tanto como sea posible, pero eliminando los lugares donde es necesario. Por ejemplo, TestA: inicia sesión, va al sitio web correcto, va a su sistema de administración, encuentra un usuario y borra parte de la información de los usuarios (como nombre), TestB: inicia sesión, va al sitio web correcto, va a es el sistema de administración, encuentra un usuario e intenta eliminar a los usuarios por completo mediante un botón.

Testa y TestB terminan en la misma página - la página de detalles de usuario. Entonces, en la prueba A, puedo hacerlo todo correctamente, exactamente cómo lo hace un usuario, pero en la prueba B, voy directamente a la página de detalles para ese usuario, en lugar de ir a la navegación correcta manualmente. ¿Por qué?

ahorra tiempo, ¿por qué debería volver a hacer la navegación en la prueba B cuando A prueba ya prueba de que de todos modos?

Recuerde que las pruebas no deben ser dependientes entre sí; si las tres pruebas fallan porque no puede iniciar sesión, ese es el punto, no puede iniciar sesión, por lo que no puede hacer ninguna de las otras acciones.

pensar en él como lo haría un usuario.Cada prueba tiene su propia funcionalidad visible para el usuario que están probando, pero si no puede iniciar sesión, un usuario no puede ver nada de eso ni hacer nada con la funcionalidad de todos modos. Si no puedo iniciar sesión, no puedo cambiar mi contraseña o mi correo electrónico, por lo que lógicamente las pruebas deberían fallar de la misma manera.

+0

Bien explicado. Estaba pensando en la misma línea, pero la idea de "no duplicar" está tan grabada en mi proceso de pensamiento que no estaba seguro en esta circunstancia. Gracias por tu respuesta. – whitlaaa

3

Esto es realmente una pregunta por proyecto, ya que ambos son enfoques válidos, pero en diferentes situaciones uno debería ser más preferido. En un sistema grande, prefiero ejecutar el caso de prueba de principio a fin, independientemente de la frecuencia con la que se repiten los pasos (por ejemplo, inicio de sesión para cada prueba). Creo que esto es lo que Arran ya ha dicho (¡+1!). La razón por la que suelo hacer esto es porque a veces un estado transferido desde una pantalla anterior puede causar un error más adelante y ese es el tipo de cosas que las pruebas automatizadas son excelentes para encontrar. Sin embargo, con estos, me aseguro de que los datos de prueba sean todos válidos para los pasos iniciales y apunten a la solución más rápida posible. Por ejemplo, el inicio de sesión siempre debe tener el usuario y la contraseña correctos; luego, al verificar que el inicio de sesión fue exitoso, simplemente asuma que debe y trate una excepción más adelante o busque un elemento fácilmente identificable en la página en lugar de uno complicado "más importante".

Dicho esto, también puede escribir pruebas que están probando múltiples requisitos en una especie de flujo de funcionalidad. Si las pruebas de interrupción de flujo deben escribirse para identificar el área en la que la tarea general está fallando. Solo recomendaría esto para proyectos pequeños, o si las pruebas no son una prioridad debido a la falta de recursos. Por ejemplo, ejecutar una prueba que inicie sesión, seleccionar un elemento, colocarlo en un carrito, revisarlo y pagar probará toda esta funcionalidad y permitirá que un equipo corrija el 'proceso' general en lugar de solo varios, potencialmente desconectados. bichos De nuevo, sin embargo, creo que el primer enfoque es más completo pero también lleva más tiempo (pero vale la pena hacerlo a menudo :)).

Por temor a que mi respuesta sea demasiado larga y bloqueada, no voy a profundizar en esto aquí, pero hay mucho de qué hablar al respecto y sugiero que se siente y extraiga lo que estamos tratando de probar en la aplicación, ahora y en el futuro. Esto probablemente será muy revelador y fomentará una buena estructura de prueba y prácticas de escritura automatizadas. Espero que esto ayude y no sea demasiado largo :)

+0

"... prueba múltiples requisitos en una especie de flujo de funcionalidad". Esto es algo que había planeado hacer además de las pruebas de funcionalidad más específicas, siempre que tengamos el tiempo y los recursos. Tu respuesta definitivamente no fue demasiado larga. :) Gracias por tu ayuda. – whitlaaa

+0

Y lo que estoy haciendo actualmente con estas pruebas de "flujo" es ponerlas en un grupo separado de mis pruebas principales. Luego, cuando se inicia una compilación, es bueno usarlos como una especie de "prueba de humo" o prueba de funcionalidad básica, ya que toman menos tiempo y aún así prueban la funcionalidad principal de la aplicación.Feliz esto ayudó :) – Nashibukasan

1

En un prueba de aceptación del usuario prueba que no desea simular, pero sea lo más cercano posible a la forma en que un usuario final usaría el sistema.

Sin embargo, el mantra de prueba de unidad one assert per test se puede extender a las pruebas de aceptación: En Testa su lógica de verificación es la hora de afirmar entrada apropiada: En TestB que no es necesario repetir esta verificación, afirmando simplemente que la modificación de la contraseña se maneja correctamente .

En JUnit, se puede utilizar en lugar de assumeTrueassertTrue a tal fin. Entonces su TestB se convertiría en:

/* ...initial test setup code here */ 
LoginPage.login(username, password); 
assumeTrue(onCorrectAccountPage); 
AccountModification.changePassword(newPassword); 

Ahora, si se supone que True falla, simplemente se ignora la prueba. Sin embargo, su TestA aún fallará, informándole a usted y a su usuario final cuál es el verdadero problema.

+0

Este es un enfoque interesante que no había pensado usar. Veré más en eso. – whitlaaa

Cuestiones relacionadas