Tutorial JUnit · Otoño 2016 · Estudios de Informática Multimedia y Telecomunicación TUTORIAL JUNIT Introducción JUnit es una biblioteca informática para Java que se utiliza para realizar pruebas unitarias y funcionales durante el desarrollo de una aplicación. Existen dos tipos de pruebas: las pruebas unitarias se refieren a pequeñas partes del código, como clases o métodos, las pruebas funcionales se refieren al comportamiento o integración de diferentes componentes. La idea general es disponer de un modo de verificar el correcto funcionamiento de cada una de las funcionalidades no triviales de una aplicación sin tener que hacer las pruebas manualmente. Estas pruebas aseguran que el código funciona como se pretende y que después de cualquier modificación, lo sigue haciendo. Cada prueba verifica que a partir de un conjunto de datos de entrada conocidos (precondición) se produce la salida esperada (postcondición). Para cada funcionalidad se deben verificar también los casos de error. Cada una de las pruebas debe ser independiente del resto y debe poder repetirse tantas veces como haga falta. Relacionado con la idea de realizar pruebas unitarias sobre el código se encuentra el desarrollo guiado por pruebas (Test Driven Development), donde primero se escriben el conjunto de pruebas que se quieren realizar y luego se programa la aplicación para que pase las pruebas definidas. JUNIT Las pruebas en JUnit se organizan en clases separadas del código que se quiere probar. Estas clases se utilizan exclusivamente para ejecutar pruebas. Habitualmente estas clases terminan o comienzan con el sufijo Test (UserTest, TestConnection, etc.) Cada clase contiene uno o más métodos y cada método marcado con la anotación @Test es una prueba. public class UsersTest { @Test public void testNewUser () { RegisteredUser user = new RegisteredUser("thename", "theemail"); assertEquals("thename", user.getName()); assertEquals("theemail", user.getEmail()); assertEquals(0, user.getMessages().size()); assertEquals("thename", user.toString()); } } 1 Tutorial JUnit · Otoño 2016 · Estudios de Informática Multimedia y Telecomunicación La clase anterior (UsersTest) contiene una prueba sobre el código. En este caso se prueba la creación de un nuevo usuario. Una vez creado se comprueba que el nombre del usuario y su correo coinciden. También se prueba que se ha creado un listado de mensajes vacío y que el resultado del método toString () sea el correcto. Anotaciones Como ya se ha comentado JUnit usa la anotación @Test en el código para indicar qué métodos son pruebas y cuáles no. Las anotaciones son metadatos que se añaden al código fuente de Java (atributos, métodos, clases, etc) de la forma básica @ Anotación o @ Anotación (parámetros). En tiempo de compilación o ejecución se pueden leer estos metadatos y hacer unas cosas u otras en consecuencia. En el caso de JUnit se usan estas anotaciones en tiempo de ejecución para saber cómo y qué pruebas se deben realizar. Existen otras anotaciones en JUnit que se añaden a los métodos y que se utilizarán en nuestras clases de prueba: Anotación Descripción @Test Identifica a un método como un método que se utilizará como prueba @BeforeClass Este método se ejecuta una única vez antes de cualquier prueba de la clase. Sirve para preparar el conjunto de objetos comunes y recursos para todas las pruebas de la clase @Before Este método se ejecuta antes de cada una de las pruebas. Se utiliza para preparar los recursos nuevos o inicializar clases A continuación, se muestra el esqueleto de una de les clases de prueba donde se pueden ver estas anotaciones: 2 Tutorial JUnit · Otoño 2016 · Estudios de Informática Multimedia y Telecomunicación public class EmptyTest { @BeforeClass public static void prepare() { // This method is executed ONCE before any test of this class } @Before public void setUp() { // This method is executed before each test } @Test public void testXYZ () { // This is a TEST } @Test public void testABC () { // This is another TEST } public Boolean sayYes () { // This is a method, not a TEST. return true; } } Asserts Como hemos visto en el primer ejemplo, JUNIT ofrece una serie de métodos llamados «asserts» que sirven para probar la validez de los resultados. Normalmente los métodos reciben parámetros con el valor deseado y el valor real. Si los valores coinciden, la ejecución de la prueba continua. Si los valores son distintos, la prueba se marca como fallada y se pasa a la siguiente prueba. Existen distintos «asserts» para los distintos datos que se quieren verificar. A continuación se muestra una tabla resumen con los utilizados en nuestras pruebas: Assert Descripció fail() La prueba a fallado. Normalmente se pone en las líneas donde se supone que el programa no debería llegar nunca assertTrue(x) Comprueba que x == true. Sino, la prueba falla assertEquals(x,y) Comprueba que x.equals(y). Sino, la prueba falla assertNotNull(x) Comprueba que x != null. Sino, la prueba falla assertSame(x,y) Comprueba que x e y son el mismo objeto. Sino, la prueba falla 3 Tutorial JUnit · Otoño 2016 · Estudios de Informática Multimedia y Telecomunicación Integración a Eclipse La biblioteca de pruebas JUnit está integrada en Eclipse y otros entornos de desarrollo. A continuación se explican los pasos a seguir para preparar el proyecto y ejecutar las pruebas: 1. Inclusión de las librerías (.jar) para que el código de pruebas compile 2. Ejecución de las clases de pruebas 3. Visualización de los resultados de las pruebas Inclusión de les librerías de JUNIT Es necesario indicar al proyecto que utilice las librerías de JUnit. Para añadirlas, tenemos que ir a las propiedades del proyecto. Una vez allí se pueden ver todas las librerías que se utilizan en la pestaña «Libraries». La librería de JUnit se encuentra en las librerías de Eclipse, por lo tanto añadimos una nueva librería. En la pantalla que se muestra a continuación se selecciona JUnit. Si el programa muestra diferentes versiones, debemos elegir siempre la versión 4 (la más reciente) 4 Tutorial JUnit · Otoño 2016 · Estudios de Informática Multimedia y Telecomunicación Si el entorno de programación Eclipse no ofrece la posibilidad de incluir la versión 4 de la biblioteca de Junit será necesario actualizar el programa Eclipse con una versión más reciente o incluir manualmente la versión 4 de las librerías de JUnit. • Eclipse: http://www.eclipse.org/downloads/ • JUnit, opción Plain-old y añadir al proyecto como librerías https://github.com/junit-team/junit/wiki/Download-and-Install 5 Tutorial JUnit · Otoño 2016 · Estudios de Informática Multimedia y Telecomunicación Ejecución de las pruebas La primera vez que se ejecuta una clase de pruebas con el entorno de programación Eclipse, se puede hacer mediante el botón derecho del ratón sobre la clase que se quiere ejecutar. En cuanto se visualiza el conjunto de acciones que se pueden realizar sobre la clase se selecciona «Run As» --> «JUnit Test» A partir de este momento se puede repetir la ejecución de esta prueba desde la barra de herramientas, como si se tratara de un programa Java normal. 6 Tutorial JUnit · Otoño 2016 · Estudios de Informática Multimedia y Telecomunicación Visualización de los resultados Los resultados se muestran en una nueva vista de Eclipse. Cada clase y método de prueba se muestra con un icono que puede ser de diferentes colores. Cada color nos indicará el resultado de la prueba: • Los métodos marcados con color verde han pasado la prueba correctamente. • Los métodos marcados con color azul no han pasado la prueba debido a alguna comprobación quiebra (assert). • Finalmente los métodos marcados con color rojo no han pasado la prueba por alguna otro excepción, normalmente relacionada con el código (no compila, NullPointerException porque los objetos sobre los que se realizan las pruebas aún no tienen valores, etc.) 7 Tutorial JUnit · Otoño 2016 · Estudios de Informática Multimedia y Telecomunicación En los resultados se pueden ver tres pantallas diferentes: 1. El resultado de las diferentes pruebas con sus colores correspondientes. 2. Si se selecciona una prueba con errores se puede ver el motivo del error. Las excepciones del tipo AssertionError se refieren a las comprobaciones que se realizan en el código mediante los métodos assertXXX 3. Finalmente si seleccionamos uno de los errores podemos ver el código y el lugar exacto donde se produjo el error. 8 Tutorial JUnit · Otoño 2016 · Estudios de Informática Multimedia y Telecomunicación Cómo implementar la Práctica Durante la implementación de la práctica se seguirá el proceso de codificar y probar. Se codificará una funcionalidad y a continuación se comprobará que funciona correctamente (pasa el juego de pruebas). Lo primero de todo será leer el enunciado y el diagrama de clases UML que lo acompaña para entender la funcionalidad que se debe implementar. Una vez queda clara la funcionalidad de la aplicación se comienza con la programación. Para cada funcionalidad que se debe implementar se realizarán los siguientes pasos: 1. Pensar cómo escribir la funcionalidad en Java 2. Comprobar, en las clases JUnit, qué pruebas se utilizan para verificar esta funcionalidad. 3. Implementar. 4. Pasar el juego de pruebas. 5. Comprobar los resultados. Si la prueba que verifica la funcionalidad implementada falla, se analizarán las causas y se cambiará la implementación en consecuencia. Sobre una misma funcionalidad es posible que existan diferentes pruebas. Cada prueba verificará diferentes aspectos de la funcionalidad. En estos casos la funcionalidad se puede ir implementado paso a paso mejor que intentar pasar todas las pruebas relacionadas de una única vez. Cada prueba puede tener diferentes comprobaciones específicas (asserts). Si la funcionalidad es muy compleja puedes ir implementado la funcionalidad poco a poco intentando pasar los asserts uno a uno. Las clases de pruebas están preparadas para crear objetos de negocio y llamar métodos sobre estos objetos. Cuando no hay ninguna clase en el proyecto, las clases de pruebas no compilarán. Es por este motivo que el primer paso será crear las clases necesarias con los atributos y métodos indicados en el diagrama UML, más los métodos (accesores) que se utilizan durante las pruebas. 9