2010-12-14 7 views
8

Al usar mi aplicación, me encontré con una condición de carrera en algún código que usa un NSOperationQueue para ejecutar tareas de forma asíncrona después de eventos desencadenados por el usuario. Sé cómo arreglar la condición de carrera, ya que es un estúpido error de diseño que no voy a profundizar, pero me gustaría probar el error con un caso de prueba (para que no vuelva a aparecer durante la optimización/refactorización posterior). abajo de la línea). Esto me tiene perplejo. ¿Cómo se puede probar algo con múltiples subprocesos, especialmente cuando el objetivo de la prueba es generar una condición de carrera?¿Código de prueba de unidad basado en el hilo? Forzar una condición de carrera

¿Alguien tiene algún enlace al material de referencia al que me refiero cuando se trata de trabajar con hilos y pruebas de unidades? Estoy particularmente interesado en la generación de condiciones de carrera.

+0

Supongo que se burlará de cualquier estructura de datos compartida, y dentro de sus objetos simulados puede hacer cualquier sincronización que necesite para que los diferentes hilos se ejecuten en el orden "incorrecto". –

Respuesta

4

Debe asegurarse de que la secuencia de eventos que causa la condición de carrera realmente surja durante la prueba. Para eso, debe afectar el entrelazado del hilo dentro del caso de prueba.

Puede lograr eso con sincronización adicional (condicional) o, (más simple y menos confiable) temporizadores adicionales. Coloque algunas llamadas sleep() en las secciones críticas para asegurarse de que se ejecuten el tiempo suficiente para que el otro subproceso llegue al estado no deseado. Cuando tenga eso funcionando, reemplace las llamadas de espera con sincronización explícita (es decir, bloquee un hilo hasta que el otro reconozca que ha llegado).

A continuación, establezca todo esto condicional en un indicador global establecido por el caso de prueba.

+3

Honestamente, no creo que una buena idea sea acoplar estrechamente el código de producción real a esta prueba en particular. Esto significa que debe tener cuidado de no alterar ese acoplamiento cada vez que refactorice el código, lo que le hace perder el punto de tener esta prueba en primer lugar. –

+0

No, la fragilidad wrt. a la refactorización realmente apoya este enfoque de prueba. Cuando refactorices, tendrás que reconsiderar las condiciones de carrera. Entonces, puede encontrar que la refactorización en realidad introdujo nuevas, o que las que antes eran vulnerables ya no pueden suceder. –

+0

Simplemente no veo cómo esto "obliga" a nadie a refactorizar a reconsiderar las posibles condiciones de carrera, o que hacerlo realmente es útil. Claramente, pensar en las condiciones de carrera no funcionó la primera vez. Cualquiera que refactorice el código en un grado significativo tendría que arrojar el código de prueba existente por completo y escribir nuevos, o dejar inútil el código de prueba. De cualquier manera, se frustra el propósito de tener código de prueba. Sería mejor tener un código de prueba que no contamine la base de código principal, sino que marca la construcción como si estuviera rota. –

Cuestiones relacionadas