Pruebas unitarias

Validación del comportamiento del código fuente aislado

Las pruebas unitarias , también conocidas como pruebas de componentes o módulos , son una forma de prueba de software mediante la cual se prueba un código fuente aislado para validar el comportamiento esperado. [1]

Las pruebas unitarias describen las pruebas que se ejecutan a nivel de unidad para contrastar las pruebas a nivel de integración o de sistema .

Historia

Las pruebas unitarias, como principio para probar por separado partes más pequeñas de sistemas de software grandes, se remontan a los primeros días de la ingeniería de software. En junio de 1956, HD Benington presentó en el Simposio de la Marina de los EE. UU. sobre métodos avanzados de programación para computadoras digitales el proyecto SAGE y su enfoque basado en especificaciones, donde la fase de codificación era seguida por una "prueba de parámetros" para validar los subprogramas de los componentes en relación con su especificación, seguida luego por una "prueba de ensamblaje" para las partes ensambladas. [2] [3]

En 1964, se describe un enfoque similar para el software del proyecto Mercury , donde las unidades individuales desarrolladas por diferentes programas se sometieron a "pruebas unitarias" antes de integrarse entre sí. [4] En 1969, las metodologías de prueba aparecen más estructuradas, con pruebas unitarias, pruebas de componentes y pruebas de integración con el propósito de validar partes individuales escritas por separado y su ensamblaje progresivo en bloques más grandes. [5] Algunas normas públicas adoptadas a finales de los años 60, como MIL-STD-483 [6] y MIL-STD-490 contribuyeron aún más a una amplia aceptación de las pruebas unitarias en proyectos de gran tamaño.

En aquella época, las pruebas unitarias eran interactivas [3] o automatizadas [7], y se utilizaban pruebas codificadas o herramientas de prueba de captura y reproducción . En 1989, Kent Beck describió un marco de pruebas para Smalltalk (posteriormente llamado SUnit ) en "Simple Smalltalk Testing: With Patterns". En 1997, Kent Beck y Erich Gamma desarrollaron y lanzaron JUnit , un marco de pruebas unitarias que se hizo popular entre los desarrolladores de Java . [8] Google adoptó las pruebas automatizadas alrededor de 2005-2006. [9]

Unidad

La unidad se define como un comportamiento único exhibido por el sistema bajo prueba (SUT), que generalmente corresponde a un requisito. Si bien puede implicar que se trata de una función o un módulo (en programación procedimental ) o un método o una clase (en programación orientada a objetos ), no significa que las funciones/métodos, módulos o clases siempre correspondan a unidades. Desde la perspectiva de los requisitos del sistema, solo el perímetro del sistema es relevante, por lo tanto, solo los puntos de entrada a los comportamientos del sistema visibles externamente definen unidades. [10]

Ejecución

Las pruebas unitarias se pueden realizar de forma manual o mediante la ejecución automática de pruebas . Las pruebas automáticas incluyen ventajas como: ejecución frecuente de pruebas, ejecución sin costos de personal y pruebas consistentes y repetibles.

Las pruebas suelen ser realizadas por el programador que escribe y modifica el código que se está probando. Las pruebas unitarias pueden considerarse parte del proceso de escritura del código.

Criterios de prueba

Durante el desarrollo, un programador puede codificar criterios o resultados que se sabe que son buenos en la prueba para verificar la corrección de la unidad.

Durante la ejecución de las pruebas, los marcos registran las pruebas que no cumplen algún criterio y las informan en un resumen.

Para ello, el enfoque más utilizado es prueba-función-valor esperado.

Caso de prueba

En ingeniería de software , un caso de prueba es una especificación de las entradas, condiciones de ejecución, procedimiento de prueba y resultados esperados que definen una sola prueba que se ejecutará para lograr un objetivo de prueba de software particular , como para ejercitar una ruta de programa particular o para verificar el cumplimiento de un requisito específico. [11] Los casos de prueba son la base de las pruebas que son metódicas en lugar de aleatorias. Se puede construir una batería de casos de prueba para producir la cobertura deseada del software que se está probando. Los casos de prueba definidos formalmente permiten que las mismas pruebas se ejecuten repetidamente contra versiones sucesivas del software, lo que permite una prueba de regresión efectiva y consistente . [12]

