tag keywords etiquetas ejemplos java cucumber acceptance-testing cucumber-jvm cucumber-junit

java - keywords - ¿Cómo organizar la definición de las especificaciones en pepino?



title html (3)

Sobre el proyecto actual en el que participo, nos hicimos la misma pregunta.

Después de juguetear un poco con las posibilidades, optamos por una combinación de las dos soluciones que expusiste.

  • Haga que los pasos se reagrupen en clases de pasos comunes centradas en el tema
    • pasos de inicio de la aplicación
    • pasos de control de seguridad
    • Pasos de [colocar una característica al azar aquí]
  • Y clases de escenario (y en algunos casos incluso características) pasos específicos.

Esto debía tener al mismo tiempo la agrupación de código factorizado, que es bastante fácil de identificar en todo lo que se refiere, el paradero y otras cosas. Sin embargo, permite no saturar esas clases comunes con un código demasiado específico.

El cableado entre todas estas clases se maneja en la primavera (con la primavera del pepino, que hace un gran trabajo una vez que aprendes).

Estamos considerando usar Cucumber en nuestro proyecto para las pruebas de aceptación.

Cuando escribimos un scenario en una feature Pepino, escribimos una lista de las declaraciones Given , When y Then .

Como usamos el proyecto cucumber-jvm , las declaraciones Given , When y Then están relacionadas con los métodos Java en las clases (JUnit).

Quiero saber cuál es la mejor organización para el código relacionado con Given / When / Then en la estructura del proyecto. Mi principal preocupación es el mantenimiento de las pruebas de pepino en un proyecto grande, donde el número de escenarios es bastante importante, y especialmente en lo que respecta a los elementos que se comparten entre las características.

Puedo ver al menos 2 enfoques principales:

  1. Cada característica está relacionada con su propia clase JUnit. Así que si tengo un archivo de pepino foo/bar/baz.feature , encontraré la clase foo.bar.Baz con los @Given adecuados @Given , @When y @Then anotados.

  2. Separe los @Given , @When y @Then en clases y paquetes "temáticos". Por ejemplo, si en mi escenario de pepino tengo una declaración Given user "foo" is logged , entonces se @Given("^user /"([^/"]*)/" is logged$") el @Given("^user /"([^/"]*)/" is logged$") en el método de la clase foo.user.User , pero potencialmente, el método @When que se usará más adelante en el mismo escenario de pepino estará en una clase y paquete Java diferente (digamos foo.car.RentCar ).

Para mí, el primer enfoque parece bueno en la forma en que puedo hacer fácilmente la relación entre mis características de pepino y mi código Java. Pero el inconveniente es que puedo tener muchas redundancias o duplicación de código. Además, puede ser difícil encontrar un posible método @Given existente, evitar recrearlo (el IDE puede ayudar, pero aquí estamos usando Eclipse, y no parece que ofrezca una lista de las declaraciones de Given existentes).

El otro enfoque parece ser mejor esencialmente cuando se le han Given condiciones compartidas entre varias características de pepino y, por lo tanto, quiero evitar la duplicación de código. El inconveniente aquí es que puede ser difícil establecer un vínculo entre el método Java @Given y la declaración del pepino Given (quizás, otra vez, el IDE pueda ayudar?).

Soy bastante nuevo en el pepino, así que tal vez mi pregunta no sea una buena pregunta, y con el tiempo y la experiencia, la estructura será evidente, pero quiero obtener buenos comentarios sobre su uso ...

Gracias.


Sugeriría agrupar su código de acuerdo con los objetos a los que se refiere, de manera similar a la opción # 2 que presentó en su pregunta. Las razones son:

  • La estructuración de su código en función de cómo y dónde se utiliza es un gran no-no. En realidad, está creando un acoplamiento entre sus archivos de características y su código.
    Imagine una cosa así en el código de su producto: la función SendEmail() no estaría en una clase llamada NewEmailScreenCommands , ¿verdad? Sería en EmailActions o algo así.
    Así que lo mismo se aplica aquí; estructura tu código de acuerdo con lo que hace, y no quién lo usa.

  • El primer enfoque dificultaría la reorganización de sus archivos de características; Tendrías que cambiar tus archivos de código cada vez que cambies tus archivos de características.

  • Mantener el código agrupado por tema hace que el SECADO sea mucho más fácil; usted sabe exactamente dónde está todo el código que trata con la entidad del user , por lo que es más fácil reutilizarlo.

En nuestro proyecto utilizamos ese enfoque (es decir, la clase BlogPostStepDefinitions ), con una mayor separación del código, si la clase es demasiado grande, a los tipos de pasos (es decir, BlogPostGivenStepDefinitions ).


También hemos comenzado a usar Cucumber-JVM para las pruebas de aceptación y tenemos problemas similares con la organización del código. Hemos optado por tener una clase de definición de 1 paso para cada función. Por el momento, esto está bien, ya que las funciones que estamos probando no son muy complejas y están bastante separadas, hay muy poca superposición en nuestras funciones.

Creo que el segundo enfoque que mencionó sería mejor, pero a menudo es un desafío unir varias clases de definición de pasos diferentes para un solo escenario. Creo que la mejor estructura del proyecto se volverá más clara una vez que comience a agregar más funciones y refactorice de manera normal.

Mientras tanto, aquí hay un plugin de Eclipse para pepino,

https://github.com/matthewpietal/Eclipse-Plugin-for-Cucumber

tiene resaltado de sintaxis, así como una lista de los pasos disponibles existentes al escribir una función.