¿Debo tener historias de usuarios que traten el caso en el que el usuario no está autenticado?

En mi software, muchos servicios esperan que el usuario sea autenticado antes de ejecutarse.

En escenarios positivos, tengo este tipo de contexto:

Given I am authenticated
When I create meeting X
Then meeting X is well created 

Estoy acostumbrado a escribir un escenario simétrico como este para cada uno de mis servicios que se ocupa del requisito de autenticación del usuario:

Given I am not authenticated  //note the 'not' word
When I create meeting X
Then meeting X is not created
And an authentication error should be thrown

Obliga al desarrollador a manejar la verificación de la autenticación del usuario en la parte superior de la implementación del servicio, para evitar que cualquier "pirata informático" potencial o código malicioso llame a la API (en este ejemplo, "creación de la reunión") directamente mientras no esté autenticado.

¿Es una práctica que debo mantener?
¿Tengo razón al considerar este escenario "defensivo" como una regla de negocios real que puedo discutir con el equipo de "Negocios"?

Tenga en cuenta que mis pruebas de aceptación no prueban a través de la parte de GUI, sino solo directamente a través de la parte de casos de uso (servicios/reglas comerciales).

La creación de etiquetas para pepinillos o pepinos podría ser útil para preguntas como estas, pero podría deslizarse fácilmente hacia la ingeniería.
"Dado que no estoy autenticado... cuando creo la reunión X": algo más en lo que pensar es por qué un usuario no autenticado puede incluso intentar crear una reunión. Esto parece más un problema de diseño de UX que un caso de prueba útil. Como siempre, YMMV.

Respuestas (4)

Respuesta corta: sí, está perfectamente bien tener en cuenta los casos negativos.

Estoy acostumbrado a ver esto un poco diferente. Por lo general, una historia de usuario es un paso adelante como:

Como usuario, me gustaría poder agregar una reunión en el calendario para poder realizar un seguimiento de mi agenda para el día"

Entonces tendría ambos como criterios de aceptación en esa historia.

Sin embargo, esta recomendación es más una cuestión de estilo. Me gusta esto porque los agrupa mejor para que los casos comerciales importantes no se pasen por alto. Lo que estás haciendo ciertamente no está mal.

Parece que tu oración es la etiqueta de una función para mí, no de una historia de usuario. La función tiene como objetivo centrarse en el objetivo ("Me gustaría..."), una historia de usuario (escenario) es un camino para lograrlo (o no) con "Dado/Cuando/Entonces".
Definitivamente he tenido una experiencia diferente en terminología, pero parece que estamos en la misma página: "Me gustaría" describe el objetivo y "Dado/Cuándo/Entonces" describe el comportamiento esperado dentro de ese . De cualquier manera, creo que es bueno e incluso importante que tenga en cuenta el comportamiento negativo esperado. Espero que sus evaluadores descubran más aún que deben tenerse en cuenta.

Capture conceptos comerciales (no pasos de ingeniería) en Gherkin

¿Es una práctica que debo mantener?

Quizás. Los casos de prueba negativos, como las condiciones límite, son cosas buenas para probar desde una perspectiva de control de calidad. Sin embargo, desde una perspectiva de ingeniería o gestión de productos, vale la pena preguntarse por qué necesita un escenario limitado como este en lugar de una función más completa o un esquema de escenario. Y desde una perspectiva comercial, los detalles de bajo nivel en las pruebas de aceptación son generalmente un antipatrón.

Expresar el caso de negocios

Por ejemplo, en lugar de tener todo tipo de puntos de entrada extraños como casos de uso separados, una característica más completa podría decir:

Given that a user is not authenticated
When the user performs any action
Then the user is redirected to the login page.

Esto captura el caso de negocio real mejor y más claramente, aunque probablemente desee pasos individuales o un esquema de escenario para probar todos los puntos de entrada posibles y poder informar fallas individuales de manera más efectiva.

El beneficio de este tipo de historia es que captura la lógica del negocio mucho mejor que una historia centrada en la implementación. Por otro lado, una falla dentro de uno de los pasos es mucho menos comunicativa y requiere el conocimiento de los pasos subyacentes para reducir las fallas específicas.

Hay un término medio: los contornos del senario.

Usar esquemas de escenario