Prueba doble

Un test double es un software utilizado en la automatización de pruebas de software que satisface una dependencia de modo que la prueba no necesita depender del código de producción. Un test double proporciona funcionalidad a través de una interfaz que el software bajo prueba no puede distinguir del código de producción.

Prueba parametrizada

Una prueba parametrizada es una prueba que acepta un conjunto de valores que se pueden usar para permitir que la prueba se ejecute con varios valores de entrada diferentes. Un marco de prueba que admita pruebas parametrizadas admite una forma de codificar conjuntos de parámetros y ejecutar la prueba con cada conjunto.

El uso de pruebas parametrizadas puede reducir la duplicación del código de prueba.

Las pruebas parametrizadas son compatibles con TestNG , JUnit , [13] XUnit y NUnit , así como con varios marcos de prueba de JavaScript. [ cita requerida ]

Los parámetros para las pruebas unitarias pueden codificarse manualmente o, en algunos casos, generarse automáticamente mediante el marco de pruebas. En los últimos años, se agregó soporte para escribir pruebas (unitarias) más potentes, aprovechando el concepto de teorías, casos de prueba que ejecutan los mismos pasos, pero utilizando datos de prueba generados en tiempo de ejecución, a diferencia de las pruebas parametrizadas regulares que utilizan los mismos pasos de ejecución con conjuntos de entrada que están predefinidos. [ cita requerida ]

Ágil

A veces, en el desarrollo ágil de software, las pruebas unitarias se realizan por historia de usuario y se realizan en la segunda mitad del sprint, una vez que se completan la recopilación de requisitos y el desarrollo. Normalmente, los desarrolladores u otros miembros del equipo de desarrollo, como los consultores , escriben "scripts de prueba" paso a paso para que los desarrolladores los ejecuten en la herramienta. Los scripts de prueba se escriben generalmente para demostrar el funcionamiento eficaz y técnico de características desarrolladas específicas en la herramienta, a diferencia de los procesos comerciales completos que serían interconectados por el usuario final , lo que generalmente se hace durante las pruebas de aceptación del usuario . Si el script de prueba se puede ejecutar completamente de principio a fin sin incidentes, se considera que la prueba unitaria ha "pasado", de lo contrario, se anotan los errores y la historia de usuario se devuelve al desarrollo en un estado "en curso". Las historias de usuario que pasan con éxito las pruebas unitarias pasan a los pasos finales del sprint: revisión de código, revisión por pares y, por último, una sesión de "presentación" que demuestra la herramienta desarrollada a las partes interesadas.

Desarrollo basado en pruebas

En el desarrollo basado en pruebas (TDD), las pruebas unitarias se escriben mientras se escribe el código de producción. A partir del código funcional, el desarrollador agrega el código de prueba para un comportamiento requerido, luego agrega el código suficiente para que la prueba pase, luego refactoriza el código (incluido el código de prueba) según tenga sentido y luego repite agregando otra prueba.

Valor

Las pruebas unitarias tienen como objetivo garantizar que las unidades cumplan con su diseño y se comporten según lo previsto. [14]

Al escribir pruebas primero para las unidades comprobables más pequeñas y luego para los comportamientos compuestos entre ellas, se pueden crear pruebas integrales para aplicaciones complejas. [14]

Uno de los objetivos de las pruebas unitarias es aislar cada parte del programa y demostrar que cada una de ellas es correcta. [1] Una prueba unitaria proporciona un contrato escrito estricto que el fragmento de código debe satisfacer.

Detección temprana de problemas en el ciclo de desarrollo

Las pruebas unitarias detectan problemas en las primeras fases del ciclo de desarrollo . Esto incluye tanto errores en la implementación del programador como fallas o partes faltantes de la especificación de la unidad. El proceso de escribir un conjunto completo de pruebas obliga al autor a pensar en las entradas, salidas y condiciones de error y, por lo tanto, a definir con mayor precisión el comportamiento deseado de la unidad. [ cita requerida ]

Costo reducido

El costo de encontrar un error antes de comenzar a codificar o cuando el código se escribe por primera vez es considerablemente menor que el costo de detectar, identificar y corregir el error más tarde. Los errores en el código publicado también pueden causar problemas costosos para los usuarios finales del software. [15] [16] [17] El código puede ser imposible o difícil de probar unitariamente si está mal escrito, por lo que las pruebas unitarias pueden obligar a los desarrolladores a estructurar funciones y objetos de mejores maneras.

