2010-09-17 9 views
37

A Rieles/herramienta de versión específica de: How deep are your unit tests?BDD con pepino y rspec: ¿cuándo es esto redundante?

En este momento, actualmente escribo:

  • características pepino (pruebas de integración) - estas pruebas en contra del HTML/JS que se devuelve por nuestra aplicación, pero a veces también prueba otras cosas, como llamadas a servicios de terceros.
  • Pruebas del controlador de RSpec (pruebas funcionales), originalmente solo si los controladores tienen alguna lógica significativa, pero ahora cada vez más.
  • pruebas RSpec modelo (pruebas de unidad)

veces esto es del todo necesario; es necesario probar el comportamiento en el modelo que no es completamente obvio ni visible para el usuario final. Cuando los modelos son complejos, definitivamente deben probarse. Pero otras veces, me parece que las pruebas son redundantes. Por ejemplo, ¿prueba el método foo si solo se llama por bar, y se prueba bar? ¿Qué pasa si bar es un método de ayuda simple en un modelo que se usa y se puede probar fácilmente en una función de pepino? ¿Probas el método en rspec y en Cucumber? Me resulta difícil lidiar con esto, ya que escribir más pruebas lleva tiempo y mantener múltiples "versiones" de lo que efectivamente son los mismos comportamientos, lo que hace que el mantenimiento del conjunto de pruebas requiera más tiempo, lo que a su vez encarece los cambios.

En resumen, ¿cree que hay un momento en que escribir solo las características de Cucumber es suficiente? ¿O debería probar siempre en todos los niveles? Si cree que hay un área gris, ¿cuál es su umbral para "esto necesita una prueba funcional/unidad"? En términos prácticos, ¿qué haces actualmente y por qué (o por qué no) crees que es suficiente?


EDITAR: Here's an example of what might be "test overkill." Es cierto, yo era capaz de escribir esto con bastante rapidez, pero era completamente hipotético.

+0

estado luchando con * exactamente * el mismo problema. Administrar la relación tiempo/beneficio es difícil de hacer a veces. – brad

+0

También tengo curiosidad sobre esto. Solo estoy tratando de averiguar cuántas pruebas de controlador/vista son realmente necesarias si tengo una capa de pruebas de cukes ejecutándose a través de mi aplicación. – wesgarrison

Respuesta

27

Buena pregunta, una que he tratado recientemente mientras trabajaba en una aplicación de Rails, también usando Cucumber/RSpec.Intento probar tanto como sea posible en todos los niveles, sin embargo, también he descubierto que a medida que crece la base de código, a veces siento que me repito innecesariamente.

Utilizando la prueba "Outside-in", mi proceso suele ser algo así como: Escenario de pepino -> Especificación de controlador -> Espec. De modelo. Cada vez me encuentro más omitiendo las especificaciones del controlador ya que los escenarios de pepino cubren gran parte de su funcionalidad. Normalmente vuelvo y agrego las especificaciones del controlador, pero puede parecer un poco pesado.

Un paso que tomo regularmente es ejecutar rcov en mis características de pepino con rake cucumber:rcov y buscar huecos notables en la cobertura. Estas son áreas del código en las que me aseguro de centrarme para que tengan una cobertura decente, ya sea de unidades o de integración.

Creo que los modelos/libs deben probarse en una unidad de forma exhaustiva, desde el principio, ya que es la lógica empresarial principal. Necesita trabajar en forma aislada, fuera del proceso de solicitud/respuesta web normal. Por ejemplo, si estoy interactuando con mi aplicación a través de la consola de Rails, estoy trabajando directamente con la lógica de negocios y quiero la seguridad de que los métodos que invoco en mis modelos/clases están bien probados.

Al final del día, cada aplicación es diferente y creo que depende del desarrollador (s) determinar cuánta cobertura de prueba se debe dedicar a diferentes partes de la base de código y encontrar el equilibrio adecuado para que su prueba suite no te empantana a medida que crece tu aplicación.

He aquí un interesante artículo Desenterré de mis marcadores que vale la pena leer: http://webmozarts.com/2010/03/15/why-not-to-want-100-code-coverage/

+0

Buen enlace + no sabía sobre 'rake pepino: rcov'. Por curiosidad, ¿pruebas de manera unitaria todos los métodos de modelos, incluso cosas simples que tienen cobertura de pepino? (Vea mi ejemplo en la pregunta) ¿Considera que es esencial hasta el punto en el que no considerará que el código está "terminado" (es decir, no se permite comprometerlo o fusionarse con el maestro) hasta que se pruebe en ese nivel? – wuputah

