¿Cuál es la diferencia entre los marcos de prueba de unidad ScalaTest y Scala Specs?

121

Ambos son marcos de prueba de unidad capaces de BDD (Behavior Driven Development) para Scala escritos en Scala. Y las especificaciones sobre las que se basa también pueden involucrar el marco ScalaTest . Pero, ¿qué ofrecen las especificaciones que ScalaTest no ofrece? ¿Cuáles son las diferencias?

Alex
fuente
1
No creo que sea exacto decir que las especificaciones se basan en ScalaTest. Tenga en cuenta que la dependencia en el pom es opcional. Sin embargo, las especificaciones tienen la capacidad de que sus especificaciones se ejecuten como un conjunto ScalaTest.
Geoff Reedy
scalatest proporciona scalatestplus con soporte específico para varias bibliotecas. Puede ser interesante. por ejemplo, tienen scalatestplus para el marco de juego
pedrorijo91

Respuestas:

172

Las especificaciones y ScalaTest son buenas herramientas con usuarios felices, pero difieren de varias maneras. Probablemente querrá elegir uno como su principal herramienta de prueba en Scala, pero no necesita renunciar al otro porque puede usar piezas de ambos. Si le gusta la FeatureSpecsintaxis de ScalaTest y la sintaxis de Mockito de las especificaciones, por ejemplo, puede poner ambos archivos jar en su classpath y usar ambos al mismo tiempo. Aquí intentaré capturar las principales diferencias de filosofía de diseño que he notado entre las especificaciones y ScalaTest.

Probablemente la principal diferencia filosófica entre las herramientas es que las especificaciones están diseñadas para Behavior-Driven Development (BDD), mientras que ScalaTest es más general. ScalaTest proporciona rasgos que puede mezclar para obtener el comportamiento que prefiere en sus clases de prueba, incluido BDD, y también puede definir fácilmente su propio comportamiento si desea algo diferente.

ScalaTest soportes TDC a través de su Spec, FeatureSpec, WordSpec, FlatSpec, y GivenWhenThenrasgos, y también tiene rasgos que se pueden mezclar para obtener una sintaxis matcher agradable. Si te gusta "should", debes mezclar DoesMatchers. Si te gusta "must", te mezclas MustMatchers. Pero si le gusta BDD pero no le gusta la sintaxis de matcher, puede usar uno de los rasgos Spec de ScalaTest sin mezclar un rasgo de matchers. Las especificaciones tienen una clase de especificación que usted extiende, y debe usar la palabra "debe" en sus expresiones de coincidencia. Una gran diferencia filosófica que es evidente aquí es que ScalaTest le ofrece muchas más opciones. Para hacer que este espacio de elección sea más fácil de navegar, proporciono un árbol de decisión aquí:

http://www.scalatest.org/quick_start

La sintaxis de matcher también es diferente entre ScalaTest y las especificaciones. En ScalaTest traté de ver hasta dónde podía llegar con la notación de operador, y terminé con expresiones de comparación que se leían muy parecidas a las oraciones en inglés, con espacios entre las palabras. La sintaxis de coincidencia de especificaciones combina más las palabras con el caso de camello.

Specs tiene más coincidencias que ScalaTest, y creo que refleja una diferencia en la actitud de diseño. De hecho, corté probablemente 2/3 de la sintaxis de matcher que construí y consideré para su lanzamiento. Agregaré más coincidencias en futuras versiones, pero quería estar seguro de que sabía que los usuarios realmente querían algo antes de agregarlo. Sin embargo, los comparadores de ScalaTest incluyen una sintaxis dinámica de comparador de propiedades que ocupa parte de esa holgura. Por ejemplo, en las especificaciones, puede escribir en java.io.File:

file must beDirectory

Esto invocará isDirectoryy se asegurará de que sea cierto. ScalaTest no tiene coincidencias especiales para la java.io.Filesactualidad, pero en ScalaTest, podría usar una verificación dinámica como esta:

file must be a ('directory)

Cada vez que pase un símbolo después be, usará la reflexión para buscar (en este caso) un método o campo llamado directoryo un método llamado isDirectory. También hay una manera de hacer esto estático, definiendo un BePropertyMatcher(que generalmente requiere solo 2 o 3 líneas de código). Básicamente, en ScalaTest trato de proporcionar más funcionalidad con menos API.

Otra diferencia de actitud de diseño general entre las especificaciones y ScalaTest implica conversiones implícitas. Por defecto, solo obtiene una conversión implícita cuando usa ScalaTest, que es la que pone al ===operador en todo. (Si es necesario, puede "desactivar" esta conversión implícita con una sola línea de código. La única razón por la que tendría que hacerlo es si intenta probar algo que tiene su propio código).=== operador y se genera un conflicto. ) ScalaTest define muchas otras conversiones implícitas, pero para usarlas debe "invitarlas" explícitamente a su código mezclando un rasgo o haciendo una importación. Cuando extiendes claseSpecificationen las especificaciones, creo que obtienes docenas de conversiones implícitas por defecto. No estoy seguro de cuánto importará eso en la práctica, pero creo que la gente querrá probar el código que usa sus propias implicaciones, y a veces puede haber un conflicto entre las implicaciones del marco de prueba y las del código de producción. Cuando eso suceda, creo que puede ser más fácil solucionar el problema en ScalaTest que las especificaciones.

