Pregunta

¿Alguien sabe dónde encontrar pautas y recomendaciones de pruebas unitarias?Me gustaría tener algo que aborde los siguientes tipos de temas (por ejemplo):

  • ¿Deberían las pruebas estar en el mismo proyecto que la lógica de la aplicación?
  • ¿Debería tener clases de prueba para reflejar mis clases de lógica o debería tener sólo tantas clases de prueba como creo que necesito?
  • ¿Cómo debo nombrar mis clases, métodos y proyectos de prueba (si van en proyectos diferentes)?
  • ¿Deberían probarse los métodos privados, protegidos e internos, o sólo aquellos que son de acceso público?
  • ¿Deberían separarse las pruebas unitarias y de integración?
  • Hay una bien ¿Por qué no tener una cobertura de prueba del 100%?

¿Qué no estoy preguntando para que debería estarlo?

Lo mejor sería un recurso en línea.

¿Fue útil?

Solución

yo recomendaria Kent Beck's libro sobre TDD.

Además, debes ir a Martín Fowler sitio.También tiene mucha buena información sobre las pruebas.

Somos bastante importantes en TDD, por lo que responderé las preguntas desde ese punto de vista.

¿Deberían las pruebas estar en el mismo proyecto que la lógica de la aplicación?

Por lo general, mantenemos nuestras pruebas en la misma solución, pero dividimos las pruebas en DLL/Proyectos separados que reflejan los DLL/Proyectos que están probando, pero mantenemos espacios de nombres con las pruebas en un subespacio de nombres.Ejemplo:Pruebas comunes / comunes

¿Debería tener clases de prueba para reflejar mis clases de lógica o debería tener sólo tantas clases de prueba como creo que necesito?

Sí, sus pruebas deben crearse antes de crear cualquier clase y, por definición, solo debe probar una única unidad de forma aislada.Por lo tanto, debes tener una clase de prueba para cada clase de tu solución.

¿Cómo debo nombrar mis clases, métodos y proyectos de prueba (si van en proyectos diferentes)?

Me gusta enfatizar que el comportamiento es lo que se está probando, por lo que normalmente nombro las clases de prueba con el nombre del SUT.Por ejemplo, si tuviera una clase de Usuario, nombraría la clase de prueba así:

public class UserBehavior

Los métodos deben nombrarse para describir el comportamiento esperado.

public void ShouldBeAbleToSetUserFirstName()

Los proyectos pueden tener el nombre que desee, pero normalmente desea que sea bastante obvio qué proyecto se está probando.Ver respuesta anterior sobre organización de proyectos.

¿Deberían probarse los métodos privados, protegidos e internos, o sólo aquellos que son de acceso público?

Nuevamente, desea que las pruebas afirmen el comportamiento esperado como si fuera un consumidor externo de los objetos que se están probando.Si prueba los detalles de la implementación interna, sus pruebas serán frágiles.Quiere que su prueba le brinde la libertad de refactorizar sin preocuparse por romper la funcionalidad existente.Si su prueba conoce los detalles de implementación, tendrá que cambiar sus pruebas si esos detalles cambian.

¿Deberían separarse las pruebas unitarias y de integración?

Sí, las pruebas unitarias deben aislarse de las pruebas de aceptación e integración.La separación de preocupaciones también se aplica a las pruebas.

¿Existe una buena razón para no tener una cobertura de prueba del 100%?

No me obsesionaría con el tema de la cobertura del código al 100%.Una cobertura del código del 100% tiende a implicar cierto nivel de calidad en las pruebas, pero eso es un mito.Puedes tener pruebas terribles y aun así obtener una cobertura del 100%.En cambio, confiaría en una buena mentalidad de Test First.Si siempre escribe una prueba antes de escribir una línea de código, garantizará una cobertura del 100% para que se convierta en un punto discutible.

En general, si se concentra en describir todo el alcance conductual de la clase, no tendrá nada de qué preocuparse.Si convierte la cobertura del código en una métrica, los programadores perezosos simplemente harán lo suficiente para alcanzar esa marca y aún tendrá pruebas deficientes.En lugar de eso, confíe en gran medida en revisiones por pares donde también se revisan las pruebas.

Otros consejos

Es una buena pregunta.Cultivamos el nuestro de forma orgánica y sospecho que la mejor manera es precisamente esa.Hay un poco de "Depende..." ahí.

Realizamos pruebas en el mismo proyecto, en un subespacio de nombres llamado "UnitTes".

Nuestras clases de prueba reflejan la clase lógica, para simplificar el seguimiento de dónde están las pruebas en relación con lo que están probando.

Las clases reciben nombres como la clase lógica que están probando, los métodos reciben nombres según el escenario que están probando.

Solo escribimos pruebas para métodos públicos e internos (las pruebas están en el mismo proyecto) y apuntamos a una cobertura del 95% de la clase.

Prefiero no distinguir entre "unidad" e "intergación".Se gastará mucho tiempo tratando de descubrir cuál es cuál... ¡embolsa eso!Una prueba es una prueba.

El 100% es demasiado difícil de lograr todo el tiempo.Nuestro objetivo es el 95%.También hay rendimientos decrecientes sobre cuánto tiempo llevará obtener ese 5% final y lo que realmente se obtendrá.

Esos somos nosotros y lo que se adaptaba al entorno y al ritmo.Su kilometraje puede variar.Piense en su entorno y en las personalidades involucradas.

¡Espero ver lo que otros tienen que decir sobre este!