El principal problema de expresar solo el dominio comercial sin definir también algún contexto o casos de uso específicos es que no puede determinar con especificidad dónde está fallando un grupo de prueba. Ahí es donde los esquemas de escenarios de Cucumber pueden ayudar.

Por ejemplo:

Scenario Outline: force authentication on all pages
  Given an unauthenticated user
  When the user connected to the <function> page
  Then the user should be redirected to the login page.

  Examples:
    | function |
    | meeting  |
    | calendar |
    | profile  |
    | launch thermonuclear warheads |

Con este tipo de esquema, el objetivo comercial es claro y también tiene un conjunto de pruebas de alto nivel que pueden pasar o fallar independientemente unas de otras. Los informes de nivel superior son granulares y cohesivos, al tiempo que evitan el tipo de "expansión de prueba" que obtendría al agregar escenarios negativos para cada comportamiento.

Resumen

La prueba es más una forma de arte que una ciencia, por lo que su kilometraje puede variar. Sin embargo, las pruebas ágiles deben funcionar como un comportamiento de autodocumentación en lugar de detalles de bajo nivel, y los criterios de aceptación deben centrarse más en la lógica comercial o el comportamiento visible del usuario que en los detalles de implementación subyacentes.

¿Qué es diferente de mi práctica en mi OP? ¿El hecho de que mencione el regreso de un error? ¿Suena demasiado técnico incluso si es "abstracto"? Lo necesito porque mis pruebas de aceptación se enfocan directamente en los casos de uso, no en la GUI ni en ningún mecanismo de "redireccionamiento".
La diferencia, si lo entiendo bien, al menos votaría por eso, es que mantienes este requisito general en un solo lugar. Esto simplifica el mantenimiento de requisitos (imagínate qué pasa si hay un cambio al respecto; en tu caso, tendrás que actualizar muchos lugares) y también la derivación de casos de prueba o requisitos técnicos de bajo nivel.
@ Mik378 Intrínsecamente está tratando de elevar los pasos al estado de primera clase en sus escenarios. Si bien puede hacer esto, y los méritos de hacerlo podrían discutirse en otro lugar (como en un sitio sobre ingeniería de pruebas de control de calidad), este es un sitio sobre gestión de proyectos. Desde la perspectiva de PM, las pruebas de bajo nivel y el lenguaje orientado a la ingeniería no deberían ser artefactos de proyectos de primera clase. De hecho, consideraría que los informes de nivel de ingeniería se hacen pasar por "pruebas de aceptación" como un problema de proyecto serio que definitivamente debería tratarse como un antipatrón. YMMV.
@CodeGnome No creo que sean pruebas de bajo nivel. Un escenario no es una prueba de bajo nivel sino una especificación exigida por el Negocio.

TL; DR: Sí, puede mantenerlo de esta manera.

Respuesta larga

Dependiendo de para qué esté utilizando los escenarios o las reglas comerciales , hay varias formas de escribirlos.

Primer caso: el escenario se utiliza para los criterios de aceptación

Historia

Como usuario, quiero crear reuniones, para...

Criterios de aceptación

  • El usuario autenticado puede crear reuniones a través de una GUI/API
  • Los usuarios anónimos no deberían poder crear reuniones y obtener un error en su lugar.

Primer caso: el escenario se utiliza para pruebas de aceptación / regresión , que son instrucciones fragmentadas para hacer clic en la aplicación. Todas estas pruebas deben pasar después de cada historia (o al menos antes de cada lanzamiento).

Ejemplo incompleto:

camino feliz

  1. abrir el navegador -> aparece la pantalla de inicio de sesión
  2. autenticar -> mensaje de inicio de sesión exitoso
  3. crear una reunión -> ver detalles de la reunión

sin autenticación

  1. abrir el navegador -> aparece la pantalla de inicio de sesión
  2. crear una reunión -> ver la creación fallida debido a un error de autenticación

Nota al margen

Recomendaría hacer las pruebas de regresión a través de la GUI por parte de un usuario. Si están bien escritos, pueden implementarse en código y ejecutarse automáticamente.

