cucumber - template - specflow documentation
SpecFlow/Cucumber/Gherkin-Uso de tablas en un esquema de escenario (2)
No creo que lo que estás pidiendo sea posible con SpecFlow, Gherkin y out-of-the-Pucumber. No puedo hablar en nombre de los autores, pero apuesto a que el propósito no debe usarse de esta manera porque va en contra del "flujo" general de escribir e implementar estas especificaciones. Entre muchas cosas, las especificaciones están destinadas a ser legibles para los no programadores, para brindar al programador una guía para implementar el código que coincida con las especificaciones, para las pruebas de integración, y para brindar a un certificado mucha flexibilidad al refactorizar.
Creo que esta es una de las situaciones en las que el dolor que sientes es una señal de que hay un problema, pero puede que no sea el que piensas. Tu dijiste:
"Sin embargo, copiar / pegar escenarios para diferentes pruebas de filtro se volverá repetitivo y ocupará una gran cantidad de código, algo que me gustaría evitar".
Primero , no estoy de acuerdo en que explicarse a sí mismo por escrito es "repetitivo", al menos no más que repetitivo para usar palabras específicas como "la manzana, el auto, etc." una y otra vez. El problema es: ¿estas palabras explican correctamente lo que estás haciendo? Si lo son, y explicar su situación requiere que escriba varios escenarios, entonces eso es justo lo que requiere. La comunicación requiere palabras, ya veces las mismas.
De hecho, lo que usted llama "repetitivo" es uno de los beneficios de usar Gherkin y una herramienta como Cucumber o SpecFlow. Si puede usar esa oración una y otra y otra vez, significa que no tiene que escribir el código de prueba una y otra y otra y otra vez.
Segundo , ¿estás seguro de que estás escribiendo una especificación para la cosa correcta? Solo pregunto porque si el número de escenarios se va de las manos, hasta el punto en que tienes tantos que un humano no puede seguir lo que escribes, es posible que tu especificación no esté orientada hacia lo correcto.
Un posible ejemplo de esto podría ser cómo está probando el filtrado y la paginación en este escenario. Sí, desea que sus especificaciones cubran todas las funciones y su sitio tendrá paginación en la misma página que su filtro, pero ¿a qué costo? Se requiere experiencia y práctica para saber cuándo renunciar al supuesto "ideal" de las pruebas de no integración burlona y completa dará mejores resultados.
Tercero , no piense que las especificaciones deben ser una cobertura perfecta para cada escenario posible. Los escenarios son básicamente instantáneas de estado, lo que significa que hay algunas características que podrían cubrir un conjunto infinitamente grande de escenarios, lo cual es imposible. Entonces, ¿Qué haces? Escribe características que cuenten la historia lo mejor que puedas. Incluso dejemos que la historia impulse el desarrollo. Sin embargo, los detalles que no se traducen a sus especificaciones u otros casos es mejor dejarlos en TDD directos, hechos además de las especificaciones.
En su ejemplo, parece que básicamente está contando una historia sobre un sitio que le permite a un usuario crear una búsqueda dinámica contra dulces y golosinas. Ingresan uno de un amplio conjunto de posibles criterios de búsqueda, hacen clic en un botón y obtienen resultados. Solo apégate a eso, escribiendo solo las especificaciones suficientes para cumplir la historia. Si no está satisfecho con su cobertura, límpielo con más especificaciones o pruebas unitarias.
De todos modos, eso es sólo mis pensamientos, espero que ayude.
Con suerte, puedo explicar mi problema con la suficiente claridad para que otros lo entiendan. Aquí vamos, imagino que tengo los dos escenarios hipotéticos siguientes:
Scenario: Filter sweets by king size and nut content
Given I am on the "Sweet/List" Page
When I filter sweets by
| Field | Value |
| Filter.KingSize | True |
| Filter.ContainsNuts | False |
Then I should see :
| Value |
| Yorkie King Size |
| Mars King Size |
Scenario: Filter sweets by make
Given I am on the "Sweet/List" Page
When I filter sweets by
| Field | Value |
| Filter.Make | Haribo |
Then I should see :
| Value |
| Starmix |
Estos escenarios son útiles porque puedo agregar tantas entradas de filas de campo / valor y luego valor como quiera sin cambiar los pasos de prueba compilados asociados. Sin embargo, copiar / pegar escenarios para diferentes pruebas de filtro se volverá repetitivo y ocupará una gran cantidad de código, algo que me gustaría evitar. Idealmente, me gustaría crear un esquema de escenario y mantener la naturaleza dinámica que tengo con las pruebas anteriores. Sin embargo, cuando trato de hacerlo, me encuentro con un problema que define la tabla de ejemplo. No puedo agregar nuevas filas como me parezca, porque eso sería Una nueva instancia de prueba, actualmente tengo esto:
Scenario Outline: Filter Sweets
Given I am on the <page> Page
When I filter chocolates by
| Field | Value |
| <filter> | <value> |
Then I should see :
| Output |
| <output> |
Examples:
| page | filter | value | output |
| Sweet/List | Filter.Make | Haribo | Starmix |
Por lo tanto, tengo el problema de poder agregar filas dinámicamente a mi filtro y los datos esperados al usar un esquema de escenario. ¿Alguien está al tanto de una forma de evitar esto? ¿Debería estar acercándome a esto desde un ángulo diferente?
Una solución podría ser algo como:
Then I should see :
| Output |
| <x> |
| <y> |
| <z> |
Examples:
| x | y | z |
Pero eso no es muy dinámico ... esperando una mejor solución? :)
Técnicamente, creo que podrías intentar llamar a pasos desde una definición de paso:
Llamando a pasos de definiciones de pasos
Por ejemplo, creo que podrías reescribir el
Then I should see :
| Output |
| <output> |
Para ser un paso personalizado como
I should have output that contains <output>
Donde la salida es una lista separada por comas de valores esperados. En el paso personalizado, podría dividir la lista separada por comas en una matriz e iterar sobre ella llamando
Then "I should see #{iterated_value}"
Podría usar una técnica similar para pasar en listas de filtros y valores de filtro. Tu fila de ejemplo para la prueba de tamaño king podría verse como
| page | filter | value | output |
| Sweet/List | Filter.KingSize, Filter.ContainsNuts | True, False | Yorkie King Size, Mars King Size |
O tal vez
| page | filter-value-pairs | output |
| Sweet/List | Filter.KingSize:True, Filter.ContainsNuts:False | Yorkie King Size, Mars King Size |
Dicho esto, quizás deberías tomar en serio las palabras de Darren. No estoy realmente seguro de que este método ayude al objetivo final de tener escenarios que los no desarrolladores puedan leer.