Loading presentation...

Present Remotely

Send the link below via email or IM

Copy

Present to your audience

Start remote presentation

  • Invited audience members will follow you as you navigate and present
  • People invited to a presentation do not need a Prezi account
  • This link expires 10 minutes after you close the presentation
  • A maximum of 30 users can follow your presentation
  • Learn more about this feature in our knowledge base article

Do you really want to delete this prezi?

Neither you, nor the coeditors you shared it with will be able to recover it again.

DeleteCancel

Make your likes visible on Facebook?

Connect your Facebook account to Prezi and let your likes appear on your timeline.
You can change this under Settings & Account at any time.

No, thanks

Pruebas unitarias

workshop
by

Luciano Martinez

on 6 April 2015

Comments (0)

Please log in to add your comment.

Report abuse

Transcript of Pruebas unitarias

Pruebas unitarias
¿Por qué pruebas unitarias?
Java
Referencias / Links útiles
Todos los programadores saben que deben realizar pruebas a su código. Pocos lo hacen. La respuesta generalizada al “¿por qué no?” es “No tengo tiempo”. Este apuro se convierte en un círculo vicioso. Cuanta más presión se siente, menos pruebas se realizan. Cuantas menos pruebas se realizan, menos productivo se es y el código se vuelve menos estable. Cuanto menos productivo y preciso se es, más presión se siente
Esta bola sobra
Hay que llenar espacio porque el template tenía seis bolas y terminamos usando solamente cinco. Si la elimino tengo que correr todo, acomodarlo y no tengo ganas.
Estrategias
A continuación se presentan una serie de recomendaciones de acuerdo al tipo de clase sobre la que se desea desarrollar casos de prueba unitarios.
Pruebas Mock
(Definición general)

mock: Hacer mímica, imitar o falsificar
Workshop
Automatizables
Completas
Repetibles o Reutilizables
Independientes
Profesionales
Características
Ventajas
Fomentan el cambio
Simplifica la integración
Documenta el código
Separación de la interfaz y la implementación
Errores más acotados / más fáciles de localizar
Mejoran el diseño
Más simple de verificar el funcionamiento
Desventajas
Es importante darse cuenta de que las pruebas unitarias no descubrirán todos los errores del código. Por definición, sólo prueban las unidades por sí solas. Por lo tanto, no descubrirán errores de integración, problemas de rendimiento y otros problemas que afectan a todo el sistema en su conjunto.
Limitaciones
Durante el año 2011 se dedicaron 1160 horas a la resolución de errores durante el desarrollo y en período de garantía, y en 2012 se registraron 710 horas.
Las pruebas 'mock' son pruebas unitarias con objetos que sustituyen a los objetos reales que la clase a probar utiliza.
El desarrollo de los casos de prueba unitarios puede ser percibido como una pérdida de tiempo dado que en sí es una actividad de codificación adicional, pero salvo el caso excepcional del desarrollador que codifica libre de errores, debe entenderse que esta actividad nos servirá para ahorrar tiempo en el futuro al disminuir la posibilidad de ocurrencia de errores.
Stub

Un ‘Stub’ es un objeto que implementa una interface de un componente, pero en lugar de retornar lo que el componente devolvería, el ‘stub’ puede ser configurado para retornar un valor que se ajuste a lo que la prueba unitaria intenta probar.
Prueba Unitaria → Stub
Prueba Unitaria → Unidad → Stub
La prueba unitaria verifica (assert) sobre el resultado y el estado de la unidad