La respuesta de Josh es correcta, solo un punto de aclaración:

La razón por la que separo las pruebas unitarias de las pruebas de integración y aceptación es la velocidad.Yo uso TDD.Necesito comentarios casi instantáneos sobre la línea de código que acabo de crear/modificar.No puedo conseguirlo si estoy ejecutando conjuntos completos de pruebas de integración y/o aceptación: pruebas que afectan a discos reales, redes reales y sistemas externos realmente lentos e impredecibles.

No cruces las vigas.Sucederán cosas malas si lo haces.

Te recomiendo insistentemente que leas Desarrollo basado en pruebas:Por ejemplo y Desarrollo basado en pruebas:Una guía práctica Son demasiadas preguntas para un solo tema.

Con respecto a su última pregunta, en mi experiencia, la "buena" razón para no insistir en una cobertura de prueba del 100% es que se necesita una cantidad desproporcionada de esfuerzo para obtener los últimos puntos porcentuales, particularmente en bases de código más grandes.Como tal, es cuestión de decidir si vale la pena dedicarle tiempo o no una vez que llegue a ese punto de rendimientos decrecientes.

En orden:

  • No, normalmente es mejor incluirlos en un proyecto independiente;a menos que desee poder ejecutar diagnósticos en tiempo de ejecución.
  • Lo ideal es una cobertura de código del 100 %, lo que significa cada línea de código en cada rutina de cada clase.
  • Voy con ClassnameTest, ClassnameTest.MethodNameTestnumber
  • Todo.
  • Yo diría que sí, ya que no es necesario ejecutar pruebas de integración si las pruebas unitarias fallan.
  • No es necesario probar las propiedades simples que simplemente configuran y obtienen un campo.

¿Deberían las pruebas estar en el mismo proyecto que la lógica de la aplicación?

Eso depende.Hay compensaciones en ambos sentidos.

Mantenerlo en un proyecto requiere ancho de banda adicional para distribuir su proyecto, tiempo de compilación adicional y aumenta el espacio de instalación, y hace que sea más fácil cometer el error de tener una lógica de producción que depende del código de prueba.

Por otro lado, mantener proyectos separados puede dificultar la escritura de pruebas que involucren métodos/clases privadas (dependiendo del lenguaje de programación) y causa problemas administrativos menores, como dificultar la configuración de un nuevo entorno de desarrollo (p. ej.cuando un nuevo desarrollador se une al proyecto) más difícil.

La importancia de estos diferentes costos varía según el proyecto, por lo que no existe una respuesta universal.

¿Debería tener clases de prueba para reflejar mis clases de lógica o debería tener sólo tantas clases de prueba como creo que necesito?

No.

Debería tener clases de prueba que permitan un código de prueba bien factorizado (es decir,duplicación mínima, intención clara, etc.).

La ventaja obvia de reflejar directamente las clases lógicas en sus clases de prueba es que facilita encontrar las pruebas correspondientes a un fragmento de código en particular.Hay otras formas de resolver este problema sin restringir la flexibilidad del código de prueba.Generalmente son suficientes convenciones de nomenclatura simples para módulos y clases de prueba.

¿Cómo debo nombrar mis clases, métodos y proyectos de prueba (si van en proyectos diferentes)?

Debes nombrarlos de modo que:

  • cada clase de prueba y método de prueba tiene un propósito claro, y
  • para que alguien que busque una prueba en particular (o pruebas sobre una unidad en particular) pueda encontrarla fácilmente.

¿Deberían probarse los métodos privados, protegidos e internos, o sólo aquellos que son de acceso público?

A menudo se deben probar métodos no públicos.Depende de si obtiene suficiente confianza simplemente probando la interfaz pública o si la unidad que realmente desea probar no es accesible públicamente.

¿Deberían separarse las pruebas unitarias y de integración?

Esto depende de su elección de marcos de prueba.Haga lo que funcione mejor con su(s) marco(s) de prueba y haga que:

  • Tanto las pruebas unitarias como las de integración relacionadas con un fragmento de código son fáciles de encontrar,
  • es fácil ejecutar solo las pruebas unitarias,
  • es fácil ejecutar solo las pruebas de integración,
  • es fácil ejecutar todas las pruebas.

¿Existe una buena razón para no tener una cobertura de prueba del 100%?

Sí, hay una buena razón.Estrictamente hablando, "cobertura de prueba del 100%" significa que se ejercitan y prueban todas las situaciones posibles en su código.Esto es simplemente poco práctico de lograr para casi cualquier proyecto.

Si simplemente considera que “cobertura de prueba del 100%” significa que cada línea de código fuente es ejercida por el conjunto de pruebas en algún momento, entonces este es un buen objetivo, pero a veces hay solo un par de líneas en lugares incómodos que son difíciles. llegar con pruebas automatizadas.Si el costo de verificar manualmente esa funcionalidad periódicamente es menor que el costo de realizar contorsiones para llegar a esas últimas cinco líneas, entonces esa es una buena razón para no tener una cobertura de línea del 100%.

En lugar de una simple regla de que debes tener una cobertura de línea del 100%, anima a tus desarrolladores a descubrir cualquier brechas en sus pruebas y encuentre formas de solucionar esas brechas, ya sea que mejore la cantidad de líneas "cubiertas".En otras palabras, si mide las líneas cubiertas, mejorará su cobertura de líneas, pero lo que realmente desea es una mejor calidad.Así que no olvide que la cobertura de líneas es sólo una aproximación muy burda de la calidad.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top