Lanzamientos más frecuentes

Las pruebas unitarias permiten lanzamientos más frecuentes en el desarrollo de software. Al probar componentes individuales de forma aislada, los desarrolladores pueden identificar y solucionar problemas rápidamente, lo que conduce a ciclos de iteración y lanzamiento más rápidos. [18]

Permite la refactorización de código

Las pruebas unitarias permiten al programador refactorizar el código o actualizar las bibliotecas del sistema en una fecha posterior y asegurarse de que el módulo aún funciona correctamente (por ejemplo, en las pruebas de regresión ). El procedimiento consiste en escribir casos de prueba para todas las funciones y métodos de modo que, siempre que un cambio provoque una falla, se pueda identificar rápidamente.

Detecta cambios que pueden romper un contrato de diseño.

Las pruebas unitarias detectan cambios que pueden romper un contrato de diseño .

Reducir la incertidumbre

Las pruebas unitarias pueden reducir la incertidumbre en las propias unidades y pueden utilizarse con un enfoque de pruebas ascendente . Al probar primero las partes de un programa y luego la suma de sus partes, las pruebas de integración se vuelven mucho más fáciles. [ cita requerida ]

Documentación del comportamiento del sistema

Algunos programadores sostienen que las pruebas unitarias proporcionan una forma de documentación del código. Los desarrolladores que quieran saber qué funcionalidad proporciona una unidad y cómo utilizarla pueden revisar las pruebas unitarias para comprenderlas. [ cita requerida ]

Los casos de prueba pueden incorporar características que son fundamentales para el éxito de la unidad. Estas características pueden indicar el uso apropiado o inadecuado de una unidad, así como los comportamientos negativos que la unidad debe detectar. Un caso de prueba documenta estas características críticas, aunque muchos entornos de desarrollo de software no dependen únicamente del código para documentar el producto en desarrollo. [ cita requerida ]

En algunos procesos, el acto de escribir pruebas y el código bajo prueba, más la refactorización asociada, pueden reemplazar al diseño formal. Cada prueba unitaria puede verse como un elemento de diseño que especifica clases, métodos y comportamiento observable. [ cita requerida ]

Limitaciones y desventajas

Las pruebas no detectarán todos los errores del programa, porque no pueden evaluar cada ruta de ejecución en ningún programa, excepto en los más triviales. Este problema es un superconjunto del problema de detención , que es indecidible . Lo mismo es cierto para las pruebas unitarias. Además, las pruebas unitarias, por definición, solo prueban la funcionalidad de las unidades mismas. Por lo tanto, no detectarán errores de integración o errores más amplios a nivel de sistema (como funciones realizadas en varias unidades o áreas de prueba no funcionales como el rendimiento ). Las pruebas unitarias deben realizarse junto con otras actividades de prueba de software , ya que solo pueden mostrar la presencia o ausencia de errores particulares; no pueden probar una ausencia completa de errores. Para garantizar el comportamiento correcto para cada ruta de ejecución y cada entrada posible, y asegurar la ausencia de errores, se requieren otras técnicas, a saber, la aplicación de métodos formales para demostrar que un componente de software no tiene un comportamiento inesperado. [ cita requerida ]

Una jerarquía elaborada de pruebas unitarias no equivale a pruebas de integración. La integración con unidades periféricas debería incluirse en las pruebas de integración, pero no en las pruebas unitarias. [ cita requerida ] Las pruebas de integración generalmente todavía dependen en gran medida de que las personas realicen pruebas manuales ; las pruebas de alto nivel o de alcance global pueden ser difíciles de automatizar, de modo que las pruebas manuales a menudo parecen más rápidas y económicas. [ cita requerida ]

