Posible código de prueba de unidad que no fue diseñar inicialmente a ensayar, sin cambiar ningún código?

StackOverflow https://stackoverflow.com/questions/4033813

Pregunta

¿Está generalmente aceptado que no se puede código de prueba a menos que el código está configurado para ser probado?

Un poco hipotético de código:

public void QueueOrder(SalesOrder order)
{
   if (order.Date < DateTime.Now-20)
      throw new Exception("Order is too old to be processed");
   ...  
}

Algunos consideraría refactorización en:

protected DateTime MinOrderAge;
{
   return DateTime.Now-20;
}

public void QueueOrder(SalesOrder order)
{
   if (order.Date < MinOrderAge)
      throw new Exception("Order is too old to be processed");
   ...
}

Nota: Puede llegar a soluciones aún más complicado; que implica una interfaz IClock y la fábrica. No afecta a mi pregunta.

El problema con el cambio del código anterior es que el código ha cambiado. El código ha cambiado sin el que pide al cliente para que pueda ser cambiado. Y cualquier cambio requiere reuniones y conferencias telefónicas. Y así que estoy en el punto en que es más fácil no prueba nada.

Si no estoy dispuesto / capaz de hacer cambios: ¿me hace no es capaz de realizar las pruebas

?

Nota: Lo anterior pseudo-código podría ser como C #, pero eso es sólo por lo que es fácil de leer. La pregunta es agnóstico idioma.

Nota: El fragmento de código hipotética, problema, necesidad de refactorización, y refactorización son hipotéticas. Usted puede insertar su propio código de ejemplo hipotético si se toma el resentimiento con la mía.

Nota: El código anterior es hipotética hipotético. Cualquier relación con cualquier código, vivo o muerto, es pura coincidencia.

Nota: El código es hipotética, pero ninguna respuesta no lo son. La cuestión no es subjetiva:. Como creo que hay una respuesta


Actualización: El problema aquí, por supuesto, es que no puedo garantizar que el cambio en el ejemplo anterior no se rompió nada. Claro i refactorizado una pieza de código a un método separado, y el código es lógicamente idénticos.

Pero i no puede garantizar que la adición de un nuevo método protegido no lo hizo compensar la Tabla método virtual del objeto , y si esta clase está en un DLL entonces he acaba de presentar una violación de acceso.

¿Fue útil?

Solución

La respuesta es sí, algo de código tendrá que cambiar para que sea comprobable.

Sin embargo, es posible que haya una gran cantidad de código que pueden ser probados sin tener que cambiarlo. Me gustaría centrarse en escribir pruebas para eso primero, y luego escribir las pruebas para el resto cuando otras necesidades de los clientes le dan la oportunidad de refactorearlo de una manera comprobable.

Otros consejos

El código puede ser escrito desde el principio para ser comprobable. Si no está escrito desde el principio con la capacidad de prueba en mente, todavía puede probarlo, es posible que sólo topado con algunas dificultades.

En su código hipotética, que podría poner a prueba el código original mediante la creación de un SalesOrder con una fecha muy lejos en el pasado, o se puede burlarse cabo DateTime.Now. Tener el código readaptado a medida que demostramos es más agradable para las pruebas, pero no es absolutamente necesario.

Si el código no está diseñado para ser probado, entonces es más difícil de probar. En su ejemplo se tendría que reemplazar el método DateTime.Now que es además probablemente ninguna tarea fácil.

Te parece que agrega poco valor para añadir pruebas a su código o el cambio de no se permite código existente, entonces no debería hacerlo.

Sin embargo, si la creencia en TDD entonces usted debe escribir nuevo código con las pruebas.

Puede unidad de prueba tu ejemplo original utilizando un marco de objetos de imitación. En este caso me gustaría burlarse del objeto SalesOrder varias veces, la configuración de un valor de fecha diferente cada vez, y la prueba. Esto evita cambiar ningún código que los barcos y le permite validar el algoritmo en cuestión que la fecha de la orden no está demasiado lejos en el pasado.

Para una mejor visión general de lo que es posible dadas las dependencias que está tratando, y el lenguaje de las características que tiene a su disposición, lo recomiendo a partir del trabajo con el código heredado .

Esto es fácil de lograr en algunos lenguajes dinámicos. Por ejemplo, yo puedo enganchar el interior de las importación / Uso de declaraciones y sustituir una dependencia real con una un talón, incluso si el SUT (Sistema Bajo Pruebas) lo utiliza como una dependencia implícita. O puedo redefinir esos símbolos (clases, métodos, funciones, etc.). No estoy diciendo que este es el camino a seguir. Las cosas deben ser refactorizan, pero es más fácil de escribir algunas pruebas de caracterización.

El problema con este tipo de código es siempre, que es la creación y en función de una gran cantidad de clases estáticas, tipos de estructuras, etc, etc ...

Una muy buena solución a falsificaciones '' Inyectar para todos estos objetos es Typemock aislador (que es comercial, pero vale la pena cada centavo). Así que sí, que sin duda puede código heredado de prueba, que fue escrito y sin la capacidad de prueba en mente. Lo he hecho en un proyecto grande con Typemock y tenía muy buenos resultados.

Como alternativa a Typemock, se puede utilizar el marco libre de MS Moles, lo que hace básicamente lo mismo. Es sólo que tiene una API muy poco intuitivo y es mucho más difícil de aprender y utilizar.

HTH.
Thomas

Mockito + PowerMock para Mockito.

Usted será capaz de probar casi todo sin cambiar drásticamente su código. Sin embargo, serán necesarios algunos emisores para inyectar los simulacros.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top