Otra diferencia en la actitud de diseño que noté es la comodidad con los operadores. Un objetivo que tenía era que cualquier programador que mirara el código de prueba de otra persona que usa ScalaTest sería capaz de adivinar cuál era el significado sin buscar nada en la documentación de ScalaTest. Quería que el código del cliente ScalaTest se volviera obvio. Una forma en que ese objetivo se manifestó es que ScalaTest es muy conservador con respecto a los operadores. Solo defino cinco operadores en ScalaTest:

  • ===, que significa igual
  • >, lo que significa mayor que
  • <, menos que
  • >=, mayor que o igual
  • <=, menor o igual.

Eso es. Entonces, estas cosas se parecen bastante a lo que significan. Si ves en el código de otra persona:

result should be <= 7

Espero que no necesite ejecutar la documentación de la API para adivinar lo que eso <=significa. Por el contrario, las especificaciones son mucho más libres con los operadores. No tiene nada de malo, pero es una diferencia. Los operadores pueden hacer que el código más conciso, pero la desventaja es que usted puede tener que ejecutar la documentación cuando encuentre cosas como ->-, >>, |, |>, !, o ^^^(que todos tienen un significado especial en Especificaciones) en el código de prueba de su colega.

Otra diferencia filosófica es que trato de facilitar un poco el uso de un estilo funcional en ScalaTest cuando necesita compartir un dispositivo, mientras que las especificaciones por defecto continúan la tradición setUpy el tearDownenfoque popularizado por JUnit, en el que reasigna vars antes de cada prueba. Sin embargo, si desea probar de esa manera, también es muy fácil en ScalaTest. Solo necesitas mezclar el BeforeAndAfterrasgo.

Para obtener más información sobre ScalaTest, puede ver la presentación "Mejore con ScalaTest" que hice en la conferencia Devoxx 2009 aquí:

http://parleys.com/play/514892260364bc17fc56bde3/chapter0/about

Bill Venners
fuente
66
La legibilidad de scalatest es un importante punto ganador sobre las especificaciones de escala para mí.
nemoo
49

Las principales diferencias son (principalmente desde el punto de vista de las especificaciones :-)):

  • ScalaTest proporciona más "estilos de prueba" que especificaciones (puede visitar cada viñeta en la página de inicio rápido para obtener una vista detallada de cada estilo)

  • ScalaTest y las especificaciones tienen un conjunto diferente de coincidencias. Puede compararlos aquí para ScalaTest y aquí para especificaciones. En ese lado de las cosas, las especificaciones tienen muchas características pequeñas que te pueden gustar al escribir tu especificación: xml matchers, composición de matchers (una manera fácil de reutilizar matchers transformándolos), fallas precisas, diferencias detalladas para cadenas largas, ... .

  • Mockito ha recibido un buen soporte de BDD en especificaciones: Mockito

  • Las especificaciones tienen tablas de datos que permiten agrupar muchos ejemplos pequeños en una especie de tabla (si puede soportar que los operadores se usen como delimitadores de tabla)

  • En las especificaciones, puede definir ejemplos que están anidados como libidum y se limpian automáticamente en cada nivel

Esta es ciertamente una comparación parcial y parcial y existen muchas otras diferencias (y las bibliotecas todavía están evolucionando, ...).

Al final del día, creo que realmente depende de su estilo de prueba / especificación. Si es simple (estructura de especificación simple, configuraciones, expectativas, ...), ambas bibliotecas aparecerán muy similares. De lo contrario, ambos tienen su opinión sobre cómo deben hacerse las cosas. Como último ejemplo de esto, puede echar un vistazo al etiquetado: en ScalaTest y en las especificaciones .

Espero que esto ayude.

Eric
fuente
¿Sería posible actualizar esto para cubrir las especificaciones2? :)
Joffer
5

Hasta donde yo sé, salvo algunas características altamente especializadas, se trata de preferencias personales según el estilo.

Daniel C. Sobral
fuente
2

El soporte IDE puede ser otro punto

He estado tratando de hacer que las especificaciones funcionen con Eclipse a través de JUnit, y encontré que la solución oficial es un poco "hacky". Configuración de especificaciones: http://code.google.com/p/specs/wiki/RunningSpecs#Run_your_specification_with_JUnit4_in_Eclipse

La integración de ScalaTest (también a través de JUnit) parece un poco menos hacky. Aún así, no tengo ninguno de ellos para trabajar tan bien como JUnit y Java.

Configuración de ScalaTest: http://groups.google.com/group/scalatest-users/web/running-scalatest-from-eclipse

Grav
fuente
Ahora obtengo un 404 para ese enlace ScalaTest. Pruebe scalatest.org/user_guide/using_junit_runner
ADN
0

Si un factor de decisión es el tiempo de compilación, scalatest parece funcionar mejor.

Actualmente estamos utilizando especificaciones2 en nuestro proyecto, pero sufrimos tiempos de compilación lentos en las pruebas. Acabo de terminar un POC al pasar a scalatest y vi que los tiempos de compilación disminuyeron en un factor de aproximadamente 0.82 con solo cambiar los 2 marcos en algunas de nuestras fuentes.

sebi
fuente