Las pruebas de software son un problema combinatorio. Por ejemplo, cada sentencia de decisión booleana requiere al menos dos pruebas: una con un resultado de "verdadero" y otra con un resultado de "falso". Como resultado, por cada línea de código escrita, los programadores a menudo necesitan de 3 a 5 líneas de código de prueba. [ cita requerida ] Obviamente, esto lleva tiempo y su inversión puede no valer la pena el esfuerzo. Hay problemas que no se pueden probar fácilmente en absoluto, por ejemplo, aquellos que no son deterministas o involucran múltiples subprocesos . Además, el código para una prueba unitaria tiene la misma probabilidad de tener errores que el código que está probando. Fred Brooks en The Mythical Man-Month cita: "Nunca te hagas a la mar con dos cronómetros; lleva uno o tres". [19] Es decir, si dos cronómetros se contradicen, ¿cómo sabes cuál es el correcto?

Dificultad para establecer pruebas realistas y útiles

Otro desafío relacionado con la escritura de pruebas unitarias es la dificultad de configurar pruebas realistas y útiles. Es necesario crear condiciones iniciales relevantes para que la parte de la aplicación que se está probando se comporte como parte del sistema completo. Si estas condiciones iniciales no se configuran correctamente, la prueba no estará ejercitando el código en un contexto realista, lo que disminuye el valor y la precisión de los resultados de las pruebas unitarias. [ cita requerida ]

Requiere disciplina durante todo el proceso de desarrollo.

Para obtener los beneficios previstos de las pruebas unitarias, se necesita una disciplina rigurosa durante todo el proceso de desarrollo de software.

Requiere control de versiones

Es esencial mantener registros detallados no sólo de las pruebas que se han realizado, sino también de todos los cambios que se han hecho al código fuente de esta o cualquier otra unidad del software. El uso de un sistema de control de versiones es esencial. Si una versión posterior de la unidad no pasa una prueba particular que había aprobado previamente, el software de control de versiones puede proporcionar una lista de los cambios del código fuente (si los hubiera) que se han aplicado a la unidad desde entonces. [ cita requerida ]

Requiere revisiones periódicas

También es esencial implementar un proceso sostenible para garantizar que las fallas de los casos de prueba se revisen regularmente y se aborden de inmediato. [20] Si dicho proceso no se implementa y se arraiga en el flujo de trabajo del equipo, la aplicación evolucionará fuera de sincronía con el conjunto de pruebas unitarias, lo que aumentará los falsos positivos y reducirá la efectividad del conjunto de pruebas.

Limitaciones del software de sistemas integrados

Las pruebas unitarias de software de sistemas integrados presentan un desafío único: debido a que el software se desarrolla en una plataforma diferente de aquella en la que finalmente se ejecutará, no se puede ejecutar fácilmente un programa de prueba en el entorno de implementación real, como es posible con los programas de escritorio. [21]

Limitaciones para probar la integración con sistemas externos

Las pruebas unitarias tienden a ser más fáciles cuando un método tiene parámetros de entrada y alguna salida. No es tan fácil crear pruebas unitarias cuando una función principal del método es interactuar con algo externo a la aplicación. Por ejemplo, un método que funcionará con una base de datos podría requerir la creación de una maqueta de interacciones con la base de datos, que probablemente no será tan completa como las interacciones reales con la base de datos. [22] [ se necesita una mejor fuente ]

Ejemplos

JUnit

A continuación se muestra un ejemplo de un conjunto de pruebas JUnit. Se centra en la Adderclase.

clase  Adder { público int add ( int a , int b ) { devolver a + b ; } }             

El conjunto de pruebas utiliza declaraciones de afirmación para verificar el resultado esperado de varios valores de entrada al summétodo.

importar org.junit.Assert.assertEquals estático ; importar org.junit.Test ; clase pública AdderUnitTest { @Test public void sumReturnsZeroForZeroInput () { Sumador sumador = nuevo Adder (); assertEquals ( 0 , sumador . add ( 0 , 0 )); }                    @Test public void sumReturnsSumOfTwoPositiveNumbers () { Sumador sumador = new Sumador (); assertEquals ( 3 , sumador . add ( 1 , 2 )); }              @Test public void sumReturnsSumOfTwoNegativeNumbers () { Sumador sumador = new Sumador (); assertEquals ( - 3 , sumador . add ( - 1 , - 2 )); }              @Test public void sumReturnsSumOfLargeNumbers () { Sumador sumador = new Sumador (); assertEquals ( 2222 , sumador . add ( 1234 , 988 )); } }             

Como especificaciones ejecutables

