unit testing - how - ¿Cuál es la diferencia entre los marcos de prueba de unidades ScalaTest y Scala Specs?
sbt command (6)
El soporte de IDE puede ser otro punto
He intentado hacer que Specs funcione con Eclipse a través de JUnit, y encontré que la solución oficial es un poco "hacky". Configuración de las 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
Hasta donde yo sé, salvo algunas características altamente especializadas, se trata de preferencias personales según el estilo.
Las principales diferencias entre ScalaTest y Specs2 son:
- La estructura general de la prueba en Specs2 es diferente a la de ScalaTest.
- Specs2 tiene un conjunto diferente de Matchers con diferente sintaxis.
- Las pruebas de Specs2 están principalmente dedicadas al desarrollo impulsado por el comportamiento (BDD) , mientras que las pruebas de ScalaTest son más genéricas.
- ScalaTest ofrece muchas más opciones y versatilidad. Por ejemplo, para escribir especificaciones similares a BDD2 en ScalaTest, se pueden usar especificaciones Spec , FeatureSpec , WordSpec , FlatSpec y GivenWhenThen junto con ShouldMatchers o MustMatcher . Esto le da al desarrollador más flexibilidad para seguir su propio estilo de especificaciones de escritura.
Specs2 tiene un número significativamente mayor de Matchers que ScalaTest. La mayoría de ellos son para una necesidad particular. Por ejemplo, en Specs2, puedes decir:
un archivo debe ser un directorio
Cuando Specs2 tiene Matchers individuales para java.io.Files , ScalaTest no tiene Matchers similares.
Otra diferencia entre ScalaTest y Spec es la conversión implícita. ScalaTest solo tiene una conversión implícita, que logramos utilizando el operador === . Sin embargo, esto se puede desactivar en ScalaTest usando una sola línea de código. Esta es la única conversión implícita que se obtiene de forma gratuita en ScalaTest. Hay otras conversiones implícitas, que se pueden usar mezclando otros rasgos. Contrariamente a esto, Specs2 le da docenas de conversiones implícitas simplemente extendiendo la clase de especificación . En la práctica, esto no hace mucha diferencia. La única diferencia sería que el código de prueba sería más legible sin conversiones explícitas.
Specs2 tiene tablas de datos. Esto permite el uso de varios ejemplos, que pueden conducir la prueba, al igual que las pruebas basadas en propiedades.
Las pruebas de Specs2 difieren de ScalaTest, ya que se pueden ejecutar simultáneamente en una secuencia separada.
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 http://www.scalatest.org/quick_start para obtener una vista detallada de cada estilo)
ScalaTest y las especificaciones tienen un conjunto diferente de emparejamientos. Puede compararlos here para ScalaTest y here para las especificaciones. Por el 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 los matchers transformándolos), fallas precisas, diferencias detalladas para cadenas largas, ... .
A Mockito se le ha dado un buen soporte BDD en las especificaciones: Mockito
las especificaciones tienen DataTables que permiten agrupar un montón de pequeños ejemplos en una especie de tabla (si puede soportar que los operadores se usen como delimitadores de tablas)
En las especificaciones, puede definir ejemplos que están anidados como libidum y se limpian automáticamente en todos los niveles
Esta es ciertamente una comparación muy parcial y parcial y existen muchas otras diferencias (y las bibliotecas aún están evolucionando, ...).
Al final del día, creo que realmente depende de tu estilo de prueba / especificación. Si es simple (estructura de especificación simple, configuraciones, expectativas, ...) entonces 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, puedes echarle un vistazo al etiquetado: en ScalaTest y en las specs .
Espero que esto ayude.
Si un factor de decisión es el tiempo de compilación, Scalatest parece funcionar mejor.
Actualmente estamos usando specs2 en nuestro proyecto, pero sufrimos tiempos de compilación lentos en las pruebas. Acabo de terminar un POC al mudarme a Scalatest y vi que los tiempos de compilación disminuyen en un factor de aproximadamente 0.82 simplemente al cambiar los 2 frameworks en algunas de nuestras fuentes.
Las especificaciones y ScalaTest son buenas herramientas para usuarios satisfechos, pero difieren en varios aspectos. Es probable que desee elegir uno como su herramienta de prueba principal en Scala, pero no necesita renunciar a la otra porque puede usar piezas de ambos. Si le gusta la sintaxis y la sintaxis de Mockito de FeatureSpec
ScalaTest, 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 el Desarrollo Dirigido por Comportamiento (BDD), mientras que ScalaTest es más general. ScalaTest proporciona características que puede combinar para obtener el comportamiento que prefiera en sus clases de prueba, incluido BDD, y también puede definir fácilmente su propio comportamiento si desea algo diferente.
ScalaTest es compatible con BDD a través de sus características Spec
, FeatureSpec
, WordSpec
, FlatSpec
y GivenWhenThen
, y también tiene características que puede combinar para obtener una buena sintaxis de matcher. Si le gusta "debería", mezcle ShouldMatchers. Si te gusta "must", puedes mezclar MustMatchers
. Pero si le gusta BDD pero no le gusta la sintaxis de matcher, puede usar uno de los rasgos de Spec de ScalaTest sin mezclar en un rasgo de matcher. Specs tiene una clase de especificación que extiendes, y debes usar la palabra "must" en tus expresiones de matcher. Una gran diferencia filosófica que es evidente aquí es que ScalaTest te brinda muchas más opciones. Para 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 del emparejador también es diferente entre ScalaTest y las especificaciones. En ScalaTest traté de ver hasta dónde podía llegar con la notación del operador, y terminé con expresiones de matcher que se parecen mucho a las oraciones en inglés, con espacios entre las palabras. La sintaxis del mezclador de Specs ejecuta palabras juntas más con camel case.
SpecsTest tiene más coincidencias que ScalaTest, y eso creo que refleja una diferencia en la actitud de diseño. En realidad, corté probablemente 2/3 de la sintaxis del emparejador que construí y consideré para su lanzamiento. Agregaré más marcadores en versiones futuras, pero quería asegurarme de que sabía que los usuarios realmente querían algo antes de que lo agregara. Sin embargo, los adaptadores de ScalaTest incluyen una sintaxis de emparejador de propiedad dinámica que absorbe parte de esa holgura. Por ejemplo, en Specs puedes escribir en un java.io.File
:
file must beDirectory
Esto invocará el isDirectory
y se asegurará de que sea verdadero. ScalaTest no tiene ningún mezclador especial para java.io.Files
actualmente, pero en ScalaTest, puedes usar un cheque dinámico como este:
file must be a (''directory)
Cada vez que pase un símbolo después de " be
, usará "reflection" 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 que esto sea estático, al definir un BePropertyMatcher
(que BePropertyMatcher
requiere solo 2 o 3 líneas de código). Básicamente, en ScalaTest intento proporcionar más funcionalidades 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 el que pone el operador ===
en todo. (Si es necesario, puede "desactivar" esta conversión implícita con una línea de código. La única razón por la que tendría que hacer eso es si estaba intentando probar algo que tiene su propio operador ===
, y obtiene un conflicto.) ScalaTest define muchas otras conversiones implícitas, pero para usarlas necesita explícitamente "invitarlas" a su código mezclando un rasgo o haciendo una importación. Cuando extiendes la Specification
clase en las especificaciones, creo que obtienes casi docenas de conversiones implícitas por defecto. No estoy seguro de cuánto importará en la práctica, pero creo que las personas querrán probar el código que usa sus propias implicaciones, y en ocasiones puede haber un conflicto entre las implicaciones del marco de prueba y las del código de producción. Cuando eso sucede, 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 he notado es la comodidad con los operadores. Uno de mis objetivos era que cualquier programador que examinara el código de prueba de otra persona que utilizara ScalaTest pudiera adivinar su significado sin buscar nada en la documentación de ScalaTest. Quería que el código del cliente de ScalaTest fuera obvio. Una forma en que esa meta se manifestó es que ScalaTest es muy conservador con respecto a los operadores. Solo defino cinco operadores en ScalaTest:
-
===
, lo que significa igual -
>
, lo que significa más que -
<
, menos que -
>=
, mayor que o igual -
<=
, menor que o igual.
Eso es. Así que estas cosas se parecen mucho a lo que significa. Si ve en el código de otra persona:
result should be <= 7
Espero que no necesites acceder a la documentación de la API para adivinar qué significa eso <=
. Por el contrario, las especificaciones son mucho más libres con los operadores. No hay nada de malo en eso, pero es una diferencia. Los operadores pueden hacer que el código sea más conciso, pero es posible que deba ejecutar la documentación cuando encuentre cosas como ->-
, >>
, |
, |>
!
o ^^^
(que tienen significados especiales en las especificaciones) en el código de prueba de su colega.
Otra diferencia filosófica es que intento y hago que sea más fácil en ScalaTest usar un estilo funcional cuando necesitas compartir un dispositivo, mientras que Specs por defecto continúa con la tradición del setUp
y tearDown
popularizado por JUnit, en el que reasignación de vars antes de cada prueba. Sin embargo, si quiere hacer la prueba de esa manera, también es muy fácil en ScalaTest. Solo necesita mezclar el rasgo BeforeAndAfter
.
Para obtener más información sobre ScalaTest, puede ver la presentación "Get Higher with ScalaTest" que di en la conferencia 2009 Devoxx aquí:
http://parleys.com/play/514892260364bc17fc56bde3/chapter0/about