Escritura de pruebas para el código cuyo propósito no entiendo

58

Recientemente completé una refactorización de caja negra. No puedo registrarlo, porque no puedo averiguar cómo probarlo.

En un nivel alto, tengo una clase cuya inicialización consiste en tomar valores de alguna clase B. Si la clase B está "vacía", genera algunos valores predeterminados razonables. Extraje esta parte a un método que inicializa la clase B con esos mismos valores predeterminados.

Todavía tengo que determinar el propósito / contexto de cualquiera de las clases, o cómo se usarían. Así que no puedo inicializar el objeto desde una clase B vacía y comprobar que tiene los valores correctos / hace lo correcto.

Mi mejor idea es ejecutar el código original, el código en los resultados de los métodos públicos en función de los miembros inicializados, y probar el nuevo código con eso. No puedo expresar por qué me siento vagamente incómodo con esta idea.

¿Hay un mejor ataque aquí?

    
pregunta JETM 23.02.2017 - 14:07

2 respuestas

121

¡Lo estás haciendo bien!

Crear pruebas de regresión automatizadas es a menudo lo mejor que puede hacer para hacer que un componente sea refactorable. Puede ser sorprendente, pero estas pruebas a menudo se pueden escribir sin la comprensión completa de lo que hace el componente internamente, siempre y cuando se entiendan las "interfaces" de entrada y salida (en el significado general de esa palabra). Hicimos esto varias veces en el pasado para aplicaciones heredadas en toda regla, no solo para clases, y con frecuencia nos ayudó a evitar romper cosas que no entendíamos completamente.

Sin embargo, debe tener suficientes datos de prueba y asegurarse de tener una comprensión firme de lo que hace el software desde el punto de vista de un usuario de ese componente, de lo contrario, corre el riesgo de omitir casos de prueba importantes.

En mi humilde opinión es una buena idea implementar sus pruebas automatizadas antes , comience a refactorizar, no después, para que pueda realizar la refactorización en pequeños pasos y verificar cada paso. La refactorización en sí debería hacer que el código sea más legible, por lo que le ayuda a aumentar su comprensión de los elementos internos poco a poco. Así que los pasos del pedido en este proceso son

  1. entienda el código "desde afuera",
  2. escribir pruebas de regresión,
  3. refactor, lo que lleva a una mejor comprensión de los aspectos internos del código
respondido por el Doc Brown 23.02.2017 - 14:30
1

Una razón importante para escribir pruebas unitarias es que documentan el componente API de alguna manera. No entender el propósito del código bajo prueba es realmente un problema aquí. La cobertura del código es otro objetivo importante, difícil de lograr sin saber qué ramas de ejecución existen y cómo se activan.

Sin embargo, si es posible restablecer el estado limpiamente (o construir el nuevo objeto de prueba cada vez), se pueden escribir pruebas tipo "trash in-trash out" que solo alimentan una entrada mayormente aleatoria al sistema y observan la salida. .

Tales pruebas son difíciles de mantener, ya que cuando fallan, puede ser complejo decir por qué y cuán grave es. La cobertura puede ser cuestionable. Sin embargo todavía son mucho mejores que nada. Cuando dicha prueba falla, el desarrollador puede revisar los últimos cambios con más atención y, con suerte, detectar el error allí.

    
respondido por el h22 24.02.2017 - 16:49

Lea otras preguntas en las etiquetas