This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
wiki:test_1 [2024/11/12 23:00] – created admin | wiki:test_1 [2024/11/12 23:18] (current) – admin | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Testing Unitario ====== | ====== Testing Unitario ====== | ||
+ | |||
+ | El software es una de las construcciones humanas más complejas, como se discutió en clases. Por lo tanto, es comprensible que los sistemas de software estén sujetos a los más diversos tipos de errores e inconsistencias. Para evitar que tales errores lleguen a los usuarios finales y causen perjuicios de valor incalculable, | ||
+ | |||
+ | Cuando el desarrollo era en cascada, las pruebas se realizaban en una fase separada, después de las fases de recopilación de requisitos, análisis, diseño y codificación. Además, existía un equipo separado de pruebas, encargado de verificar si la implementación cumplía con los requisitos del sistema. Para comprobar esto, con frecuencia las pruebas eran manuales, es decir, una persona usaba el sistema, ingresaba datos y verificaba si las salidas eran las esperadas. Así, el objetivo de esas pruebas era solo detectar errores antes de que el sistema entrara en producción. | ||
+ | |||
+ | Con los métodos ágiles, la práctica de las pruebas de software se reformuló profundamente, | ||
+ | |||
+ | * Gran parte de las pruebas comenzó a ser automatizada, | ||
+ | |||
+ | * Las pruebas ya no se implementan después de que todas las clases de un sistema estén listas. Muchas veces, se implementan incluso antes de que esas clases estén terminadas. | ||
+ | |||
+ | * Ya no existen grandes equipos de pruebas, o si existen, son responsables de pruebas específicas. En su lugar, el desarrollador que implementa una clase también debe implementar sus pruebas. | ||
+ | |||
+ | * Las pruebas ya no son solo una herramienta exclusiva para detectar errores. Claro, esto sigue siendo importante, pero las pruebas han adquirido nuevas funciones, como verificar si una clase seguirá funcionando después de que se corrija un error en otra parte del sistema. Las pruebas también se utilizan como documentación para el código de producción. | ||
+ | |||
+ | Estas transformaciones han convertido las pruebas en una de las prácticas de programación más valoradas en el desarrollo moderno de software. Es en este contexto que debemos entender la frase de Michael Feathers: //si un código no viene acompañado de pruebas, puede considerarse de baja calidad o incluso un código legado//. | ||
+ | |||
+ | Esta sección se enfoca en las pruebas automatizadas, | ||
+ | |||
+ | Una forma interesante de clasificar las pruebas automatizadas es mediante una pirámide de pruebas (ver slides), originalmente propuesta por Mike Cohn [[https:// | ||
+ | Particularmente, | ||
+ | |||
+ | Las pruebas unitarias son pruebas automatizadas de pequeñas unidades de código, normalmente clases, que se prueban de forma aislada del resto del sistema. Una prueba unitaria es un programa que llama métodos de una clase y verifica si devuelven los resultados esperados. Así, cuando se utilizan pruebas unitarias, el código de un sistema puede dividirse en dos grupos: un conjunto de clases, que implementan los requisitos del sistema, y un conjunto de pruebas. | ||
+ | |||
+ | Las pruebas unitarias se implementan usando frameworks construidos específicamente para este fin. Los más conocidos se llaman frameworks xUnit, donde la " | ||
+ | |||
+ | Hoy en día, existen versiones de frameworks xUnit para los principales lenguajes. Por lo tanto, una de las ventajas de las pruebas unitarias es que los desarrolladores no necesitan aprender un nuevo lenguaje de programación, | ||
+ | |||
+ | Para explicar los conceptos de pruebas unitarias, usaremos una clase Stack (Pila): | ||
+ | |||
+ | <code java> | ||
+ | |||
+ | import java.util.ArrayList; | ||
+ | import java.util.EmptyStackException; | ||
+ | |||
+ | public class Stack< | ||
+ | |||
+ | private ArrayList< | ||
+ | private int size = 0; | ||
+ | |||
+ | public int size() { | ||
+ | return size; | ||
+ | } | ||
+ | |||
+ | public boolean isEmpty() { | ||
+ | return (size == 0); | ||
+ | } | ||
+ | |||
+ | public void push(T elem) { | ||
+ | elements.add(elem); | ||
+ | size++; | ||
+ | } | ||
+ | |||
+ | public T pop() throws EmptyStackException { | ||
+ | if (isEmpty()) | ||
+ | throw new EmptyStackException(); | ||
+ | T elem = elements.remove(size-1); | ||
+ | size--; | ||
+ | return elem; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | JUnit permite implementar clases que probarán — de forma automática — las clases de la aplicación, | ||
+ | |||
+ | A continuación, | ||
+ | |||
+ | <code java> | ||
+ | |||
+ | import org.junit.Test; | ||
+ | import static org.junit.Assert.assertTrue; | ||
+ | |||
+ | public class StackTest { | ||
+ | |||
+ | @Test | ||
+ | public void testEmptyStack() { | ||
+ | Stack< | ||
+ | boolean empty = stack.isEmpty(); | ||
+ | assertTrue(empty); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | En esta primera versión, la clase StackTest tiene un único método de prueba, público, anotado con '' | ||
+ | |||
+ | Los métodos de prueba tienen la siguiente estructura: | ||
+ | |||
+ | * Primero, se crea el contexto de la prueba, también llamado fixture. Para ello, se deben instanciar los objetos que se van a probar y, si es necesario, inicializarlos. En nuestro primer ejemplo, esta parte de la prueba incluye solo la creación de una pila llamada stack. | ||
+ | |||
+ | * A continuación, | ||
+ | |||
+ | * Finalmente, debemos comprobar si el resultado del método es el esperado. Para ello, se utiliza un comando llamado assert. De hecho, JUnit ofrece varias variantes de assert, pero todas tienen el mismo objetivo: comprobar si un determinado resultado es igual a un valor esperado. En el ejemplo, usamos assertTrue, que verifica si el valor pasado como parámetro es verdadero. | ||
+ | |||
+ | Las IDEs ofrecen opciones para ejecutar solo las pruebas de un sistema, por ejemplo, a través de una opción de menú llamada Run as Test. Es decir, si el desarrollador selecciona Run, ejecutará su programa normalmente, | ||