¿Cómo puede TDD para un error que solo se puede probar después de que se ha solucionado?

13

Aquí hay un ejemplo: mi aplicación web contiene elementos arrastrables. Al arrastrar un elemento, el navegador genera una "imagen fantasma". Quiero eliminar la "imagen fantasma" al arrastrar y escribo una prueba para este comportamiento.

Mi problema es que inicialmente no tengo idea de cómo solucionar este error y la única forma en que puedo escribir una prueba es después de haberlo solucionado.

En una función simple como let sum = (a, b) => a - b, puede escribir una prueba de por qué sum(1, 2)no es igual 3antes de escribir cualquier código.

En el caso que describo, no puedo probar, porque no sé cuál es la verificación (no sé cuál debería ser la afirmación).

Una solución al problema descrito es:

let dataTransfer = e.dataTransfer
let canvas = document.createElement('canvas');
canvas.style.opacity = '0';
canvas.style.position = 'absolute';
canvas.style.top = '-1000px';
dataTransfer.effectAllowed = 'none';

document.body.appendChild(canvas);
dataTransfer.setDragImage(canvas, 0, 0);

No podría haber sabido que esta era la solución. Ni siquiera pude haber escrito la prueba después de encontrar la solución en línea, porque la única forma de saber si realmente funcionaba era agregar este código a mi base de código y verificar con el navegador si tenía el efecto deseado. La prueba tuvo que escribirse después del código, que va en contra de TDD.

¿Cuál sería el enfoque TDD para este problema? ¿Escribir la prueba antes del código es obligatorio u opcional?

maximedupre
fuente
2
Haz tu investigación entonces. Encuentre una solución ... luego escriba su prueba, arreglo y refactorice. Las pruebas no están destinadas a (solo) verificar que su código funcione, sino a probar en el futuro su solución completa. Inicialmente crea su prueba para que falle, entonces, ¿qué propiedad probará? Esa es una forma de comenzar.
Juan Carlos Eduardo Romaina Ac
@Kilian Foth: veo sus buenas intenciones al cambiar el título de la pregunta, pero su edición invalida partes de mi respuesta. Además, su nuevo título, en mi humilde opinión, no se ajustaba bien al cuerpo de la pregunta. Así que hice una reversión, sin ofender.
Doc Brown

Respuestas:

26

Cuando lo entendí correctamente, ni siquiera puede escribir una prueba automatizada confiable para su ejemplo de "imagen fantasma" después de encontrar una solución, ya que la única forma de verificar el comportamiento correcto es mirar la pantalla y verificar si no hay imagen fantasma nunca más. Eso me da la impresión de que su titular original hizo la pregunta incorrecta. La verdadera pregunta debería ser

  • ¿Cómo probar automáticamente un cierto comportamiento de una interfaz gráfica de usuario?

Y la respuesta es: para varios tipos de problemas de IU, no lo hace . Claro, uno puede intentar automatizar la interfaz de usuario que muestra el problema de alguna manera, e intentar implementar algo como una comparación de captura de pantalla, pero esto a menudo es propenso a errores, quebradizo y no rentable.

Es especialmente imposible el diseño de interfaz de usuario de "prueba de manejo" o las mejoras de la interfaz de usuario mediante pruebas automatizadas escritas por adelantado. Usted "impulsa" el diseño de la interfaz de usuario haciendo una mejora, muestra el resultado a un humano (usted mismo, algunos probadores o un usuario) y solicita comentarios.

Acepte el hecho de que TDD no es una bala de plata, y para algunos tipos de problemas, las pruebas manuales aún tienen más sentido que las pruebas automatizadas. Si tiene un proceso de prueba sistemático, tal vez con algunos probadores dedicados, lo mejor que puede hacer es agregar el caso a su plan de prueba.

Doc Brown
fuente
En general, las pruebas de IU no son triviales; puede fijar, es decir, hash, una imagen generada, puede simular / automatizar, puede grabar macros, puede usar una solución patentada, puede usar pruebas manuales, depende de la situación y de cuán necesarias sean las pruebas automatizadas de UI para su proyecto.
esoterik
1
@esoterik: sí, y todas estas técnicas automatizadas son propensas a errores y frágiles, como ya escribí. El único enfoque no frágil que conozco es la prueba manual.
Doc Brown
3
Gracias por responder. Creo que tienes razón, erróneamente espero encontrar una bala de plata en TDD. No parece haber una forma eficiente de probar lo que quiero probar: la comparación de capturas de pantalla y todo lo anterior no parecen dar un ROI suficiente. La comparación de capturas de pantalla en particular parece llevar mucho tiempo y, como dijiste, propenso a errores.
maximedupre
1
@maximedupre: encontré este anuncio para una herramienta que intenta abordar el problema, pero sin embargo, el artículo parece estar de acuerdo con mi respuesta en general.
Doc Brown
5

¿Cuál sería el enfoque TDD para este problema? ¿Escribir la prueba antes del código es obligatorio u opcional?

Una forma es aplicar un análogo de una solución de espiga .

James Shore lo describió de esta manera:

Realizamos pequeños experimentos aislados cuando necesitamos más información.

La idea básica es que dejes las herramientas de diseño mientras descubres lo que está sucediendo. Una vez que te orientas, retomas las herramientas de diseño nuevamente.

