Código de límite de tiempo de prueba de unidad

7

Actualmente estoy trabajando en una aplicación que realiza muchas operaciones con límite de tiempo. Es decir, basado en long now = System.currentTimeMillis(); , y combinado con un planificador, calculará períodos de tiempo que parametrizan la ejecución de algunas operaciones. por ejemplo:

public void execute(...) { // executed by an scheduler each x minutes
    final int now = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
    final int alignedTime = now - now % getFrequency() ;
    final int startTime = alignedTime - 2 * getFrequency(); 
    final int endTimeSecs = alignedTime - getFrequency(); 
    uploadData(target, startTime, endTimeSecs);
}

La mayoría de las partes de la aplicación se prueban por unidades independientemente del tiempo (en este caso, uploadData tiene una prueba de unidad natural), pero me preguntaba cuáles son las mejores prácticas para probar partes con límite de tiempo que dependen de System.currentTimeMillis()

    
pregunta maasg 09.07.2012 - 16:40

3 respuestas

11

DEFINITIVAMENTE debes hacer arreglos para simular el reloj del sistema. He trabajado en C ++ y hago que el objeto tome un objeto de 'interfaz de reloj', o uso una interfaz interna o un puntero de función dentro de la clase que luego reemplazo cuando hago el código de prueba.

En realidad, tengo experiencia con NO burlarme del reloj del sistema y créeme cuando te lo digo, nunca termina bien.

En realidad, existen varios problemas para realizar pruebas unitarias que dependen del reloj del sistema real. La primera es que es simplemente difícil de hacer (terminas agarrando el reloj, luego haciendo cosas, luego agarrando el reloj nuevamente para verificar), pero también es molesto porque tus tiempos de prueba se limitan en tiempo real (si estás probando algo eso es 30 segundos, luego son más de 30 segundos para ejecutar la prueba).

El problema más importante, sin embargo, es que hace que tus pruebas sean MUY BRITTLE.

Sus pruebas comenzarán a fallar aleatoriamente debido a problemas de carga del servidor. Fallarán de forma aleatoria y enviará tiempo revisando las fallas una y otra vez.

No vale la pena: usa una interfaz para el reloj del sistema y simulalo en el código de prueba.

    
respondido por el Michael Kohne 09.07.2012 - 17:18
12

En lugar de llamar directamente a System.currentTimeMillis() , lo ajustaría en su propia clase y lo inyectaría en su código de forma dinámica. Lo que esto le proporciona es la capacidad de burlarse de su objeto envoltorio para devolver un tiempo fijo en el contexto de las pruebas. Esto significa que su código de prueba nunca llamará a System.currentTimeMillis() , sino que obtendrá un tiempo fijo para trabajar que puede predecir.

    
respondido por el Oleksi 09.07.2012 - 16:44
6

No use System.currentTimeMillis (), pero programe todo usando el tiempo contra un tiempo de retorno de la interfaz. Durante la prueba de unidad, simule la interfaz, de lo contrario, simplemente no puede probar nada usando el tiempo de manera confiable. Esto también tiene la ventaja de que, si decide que currentTimeMillis no es lo suficientemente preciso, puede reemplazarlo con otro método en un solo lugar y todo ahora utilizará ese otro método.

    
respondido por el stijn 09.07.2012 - 16:44

Lea otras preguntas en las etiquetas