+0

Normalmente mi objetivo es la cobertura de prueba unitaria de la mayoría de los modelos/libs. Sin embargo, no siempre sucede, cuando estoy en pleno flujo, escribiendo código, a veces termino tomando atajos. Intento verificar regularmente las lagunas notables en la cobertura de mi prueba, ya sea de forma manual o con herramientas como rcov, y luego conecto esas lagunas. Y no me apego a una regla dura y rápida como no comprometer el código no probado en el nivel de la unidad. Los métodos booleanos simples, como en su ejemplo, no me preocuparían si no tuvieran una cobertura de prueba unitaria, sino métodos con algún tipo de complejidad que trato de probar. – Sidane

0

Pruebo modelos complejos/lib métodos con rspec entonces la lógica de negocio principal en web con pepino, así que estoy seguro de que las características principales de la web funcionarán al 100%, entonces si tengo más tiempo y recursos pruebo todo lo demas.

+0

Tengo los mismos sentimientos, pero me gustaría saber más sobre su enfoque. ¿Cómo convencerías a los demás de que esta es la forma correcta de hacerlo? – wuputah

+0

La razón principal por la que lo hago es porque no puedo probarlo todo, así que debo priorizar y probar de más importante a menos. Para cubrir más de la página web, sugiero crear especificaciones simples para todos los modelos para ver si todo guarda/valida, luego las especificaciones para todos los métodos complejos y, por último, pepino para todas las formas, vistas principales. Y luego, si tiene más tiempo/recursos puede probar cosas no tan importantes. – Gacha

2

Rails tiene una base de código bien probada, así que evitaría volver a probar las cosas que se cubren en esos pasos.

Por ejemplo, a menos que sea un código personalizado, no tiene sentido probar los resultados de las validaciones en unidades y niveles funcionales. Sin embargo, los probaría en el nivel de integración. Las características de pepino actúan como especificaciones para su proyecto, por lo que es bueno especificar que necesita una validación para xey, incluso si la implementación es una declaración de línea única en el modelo.

+0

Sí, pero: si bien es fácil con Shoulda para probar las validaciones en rspec, ¿cree que debería probar las validaciones tanto en Cucumber como en rspec? El punto no es que las cosas se deberían probar o no, sino si las cosas deberían probarse en múltiples niveles. Las validaciones no son exactamente lo que estaba pensando (sobre todo porque Shoulda lo hace tan fácil), pero es un ejemplo razonable. ¡Imagina que tienes que escribir esas pruebas de rspec a mano! – wuputah

+2

Para decirlo de otra manera, lo que quise decir es que debes probar tu código original en todos los niveles, y probar todo en el nivel superior. Considere las devoluciones de llamadas del ciclo de vida de ActiveRecord, por ejemplo. No necesita preocuparse si las devoluciones de llamada son guardadas. Debe preocuparse si el resultado que espera de esa devolución de llamada está en el registro o no. – edgerunner

0

Es más fácil escribir especificaciones simples para métodos simples. Es mucho más fácil que escribir cukes.

Si mantiene sus métodos simples y mantiene sus especificaciones simples, al probar solo la lógica dentro de ese método, encontrará alegría en las pruebas de unidad.

Si algo es redundante, prueba el pepino. Si ha probado modelos y lib, su software debería funcionar.

+3

Hasta que se dé cuenta de que olvidó poner un botón de enviar en su formulario y no puede obtener desde A -> B en su aplicación. Los métodos en cuestión pueden funcionar de forma aislada y todas las pruebas de su unidad pasan, pero cuando se utilizan en una situación real, su aplicación no funcionará. Las pruebas de integración son tan importantes como las pruebas unitarias y no deben considerarse redundantes. – Sidane

+0

Sí, esa es una perspectiva. – Vojto

+0

La pregunta es, hasta cierto punto, subjetiva, y una sobre las mejores prácticas.Definitivamente entiendo la idea de que las pruebas de integración pueden parecer redundantes si tienes buenas pruebas compartimentadas. Principalmente provengo del otro ángulo, que existen pruebas de integración dadas, el resto puede parecer redundante a veces. Personalmente creo que este es un mejor enfoque ya que, como señala Sidane, puede perderse el "panorama general" si no tiene pruebas de integración. Creo que ambas opiniones tienen mérito, sin embargo. – wuputah

0

lo general, no quieren tener ambas historias del pepino y las especificaciones del controlador RSpec/pruebas de integración. Escoja uno (generalmente Pepino es la mejor opción, excepto en ciertos casos especiales). Luego usa RSpec para tus modelos, y eso es todo lo que necesitas.