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 FeatureSpec
sintaxis 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 GivenWhenThen
rasgos, 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á isDirectory
y se asegurará de que sea cierto. ScalaTest no tiene coincidencias especiales para la java.io.Files
actualidad, 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 directory
o 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 claseSpecification
en 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 setUp
y el tearDown
enfoque 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 BeforeAndAfter
rasgo.
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