Lo que llamas historia, yo lo llamo característica. Lo que llamas criterio, yo lo llamo historia o escenario. Esos son términos de pepinillo.
Ya veo, tal vez reemplace una etiqueta con pepinillo :) No importa, además de los términos, ¿esta respuesta es útil de alguna manera?
Sí, la respuesta es útil, pero no estoy de acuerdo con el hecho de que la prueba de regresión deba realizarse a través de la GUI. 8thlight.com/blog/doug-bradbury/2011/04/26/… (al final de este artículo)
Pensamientos interesantes :) Solo para aclarar esto, además de las pruebas de regresión, estamos usando pruebas unitarias para obtener resultados rápidos (casi sin esperas) y pruebas de regresión automatizadas todos los días, comprobando todas las pruebas de aceptación en entornos "reales" (además de varias versiones y sistemas de base de datos). De esta manera nos aseguramos de que todo funcione como debería, incluso para pequeños cambios. Antes de eso, a menudo teníamos la situación de que muchas de nuestras pruebas se burlaban y daban errores después de lanzarlas a otros entornos.
Practico ATDD, que consiste en implementar pruebas de aceptación a través de unos ciclos TDD (pruebas unitarias). Tan pronto como pasen esas pruebas unitarias (algoritmo incremental), la prueba de aceptación en cuestión debería pasar.
El tío Bob (Robert C. Martin) discute profundamente sobre su forma de hacer. El inconveniente de su enfoque es que acopla la GUI a las reglas comerciales. Cambia la GUI (cliente pesado a cliente web, por ejemplo), rompe las pruebas sobre las reglas comerciales ... Además, sus pruebas serían lentas, muy lentas si tiene en cuenta la GUI. Las pruebas que se ocupan de la GUI no deben probar las reglas comerciales, sino solo las cosas de la GUI.
De hecho, el rendimiento es un problema y sí, cambiar la GUI lo obliga a cambiar la prueba; ¡es por eso que nuestra lógica comercial se prueba completamente con pruebas unitarias! Las pruebas de regresión, tal como las usamos, con una GUI, se acercan lo más posible a la forma de hacer las cosas de los usuarios, por eso me gustan.
Las pruebas unitarias no son suficientes aunque parecen pruebas de aceptación ( vimeo.com/68375232 ). La diferencia es que las pruebas de aceptación son dominadas por el equipo comercial, no solo por los desarrolladores. Gherkin, por ejemplo, está a punto de conversar con Business. Los archivos Gherkin son la fuente de las pruebas de aceptación, no deben tratar con la GUI. 8thlight.com/blog/uncle-bob/2013/09/26/AT-FAIL.html ctrl+f => "Qué cambia más que la interfaz de usuario"

Como han escrito otros, dar cuenta de los casos negativos es bueno. Sin embargo, la estructura de su caso negativo no lo es, porque contiene una contradicción interna.

El problema es que está describiendo los resultados como si fueran acciones del usuario. Pero en realidad son la acción que toma el software en respuesta a la acción del usuario. Las fallas tienen acciones del usuario, pero el resultado esperado nunca ocurre, porque la falla evita que suceda realmente, por lo que una historia basada en el evento nunca se satisface.

Malo:

Dado que estoy autenticado

Cuando creo la reunión X

Mejor:

Dado que estoy autenticado

Cuando envío una solicitud de "crear reunión"

Esto sigue funcionando a nivel de backend, no se refiere a elementos específicos de la interfaz de usuario, como menús o botones, y cubre la actividad de la red no generada por la interfaz aprobada (cubriendo la preocupación de "pirateo").

hmm, no estoy de acuerdo como expliqué anteriormente. Las pruebas de aceptación no deben centrarse en la GUI o la parte del controlador, sino directamente en el caso de uso. Cuando menciona "enviar"/"solicitar", esos son términos de web => gui. Gui es un detalle de implementación y los detalles no deben ser parte de las pruebas de aceptación. Por ejemplo, si su cliente es una consola pura (terminal) en lugar de una web, los términos de su prueba de aceptación serían inapropiados.
Pensé en tu punto. Encontré el siguiente ejemplo que mejora bastante la coherencia de un escenario: agilealliance.org/glossary/gwt (en la parte inferior). Me gusta el enfoque "Intento...", lo que significa que el resultado aún no es predecible antes de actuar. Es lo suficientemente abstracto para cumplir con mi agnosticismo de UI y es similar a su "Envío...".
@Mik378: Sí, eso también debería funcionar bien.