El truco: trae el conocimiento de su investigación de vuelta a su base de código de producción, pero no trae el código . En cambio, lo recrea mientras usa sus técnicas de diseño disciplinado.

Caballos de carreras.

EDITAR:

¿Cómo puede automatizar una prueba si el defecto solo puede ser visto por un ojo humano?

Me gustaría sugerir una ortografía ligeramente diferente: "¿Cómo puede automatizar una prueba si la automatización de la prueba no es rentable?"

La respuesta, por supuesto, es "no lo haces". En su lugar, intente separar su implementación en dos partes: una gran parte donde las pruebas son rentables y una parte más pequeña que es demasiado simple de romper.

Hay dos formas de construir un diseño de software: una es hacerlo tan simple que obviamente no haya deficiencias - CAR Hoare

Entonces, cuando trabajemos con código de terceros, tendremos una capa muy delgada de código que actúa como un proxy para la biblioteca de terceros. En la prueba, reemplazamos ese shell con un "doble de prueba", que verifica el protocolo , sin preocuparse de que produzca los efectos deseados.

Para probar la integración de nuestros códigos con el código real de terceros, confiamos en otras técnicas (verificación visual, llamadas de soporte técnico, optimismo ...)

Puede ser útil mantener algunos artefactos de demostración, para que pueda verificar que sus suposiciones aún se mantienen cuando actualiza la biblioteca de terceros.

VoiceOfUnreason
fuente
Me encanta lo que James Shore tiene que decir. Actualmente estoy siguiendo el screencast www.letscodejavascript.com y estoy aprendiendo mucho. Leeré los enlaces a los que me apuntaste.
maximedupre
Tienes razón, leí más sobre TDD y picos. En realidad, necesita saber cómo se ve el código que está tratando de verificar antes de intentar probarlo. TDD no puede enseñarle nada que aún no sepa, pero puede mostrarle algunas cosas que necesita aprender, parafraseando a James Shore. En ese sentido, me gustaría proponer un paso adicional en TDD: Spike, Test, Fail, Pass, Refactor.
maximedupre
0

Solo desde una perspectiva diferente, las pruebas en torno a la interfaz de usuario / GUI se pueden hacer algo mejor con respecto a las pruebas de aceptación (pruebas centradas en el flujo de trabajo de negocios / características).

Para la web, creo que los marcos como el selenio webdriver tienen el potencial de acercarse a la prueba correcta, pero la sobrecarga para comenzar podría ser un poco grande, y es un cambio en el flujo visto con TDD con respecto a las pruebas unitarias .

La parte que ayudaría específicamente con su situación es algo llamado Modelo de objetos de página ( https://www.guru99.com/page-object-model-pom-page-factory-in-selenium-ultimate-guide.html ). Esto logra una asignación explícita de la GUI en tiempo de ejecución a algún código, ya sea nombrando métodos / eventos / miembros de la clase.

Los principales argumentos en contra de esto serían los gastos generales, y que estos gastos generales generalmente podrían verse al final del ciclo de desarrollo. La sobrecarga es que las pruebas requieren un contenedor que parece crear un trabajo duplicado.

En el futuro, dependería del costo / beneficio del equipo y el negocio, por lo que podría ser un tema beneficioso para discutir para determinar las expectativas y puntos de vista.

eparham7861
fuente
Realmente estaba probando pruebas e2e / funcionales (con selenium webdriver) en TDD recientemente, pero la sobrecarga es definitivamente demasiado grande como dijiste. No puede ser un desarrollador eficiente y hacer TDD con pruebas e2e. Estaba usando POM, pero el único beneficio que me dio fue una arquitectura mejorada en mi base de código de prueba.
maximedupre
Sí, creo que una opción más viable que he visto de diferentes compañías a diferentes equipos sería incorporar un proceso SQA más manual, donde un miembro del equipo / equipo está designado para realizar solo pruebas manuales de la interfaz de usuario. Las pruebas en su mayoría tienen capturas de pantalla y documentación paso a paso. Por lo menos, algo así produciría alguna evidencia de prueba hacia una aplicación.
eparham7861
0

¿Cómo se ve una imagen fantasma? Si creó una interfaz de usuario ficticia de un color conocido, ¿dónde puso su componente arrastrable? ¿Habría un color específico presente si hubiera una imagen fantasma?

Luego, la prueba podría probar la ausencia del color de la imagen fantasma.

Tal prueba sería razonablemente duradera y factible.

Esben Skov Pedersen
fuente
Factible, sí. Durable - depende. Solo cambiar el color / tema de su interfaz de usuario podría romper su / s prueba / s, eso no me parece demasiado duradero.
Sean Burton
1
No probarías toda tu IU. Crearía una interfaz de usuario ficticia para el componente de arrastrar y soltar.
Esben Skov Pedersen
No estoy seguro de cómo lograr lo que estás sugiriendo. Una imagen fantasma en mi caso sería una réplica semi opaca del elemento que se está arrastrando. La imagen fantasma sigue al cursor en todo momento mientras se produce el arrastrar y soltar.
maximedupre
Si. Tendría que automatizar el arrastre. No sería una prueba unitaria sino más bien una prueba e2e.
Esben Skov Pedersen