Mi trabajo actual es principalmente escribir código de prueba GUI para varias aplicaciones en las que trabajamos. Sin embargo, encuentro que tiendo a copiar y pegar mucho código dentro de las pruebas. La razón de esto es que las áreas que estoy probando tienden a ser lo suficientemente similares como para necesitar repetición, pero no lo suficientemente similares como para encapsular código en métodos u objetos. Encuentro que cuando trato de usar clases o métodos de manera más extensa, las pruebas se vuelven más engorrosas de mantener y, a veces, absolutamente difíciles de escribir en primer lugar.
En cambio, generalmente copio una gran porción de código de prueba de una sección y la pego en otra, y hago los cambios menores que necesito. No uso formas más estructuradas de codificación, como el uso de más principios o funciones OO.
¿Otros codificadores se sienten así al escribir el código de prueba? Obviamente quiero seguir los principios DRY y YAGNI, pero encuentro que el código de prueba (código de prueba automatizado para pruebas GUI de todos modos) puede hacer que estos principios sean difíciles de seguir. ¿O solo necesito más práctica de codificación y un mejor sistema general de hacer las cosas?
EDITAR: La herramienta que estoy usando es SilkTest, que está en un lenguaje propietario llamado 4Test. Además, estas pruebas son principalmente para aplicaciones de escritorio de Windows, pero también he probado aplicaciones web con esta configuración.
fuente
Respuestas:
Los casos de prueba copiados y luego editados a menudo están bien.
Las pruebas deben tener la menor cantidad de dependencias externas posible y ser lo más sencillo posible. Los casos de prueba tienden a cambiar con el tiempo, y anteriormente los casos de prueba casi idénticos pueden divergir repentinamente. Actualizar un caso de prueba sin tener que preocuparse por romper otros casos es una buena cosa.
Por supuesto, el código repetitivo que es idéntico en muchos casos de prueba y tiene que cambiar en concierto puede y debe ser eliminado.
fuente
La repetición es la raíz de todo mal
¡Eso es correcto! La repetición es la raíz de todo mal . Probablemente fue Knuth diciendo en su libro "La optimización prematura es la raíz de todo mal", pero creo que es la repetición.
Cada vez que miras un programa o estás escribiendo uno y descubres algún tipo de repetición: ¡elimínalo! Mátalo inmediatamente ... ¡lo que sea, pero deshazte de él !
Cada vez que introduje algún tipo de repetición y tuve que arreglar un error allí, olvidé arreglar la réplica ... (Donald Knuth) Entonces, cada vez que haya una repetición, elimínela lo mejor que pueda, no piratee !
Piense en un diseño limpio y esbelto (como encapsular sus bloques de código repetidos en clases auxiliares) y escriba algunas pruebas antes de cambiar algo (solo para asegurarse de no romper algo). Esto es cierto para cualquier código escrito y los códigos de prueba no son una excepción.
Aquí hay una buena lectura de Code Horror que me inspira: una modesta propuesta para copiar y pegar la escuela de reutilización de código .
fuente
Todavía es bastante malo cortar y pegar. Hay algunos problemas
Es posible que sus pruebas sean frágiles, porque es vulnerable a algo que requiere un cambio en todo ese código copiado y pegado. ¿Tendrás que reescribir todas las pruebas?
Si no puede encapsular la lógica en métodos auxiliares fuera de sus pruebas, no puede escribir pruebas de esos métodos auxiliares. Escribir pruebas de métodos de prueba suele ser demasiado difícil de hacer, ya que debe romper su código para probar la prueba. Pero puede probar métodos auxiliares de prueba.
Bien puede hacer que las pruebas sean menos legibles. Un gran bloque de código copiado puede ser más difícil de leer que una llamada al método auxiliar con un nombre descriptivo.
Todo lo que he enumerado es algo que puede ser un problema. Si encuentra que ninguno de ellos en realidad son un problema, entonces por supuesto que está bien.
fuente
Solía estar de acuerdo contigo. Pero luego, con el tiempo, descubrí que cada cambio que hacía (particularmente los cambios DI en las pruebas unitarias) requería numerosas pruebas para cambiar y eso era engorroso. Ahora me suscribo a la escuela de DRY, incluso cuando escribo exámenes.
Para las pruebas de GUI, es posible que desee mirar el patrón de PageObject para reducir el código repetido.
fuente
Recomendaría elegir patrones XUnit. Solía tener exactamente el mismo problema hasta que comencé a aprovechar ese libro. El patrón Madre de objeto suena como si fuera el más útil para su escenario.
Como alguien más mencionó, encapsular adecuadamente este código de configuración puede ser oneroso, pero tener que cambiarlo en todos los lugares que copia y pega es aún más.
fuente
Object Mother pattern
código de inicialización común.Si las personas intentan limitar la repetición cuando pueden, sí. Pero la recompensa depende de la situación. Esto podría volver al debate sobre las "mejores prácticas". Pero la pregunta es qué es lo mejor para usted en esta situación. Hay excepciones a cada regla.
Un par de cosas que pediría son: 1) ¿Qué posibilidades hay de que cambie esta funcionalidad que se está probando en la UAT? Si es poco probable que cambie, entonces hay menos posibilidades de que tenga que actualizar cada uno de sus conjuntos de código. 2) Si hay un cambio en UAT, ¿afectará siempre a cada conjunto del código copiado o podría afectar solo uno o dos conjuntos? Si puede estar aislado y solo requiere un cambio en un conjunto, puede ser útil separar las cosas. 3) ¿Qué tan complejo será el método inicial si intenta que maneje todos los escenarios? ¿Está agregando muchos bucles anidados if / else / loops? Si comienza a hacer todas las ramificaciones, puede terminar con un código que es difícil de comprender. ¿Sería más fácil realizar la actualización en cada texto copiado que volver a visitar toda la lógica de ramificación?
Si está atascado, copie / pegue / altere, creo que desea agregar comentarios como 'Esto se copia en el método xyz'. De esa forma, se le recordará que actualice todas las versiones pegadas del código. O (viniendo de otro usuario de SilkTest) podría agregar un archivo inc separado que se centraría solo en este código repetido. De esa manera, tiene todas las variaciones en un solo lugar y puede ver fácilmente los diferentes métodos que requerirían una actualización.
fuente
Un gran procedimiento
Un pensamiento: Parece que está tratando de evitar el código de cortar y pegar haciendo métodos como:
Muchos pequeños procedimientos (kit de herramientas)
¿También has considerado el enfoque opuesto? En lugar de pasar un millón de parámetros a un gran procedimiento testScreen (), tal vez cree su propio marco o kit de herramientas de pequeños procedimientos auxiliares que usted pueda preparar cuando los necesite. Me gusta:
Aún puede cortar y pegar estos procedimientos en cada pantalla, pero está cortando y pegando fragmentos de código más pequeños y creando fragmentos de elementos comunes que no se cortan y pegan (el contenido de cada pequeño procedimiento).
Cortar y pegar
El único momento en que el código cortado y pegado no me ha mordido fue cuando el código fue desechado antes de que tuviera que cambiarlo. Mi mayor preocupación con las pruebas de IU es qué tan rápido se vuelven obsoletas. Si descubre que tira todo su código antes de cambiarlo, entonces tal vez haya encontrado un nicho donde cortar y pegar está bien. Además, no es tan malo cuando no hay código aguas abajo del código cortado y pegado (por ejemplo, en la interfaz de usuario de una aplicación). Si está pegando más de 3 líneas, realmente consideraría hacer algo al respecto. ¡Al menos tome medidas para minimizarlo!
Prueba automatizada de IU
Demonios, si puede demostrar una mayor productividad con las pruebas de IU automatizadas que las pruebas manuales con cualquier técnica (el costo de escribir / mantener pruebas automatizadas es menor que las pruebas manuales cada vez, pero la calidad es la misma) Creo que debería escribir un documento. ¡Lo leería! Ahora puedo ver el título, "¡Cortar y pegar, codifique una ganancia neta para las pruebas de IU!"
fuente
En realidad no está tan mal. De hecho, si encuentra que ciertos patrones de código se usan con mucha frecuencia y los cambios son muy rutinarios (como algunas cadenas o valores de parámetros), incluso podría escribir un generador de código que genere código de prueba repetitivo basado en un pequeño (- ish?) lista de entrada de valores que cambian. He hecho esto (código de prueba generado) muchas veces, usando archivos por lotes, scripts de SQLPlus, incluso macros de Excel (suena feo, pero las variables para los diferentes scripts de prueba ya estaban en una hoja de cálculo) y puede ser un gran ahorro de tiempo . La cuestión es que si algo cambia en la estructura general del código de caso de prueba repetitivo, puede regenerar lo que necesite.
fuente
Esto es lo mismo que la mayoría de las otras respuestas, pero de una manera que un gerente no técnico puede entender.
Imagine el siguiente escenario de error:
¿Qué harás?
De acuerdo con mi experiencia:
Al introducir pruebas automatizadas de gestión como "copiar y pegar pruebas": obtiene muchas pruebas en poco tiempo.
Después de algunos de los "escenarios de error", la administración prefiere (4) porque arreglar "copiar y pegar pruebas" es muy costoso.
Hacerlo bien en primer lugar (3) no será tan rápido pero aumenta las posibilidades de que las pruebas sobrevivan
fuente