public void testStub() {
Calculadora calculadora = new Calculadora();
GenericDAO stubGenericDao = stub(GenericDAO.class);
when call (stubGenericDao.getPrimerValor()) then return(4);
when call (stubGenericDao.getSegundoValor()) then return(8);
calculadora.setDao(stubGenericDao);
assertEquals(new Integer(12), calculadora.sumar());
}
Mock
Un ‘Mock’ es como un ‘stub’, que además permite determinar qué métodos fueron llamados durante la prueba. Utilizando un ‘mock’ se puede probar tanto si los valores devueltos por la unidad son los correctos, como así también si la Unidad está utilizando de forma correcta al Colaborador.
Prueba Unitaria → Mock
Prueba Unitaria → Unidad → Mock
La prueba unitaria verifica (assert) el resultado y el estado de la unidad.
La prueba unitaria verifica (assert) las llamadas a los métodos en el mock.
public void testMock() {
Calculadora calculadora = new Calculadora();
GenericDAO mockGenericDao= mock(GenericDAO.class);
When call (mockGenericDao.getPrimerValor()) then return(10);
When call (mockGenericDao.getSegundoValor()) then return(11);
calculadora.setDao(mockGenericDao);
assertEquals(new Integer(21), calculadora.sumar());
verify at least one call of mockGenericDao.getPrimerValor();
}
Proxy
Los ‘Proxies’ son objetos ‘mock’ que delegan las llamadas a los métodos en el objeto Colaborador real, pero continúa registrando internamente qué métodos fueron llamados en el proxy. Los ‘proxies’ permiten hacer pruebas mock con los colaboradores reales
Prueba Unitaria → Colaborador
Prueba Unitaria → Proxy
Prueba Unitaria → Unidad → Proxy → Colaborador.
La prueba unitaria verifica (assert) el resultado y el estado de la unidad.
La prueba unitaria verifica (assert) las llamadas a los métodos en el proxy.
Connection connection = (Connection) MockFactory.createProxy(Connection.class); IGenericDao dao = new GenericDao(connection, config);
IMock mock = MockFactory.getMock(connection);
dao.setAutoCommit(true);
mock.assertInvoked(new MethodInvocation("setAutoCommit",
boolean.class, new Boolean(true)));
Clases dependientes
de un “Servlet Container”
Pruebas en
“Dependency Injection Container”
Spring Validator
Spring FormAction
Clases de IO
En esta categoría incluimos clases o unidades que realizan operaciones de lectura o escritura de archivos.
Clases de
acceso a BD
El objetivo al desarrollar pruebas unitarias para las clases que realizan el acceso a la base de datos será verificar que tanto las operaciones de lectura como de escritura sobre la base de datos se ejecuten correctamente, intentando mantener la consistencia de los datos almacenados y sin necesidad de implementar lógica compleja para poder operar con los juegos de valores o realizar una limpieza al finalizar las pruebas.
En este caso, para evitar tener que emular el Servlet Container y la dependencia de objetos propios del contexto de ejecución, se recomienda mover el código que implementa la lógica de negocio a una nueva clase que no tenga dependencias de la Servlet API.
Cuando se trabaja con un contenedor de dependencias en la aplicación, se puede delegar en él la inyección de objetos mock a las unidades durante las pruebas.
Existirá situaciones en las que resultará práctico contar con un mecanismo para hacer pruebas unitarias sobre los Action intentando evitar la necesidad del refactoring para extraer la lógica de la aplicación de clases con dependencias del contexto de ejecución.


El caso de los Validators es más simple que el anterior, dado que estas clases no presentan (en general) dependencias del contexto u otro objeto.

Es por ello, que en este caso bastará con utilizar un objeto mock con valores preestablecidos y verificar que los errores retornados coincidan con lo esperado.
Introducción a los frameworks
JUnit
Mockito
JUnit en su versión 4.x es un framework de pruebas que utiliza ‘annotations’ para identificar los métodos que ejecutan pruebas. Generalmente estos métodos son llamados en clases que son utilizadas especificamente para realizar pruebas del tipo Test
Annotations
Assert statements

fail(String)
assertTrue([message], boolean condition)
assertsEquals([String message], expected, actual)
assertsEquals([String message], expected, actual, tolerance)
assertNull([message], object)
assertNotNull([message], object)
assertSame([String], expected, actual)
assertNotSame([String], expected, actual)
@Test
@Before
@After
@BeforeClass
@AfterClass
@Ignore
@Test (exception)
@Test (timeout)
Crear una suite de pruebas con JUnit
Si se tienen varios casos de pruebas se los puede combinar todos en una suite. Se utiliza la sentencia @Suite.SuiteClasses
El siguiente código de ejemplo muestra una suite de prueba que define que dos clases de pruebas deben ejecutarse
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses(
{ MyClassTest.class, MySecondClassTest.class }
)
public class AllTests {
}

> Qué es un unit test
http://msdn.microsoft.com/es-es/library/jj130731.aspx
> Mocks Aren't Stubs
http://www.martinfowler.com/articles/mocksArentStubs.html
> Stub, Mock and Proxy Testing
http://tutorials.jenkov.com/java-unit-testing/stub-mock-and-proxy-testing.html
> disableAutoCommit in Hibernate
http://www.coderanch.com/t/463713/ORM/databases/disabling-autoCommit-hibernate
> Mockito in six easy examples
http://gojko.net/2009/10/23/mockito-in-six-easy-examples/
> JUnit Tutorial
http://www.vogella.com/articles/JUnit/article.htm
> Wikipedia - Prueba unitaria
http://es.wikipedia.org/wiki/Prueba_unitaria
> JUnit testing Hibernate and Spring
http://www.disasterarea.co.uk/blog/?p=75
Preguntas
@Test
public void testMultiply() {
// MyClass is tested
MyClass tester = new MyClass();
// Check if multiply(10,5) returns 50
assertEquals("10 x 5 must be 50", 50, tester.multiply(10, 5));
}
Mockito es un Framework OpenSource para pruebas de aplicaciones JAVA. Permite simular comportamientos complejos de objetos.Mockito se basa en el principio de un objeto mock que simula el comportamiento de otro objeto.
La implementación de tests Mockito se hace en varias etapas:
Creación del objeto mock.
Descripción del comportamiento esperado
Uso de los mocks
Verificación que la interacción sea correcta.
@Testpublic void iterator_will_return_hello_world(){
//arrange
Iterator i=mock(Iterator.class);
when(i.next()).thenReturn("Hello").thenReturn("World");
//act
String result=i.next()+" "+i.next();
//assert
assertEquals("Hello World", result);
}
Full transcript