El uso de pruebas unitarias como especificación de diseño tiene una ventaja significativa sobre otros métodos de diseño: el documento de diseño (las pruebas unitarias en sí) se puede utilizar para verificar la implementación. Las pruebas nunca se aprobarán a menos que el desarrollador implemente una solución de acuerdo con el diseño.

Las pruebas unitarias carecen de la accesibilidad de una especificación diagramática como un diagrama UML , pero pueden generarse a partir de la prueba unitaria utilizando herramientas automatizadas. La mayoría de los lenguajes modernos tienen herramientas gratuitas (normalmente disponibles como extensiones de los IDE ). Las herramientas gratuitas, como las basadas en el marco xUnit , externalizan a otro sistema la representación gráfica de una vista para el consumo humano.

Aplicaciones

Programación extrema

Las pruebas unitarias son la piedra angular de la programación extrema , que se basa en un marco de trabajo de pruebas unitarias automatizadas . Este marco de trabajo de pruebas unitarias automatizadas puede ser de terceros, por ejemplo, xUnit , o creado dentro del grupo de desarrollo.

La programación extrema utiliza la creación de pruebas unitarias para el desarrollo basado en pruebas . El desarrollador escribe una prueba unitaria que expone un requisito de software o un defecto. Esta prueba fallará porque el requisito aún no se implementó o porque expone intencionalmente un defecto en el código existente. Luego, el desarrollador escribe el código más simple para que la prueba, junto con otras pruebas, pase.

La mayor parte del código de un sistema se prueba unitariamente, pero no necesariamente todas las rutas a través del código. La programación extrema exige una estrategia de "probar todo lo que pueda romperse", en lugar del método tradicional de "probar cada ruta de ejecución". Esto lleva a los desarrolladores a desarrollar menos pruebas que los métodos clásicos, pero esto no es realmente un problema, sino más bien una reafirmación de un hecho, ya que los métodos clásicos rara vez se han seguido con la metódica suficiente como para que se hayan probado a fondo todas las rutas de ejecución. [ cita requerida ] La programación extrema simplemente reconoce que las pruebas rara vez son exhaustivas (porque a menudo son demasiado caras y requieren mucho tiempo para ser económicamente viables) y proporciona orientación sobre cómo concentrar eficazmente los recursos limitados.

Fundamentalmente, el código de prueba se considera un artefacto de proyecto de primera clase, ya que se mantiene con la misma calidad que el código de implementación, y se elimina toda duplicación. Los desarrolladores publican el código de prueba unitaria en el repositorio de código junto con el código que prueba. Las pruebas unitarias exhaustivas de la programación extrema permiten los beneficios mencionados anteriormente, como un desarrollo y una refactorización de código más simples y confiables , una integración de código simplificada, una documentación precisa y diseños más modulares. Estas pruebas unitarias también se ejecutan constantemente como una forma de prueba de regresión .

Las pruebas unitarias también son fundamentales para el concepto de diseño emergente . Como el diseño emergente depende en gran medida de la refactorización, las pruebas unitarias son un componente integral. [ cita requerida ]

Marcos de pruebas automatizadas

Un marco de pruebas automatizadas proporciona funciones para automatizar la ejecución de pruebas y puede acelerar la escritura y la ejecución de pruebas. Se han desarrollado marcos para una amplia variedad de lenguajes de programación .

Generalmente, los frameworks son de terceros y no se distribuyen con un compilador o un entorno de desarrollo integrado (IDE).

Las pruebas se pueden escribir sin utilizar un marco de trabajo para ejercitar el código bajo prueba utilizando aserciones , manejo de excepciones y otros mecanismos de flujo de control para verificar el comportamiento e informar de los fallos. Algunos señalan que realizar pruebas sin un marco de trabajo es valioso, ya que existe una barrera de entrada para la adopción de un marco de trabajo; que tener algunas pruebas es mejor que ninguna, pero una vez que se implementa un marco de trabajo, agregar pruebas puede ser más fácil. [23]

En algunos marcos faltan funciones de prueba avanzadas y deben codificarse manualmente.

Soporte para pruebas unitarias a nivel de lenguaje

Algunos lenguajes de programación admiten directamente las pruebas unitarias. Su gramática permite la declaración directa de pruebas unitarias sin importar una biblioteca (ya sea de terceros o estándar). Además, las condiciones booleanas de las pruebas unitarias se pueden expresar con la misma sintaxis que las expresiones booleanas utilizadas en el código de pruebas no unitarias, como por ejemplo, las declaraciones ify que se utilizan para while.

Los lenguajes con soporte para pruebas unitarias incorporado incluyen:

Los lenguajes con soporte para el marco de pruebas unitarias estándar incluyen:

Algunos lenguajes no cuentan con compatibilidad integrada con pruebas unitarias, pero cuentan con bibliotecas o marcos de trabajo de pruebas unitarias establecidos. Entre estos lenguajes se incluyen:

Véase también

Referencias

  1. ^ ab Kolawa, Adam; Huizinga, Dorota (2007). Prevención automatizada de defectos: mejores prácticas en la gestión de software . Wiley-IEEE Computer Society Press. pág. 75. ISBN 978-0-470-04212-0.
  2. ^ Benington, Herbert D. (1956). "Producción de grandes programas informáticos". Actas del Simposio sobre métodos avanzados de programación para ordenadores digitales, Washington, DC, 28 y 29 de junio de 1956. Oficina de Investigación Naval, Departamento de la Armada: 15–28.
  3. ^ ab Benington, HD (1 de marzo de 1987). "Producción de grandes programas informáticos (reimpresión del artículo de 1956 con un prólogo actualizado)". Actas de la 9.ª Conferencia Internacional sobre Ingeniería de Software . ICSE '87. Washington, DC, EE. UU.: IEEE Computer Society Press: 299–310. ISBN 978-0-89791-216-7.
  4. ^ Donegan, James J.; Packard, Calvin; Pashby, Paul (1 de enero de 1964). "Experiencias con el sistema de computación Goddard durante misiones espaciales tripuladas". Actas de la 19.ª conferencia nacional de la ACM de 1964. ACM '64. Nueva York, NY, EE. UU.: Association for Computing Machinery. págs. 12.101–12.108. doi :10.1145/800257.808889. ISBN 978-1-4503-7918-2.
  5. ^ Zimmerman, Norman A. (26 de agosto de 1969). "La integración de sistemas como función de programación". Actas de la 24.ª conferencia nacional de 1969. ACM '69. Nueva York, NY, EE. UU.: Association for Computing Machinery. págs. 459–467. doi :10.1145/800195.805951. ISBN 978-1-4503-7493-4.
  6. ^ MIL-STD-483 Norma militar: prácticas de gestión de configuración para sistemas, equipos, municiones y programas informáticos . Estados Unidos, Departamento de Defensa. 31 de diciembre de 1970. págs. Sección 3.4.7.2. El contratista deberá codificar y probar las Unidades de software, e ingresar el código fuente y el código objeto, y los listados asociados de cada Unidad probada con éxito en la Configuración de desarrollo.{{cite book}}: CS1 maint: date and year (link)
  7. ^ Tighe, Michael F. (1 de enero de 1978). "El valor de una metodología adecuada de aseguramiento de la calidad del software". ACM SIGMETRICS Performance Evaluation Review . 7 (3–4): 165–172. doi :10.1145/1007775.811118. ISSN  0163-5999.
  8. ^ Gulati, Shekhar (2017). Pruebas unitarias de Java con JUnit 5: desarrollo basado en pruebas con JUnit 5. Rahul Sharma. Berkeley, CA: Apress. pág. 8. ISBN 978-1-4842-3015-2.OCLC 1012347252  .
  9. ^ Winters, Titus (2020). Ingeniería de software en Google: lecciones aprendidas de la programación a lo largo del tiempo . Tom Manshreck, Hyrum Wright (1.ª ed.). Sebastopol, CA: O'Reilly. ISBN 978-1-4920-8274-3.OCLC 1144086840  .
  10. ^ Beck, Kent (2002). Desarrollo basado en pruebas mediante ejemplos . Addison-Wesley. ISBN 978-0321146533.
  11. ^ Ingeniería de sistemas y software -- Vocabulario . Iso/Iec/IEEE 24765:2010(E). 1 de diciembre de 2010. pp. 1–418. doi :10.1109/IEEESTD.2010.5733835. ISBN 978-0-7381-6205-8.
  12. ^ Kaner, Cem (mayo de 2003). "¿Qué es un buen caso de prueba?" (PDF) . STAR East : 2.
  13. ^ Gulati y Sharma 2017, págs. 133-137, Capítulo §7 Modelo de extensión JUnit 5: Prueba parametrizada.
  14. ^ ab Hamill, Paul (2004). Marcos de trabajo para pruebas unitarias: herramientas para el desarrollo de software de alta calidad. O'Reilly Media, Inc. ISBN 9780596552817.
  15. ^ Boehm, Barry W. ; Papaccio, Philip N. (octubre de 1988). "Understanding and Controlling Software Costs" (PDF) . IEEE Transactions on Software Engineering . 14 (10): 1462–1477. doi :10.1109/32.6191. Archivado desde el original (PDF) el 9 de octubre de 2016 . Consultado el 13 de mayo de 2016 .
  16. ^ "Realice pruebas con frecuencia y de forma temprana". Microsoft.
  17. ^ "Demuestre que funciona: uso del marco de pruebas unitarias para la prueba y validación de software". National Instruments . 21 de agosto de 2017.
  18. ^ Erik (10 de marzo de 2023). "Aún no sabes cómo hacer pruebas unitarias (y tu secreto está a salvo conmigo)". Stackify . Consultado el 10 de marzo de 2023 .
  19. ^ Brooks, Frederick J. (1995) [1975]. El mes mítico del hombre . Addison-Wesley. pág. 64. ISBN 978-0-201-83595-3.
  20. ^ daVeiga, Nada (6 de febrero de 2008). "Cambie el código sin miedo: utilice una red de seguridad para la regresión" . Consultado el 8 de febrero de 2008 .
  21. ^ Kucharski, Marek (23 de noviembre de 2011). "Hacer que las pruebas unitarias sean prácticas para el desarrollo integrado" . Consultado el 20 de julio de 2020 .
  22. ^ "Pruebas unitarias y bases de datos" . Consultado el 29 de enero de 2024 .
  23. ^ Bullseye Testing Technology (2006–2008). «Objetivos de cobertura intermedia» . Consultado el 24 de marzo de 2009 .
  24. ^ "Pruebas unitarias - Lenguaje de programación D". Lenguaje de programación D . Fundación del lenguaje D . Consultado el 5 de agosto de 2017 .
  25. ^ Steve Klabnik y Carol Nichols, con contribuciones de la comunidad Rust (2015–2023). «Cómo escribir pruebas» . Consultado el 21 de agosto de 2023 .
  26. ^ "Crystal Spec". crystal-lang.org . Consultado el 18 de septiembre de 2017 .
  27. ^ "testing - The Go Programming Language" (Pruebas: el lenguaje de programación Go). golang.org . Consultado el 3 de diciembre de 2013 .
  28. ^ "Pruebas unitarias · El lenguaje Julia". docs.julialang.org . Consultado el 15 de junio de 2022 .
  29. ^ Documentación de Python (2016). «unittest -- Marco de pruebas unitarias» . Consultado el 18 de abril de 2016 .
  30. ^ Welsh, Noel; Culpepper, Ryan. "RackUnit: Unit Testing". PLT Design Inc. Consultado el 26 de febrero de 2019 .
  31. ^ Welsh, Noel; Culpepper, Ryan. «Paquete de pruebas unitarias RackUnit, parte de la distribución principal de Racket». PLT Design Inc. Consultado el 26 de febrero de 2019 .
  32. ^ "Minitest (Ruby 2.0)". Ruby-Doc.org.
  33. ^ Sierra, Stuart. «API para clojure.test - Clojure v1.6 (estable)» . Consultado el 11 de febrero de 2015 .
  34. ^ "Pester Framework". GitHub . Consultado el 28 de enero de 2016 .

Lectura adicional

  • Feathers, Michael C. (2005). Cómo trabajar eficazmente con código heredado . Upper Saddle River, NJ: Referencia técnica profesional de Prentice Hall. ISBN 978-0131177055.
  • Gulati, Shekhar; Sharma, Rahul (2017). Pruebas unitarias de Java con JUnit 5. Apress .
  • Desarrollo basado en pruebas (Wiki de Ward Cunningham)
Retrieved from "https://en.wikipedia.org/w/index.php?title=Unit_testing&oldid=1249792515"