¿Cómo ha hecho que las pruebas unitarias sean más agradables? [cerrado]

18

Si siempre te han gustado las pruebas unitarias, ¡bien por ti! Pero para los desafortunados que no nacieron con un gusto por él, ¿cómo han logrado que esta tarea sea más agradable?

Esta no es una pregunta de "cuál es la forma correcta de la prueba unitaria". Simplemente quiero saber pequeños trucos personales que reducen el aburrimiento (me atrevo a decir) de escribir pruebas unitarias.

Calles
fuente
1
Me encanta escribir pruebas unitarias y otras pruebas en parte porque casi todos los demás apestan (a veces también apestan al hacer herramientas que estoy probando). No, no soy un asco como desarrollador. Simplemente me gusta la usabilidad, la belleza visual y la automatización. La MbUnitbiblioteca ha cambiado mi vida. La prueba automática es importante. Las pruebas automáticas ahorran tiempo. Las pruebas automáticas ahorran dinero. Las pruebas automáticas pueden salvar vidas. La prueba automática es la única forma. La prueba automática es otra red de seguridad. Cuando soy una de las 50 personas que trabajan en una gran arquitectura, me siento como otro ladrillo en una pared. Con las pruebas unitarias tengo el control.
Trabajo
La pereza y la frustración en las pruebas unitarias es una reacción normal al trabajo que nuestro cerebro percibe como inútil. Odio escribir y mantener pruebas unitarias que tengan un ROI pequeño o negativo. Sin embargo, escribir pruebas útiles es una tarea agradable, pero es una habilidad en sí misma reconocer lo que es útil y lo que es basura. Hay un tipo que está escribiendo un libro sobre este tema basado en su blog, puede leer aquí: enterprisecraftsmanship.com/2016/06/01/…
KolA

Respuestas:

22

En primer lugar, estoy de acuerdo con usted: si está escribiendo sus pruebas unitarias en un código ya completado, o si está probando manualmente su código, también me parece extremadamente aburrido.

Creo que hay dos formas de pruebas unitarias para mí que realmente lo hacen agradable:

  1. Al usar Test Driven Development (TDD), escribir las pruebas primero me permite pensar en la siguiente funcionalidad o comportamiento que necesito en mi código. Encuentro conducir hacia mi meta final en pequeños pasos y ver un progreso tangible hacia esa meta cada pocos minutos extremadamente gratificante y agradable.
  2. Cuando hay errores, en lugar de ir directamente al depurador, es un desafío divertido encontrar una manera de escribir una prueba de unidad que falla y reproduce el error. Es extremadamente satisfactorio descubrir finalmente las circunstancias que hacen que su código falle, luego arreglarlo y ver la barra volverse verde para la nueva prueba fallida (y permanecer verde para todas sus pruebas existentes).
Paddyslacker
fuente
12

Presumida superioridad.

Solo estoy bromeando a medias. "¡Mírame, cultivando buenos hábitos de programación! Estas cosas de 'pruebas unitarias' son algo que yo desde hace diez años nunca hubiera hecho, ¡qué tonto! Y solo piensa en todos los errores que voy a atrapar como resultado de este trabajo aburrido y tedioso que estoy haciendo en este momento: ¡mi código será increíble! ¡Obtendré un aumento seguro! * "

* - No, no lo haré.

Me parece que es como hacer ejercicio o comer sano; hasta que los beneficios tangibles realmente entren en acción ("¡Santa bola, realmente estoy atrapando una tonelada de errores de regresión que se habrían colado en la producción!"), el orgullo moral de saber que estás haciendo lo correcto puede ayudarte a llevarte mediante.

BlairHippo
fuente
7

Por un lado, casi nunca me siento y escribo pruebas unitarias. Las pruebas unitarias son un medio para un fin, no un fin en sí mismas. Son una forma de responder "¿este código hace la tarea básica que se supone que debe hacer?"

Por ejemplo, algunas personas escribirán una función y luego abrirán una sesión interactiva para probarla con algunos valores y asegurarse de que funciona:

def fact x
  if x == 0
    1
  else 
    x * fact(x-1)
  end
end

>> fact 10
=> 3628800
>> fact 7
=> 5040

Pero ahora descubres un error:

>> fact -1
SystemStackError: stack level too deep
    from (irb):2:in `fact'
    from (irb):5:in `fact'
    from (irb):10

Entonces lo arreglas:

def fact x
  if x < 0
    raise "Can't take the factorial of a negative number"
  elsif x == 0
    1
  else 
    x * fact(x-1)
  end
end

>> fact -1
RuntimeError: Can't take the factorial of a negative number
    from (irb):3:in `fact'
    from (irb):10

Pero ahora realmente debería probar para asegurarse de que todavía funciona:

>> fact 10
=> 3628800
>> fact 7
=> 5040

Como puede ver, sigue repitiendo las mismas pruebas ... y tiene que comparar los resultados visualmente. Las pruebas unitarias son una forma de evitar la repetición en este caso; Reduce la cantidad de trabajo que necesita hacer. Y si bien este es un pequeño ejemplo tonto, en el mundo real, se vuelve cada vez más importante y cada vez más difícil de probar manualmente. Lo que esto significa, por supuesto, es que la gente simplemente no prueba los componentes individuales; solo prueban todo el programa. Pero luego surgen errores, y son mucho más difíciles de encontrar. O ocurren errores, y se corrigen, pero alguien introduce el mismo error de nuevo, porque nadie agregó un caso de prueba para asegurarse de que no sucedió. O alguien mira un gran fragmento de código y dice: "No tengo idea de lo que se supone que debe hacer, ya que no está documentado y no tiene pruebas ... si soluciono este error, no tengo idea si romperé algo más dependiendo de ello; tal vez solo reescriba esto desde cero ".

Las pruebas unitarias reducen todo el trabajo extra en estos casos. La mejor manera de hacerlos divertidos es asegurarse de que las personas entiendan todo el trabajo que están reemplazando, y la flexibilidad adicional que viene de saber qué se supone que debe hacer cada parte del código. Hasta cierto punto, las personas necesitan tener un poco más de experiencia con la escritura y el mantenimiento de una gran base de código para comprender la importancia de las pruebas unitarias; Si todo su código es algo que escriben una vez y tiran, nunca lo entenderán.

Y las pruebas unitarias no deben escribirse después del hecho, como una tarea adicional una vez que tiene un código que "sabe" que ya funciona. Las pruebas unitarias deben escribirse primero, o al menos (ya que a veces olvida escribirlas primero) justo después de escribir el código en cuestión. Esto se llama desarrollo basado en pruebas y puede ayudar a mejorar sus API; si escribe las pruebas que ejercitan las API primero, aprenderá dónde es difícil usar las API incluso antes de escribir el código, y puede rediseñar mucho más fácilmente que si solo agrega las pruebas después.

Brian Campbell
fuente
@Biran, estoy de acuerdo. Pero todo eso hace que sea lo "correcto". Pero, ¿cómo se hace agradable? Incluso un poco?
Calles
@Preets Es agradable porque evitas realizar pruebas manuales repetitivas. Es más divertido cuando lo haces primero , en lugar de después del hecho, porque se convierte en parte del proceso de diseño, no en una tarea después del hecho para el código que ya "funciona".
Brian Campbell
Entonces, ¿pasa tiempo haciéndolo mal, de modo que hacerlo DERECHO se siente divertido en comparación? ... Eso podría funcionar, en realidad ...
BlairHippo
@Biran, estoy de acuerdo, uno debe hacerlo "primero", no solo para eliminar el aburrimiento, sino que supongo que ES la forma correcta de hacerlo para obtener los verdaderos beneficios de las pruebas unitarias.
Calles
@Biran, gracias! Recientemente utilicé TDD en un proyecto hobby mío y cambió mi forma de pensar acerca de las pruebas unitarias.
Calles
5

No lo sé. Lo que definitivamente hace que las pruebas unitarias sean más agradables para mí es la idea de toda la depuración frustrante, larga, aburrida y poco gratificante que no tendré que pasar cada vez que realice un cambio en el software :)

back2dos
fuente
2
Eso es interesante. Porque personalmente, cuando alguien encuentra un error en mi código, entierro mi cabeza avergonzado, pero al mismo tiempo, el proceso de depuración para mí es realmente entretenido y mucho más divertido que la prueba de la unidad. Es como resolver un rompecabezas donde tienes que atrapar ese error furtivo.
Calles
@Preets: Estoy de acuerdo, a veces puede ser divertido, pero para mí, el diseño es mucho más interesante que la implementación. Por lo tanto, no me gusta pasar mucho tiempo en la implementación. Prefiero que sea sencillo y predecible, especialmente porque permite hacer horarios más confiables. Por mucho que disfrute el proceso de creación de software, creo que el resultado es decisivo.
back2dos
¡Oh, estoy completamente de acuerdo! Un sistema con errores aleatorios puede causar noches de insomnio ... ¡mi elección fue simplemente una preferencia en un mundo irreal donde nada más que divertirse importaba!
Calles
3

La engreída superioridad que sientes cuando registras un código que es sólido como una roca, robusto y estable. Y si escribe pruebas unitarias con una herramienta de cobertura de código, puede jactarse en su cheque en los comentarios de que su cobertura de código es del 90% o más.

C Johnson
fuente
3

Obviamente, existe la satisfacción del primer desarrollo de la prueba y la sensación que tiene cuando se combinan su diseño y las pruebas. Sin embargo, escribir pruebas para código preexistente / heredado puede ser frustrante y adormecedor. Cuando nuestro proyecto estaba en un patrón de mantenimiento, escribí pruebas para el código no probado usando el informe de cobertura como un juego. Puede crear un poco de competencia consigo mismo y / o con otros para aumentar los números de cobertura. De acuerdo, podría llevarlo demasiado lejos y crear algunas pruebas malas, pero puede ser un buen motivador.

Matt H
fuente
Dado que el código heredado generalmente no es fácilmente comprobable, me resulta difícil escribir buenas pruebas unitarias, por lo que no solo el proceso es doloroso, sino que el resultado (pruebas unitarias) tampoco es particularmente útil: - / Me parece muy frustrante ... Sin embargo, el juego de cobertura es bueno :)
Preets
1

Intenta entrar en el flujo . Establezca metas difíciles pero alcanzables para usted mismo. ¿Cuál podría ser un objetivo en las pruebas unitarias? Por ejemplo, intente escribir más rápido manteniendo la calidad. Las pruebas unitarias no requieren pensar demasiado, por lo que es poco probable que se confundan. Concéntrese en su objetivo y verifique con frecuencia para ver a medida que se acerca.

Tamás Szelei
fuente
ás, ¿por qué dices que la prueba unitaria no requiere pensar demasiado? Si trabaja con TDD implica mucho pensar. ¿No es eso cierto?
Calles
Tienes razón, no tomé TDD en cuenta.
Tamás Szelei
0

A veces, para motivarme, escribo mi "cobertura de código" actual al comienzo del día. Luego, cada vez que escribo una prueba y la apruebo, ejecutaré la suite y actualizaré el número de cobertura. Es divertido y me ayuda a recordar por qué estoy haciendo esto. (También hay otras razones, pero me gustan los números. ¡Tal vez solo soy yo!)

Marcie
fuente
0

Al no tratar de engañarme a mí mismo, puedo engañar a mi mente para que piense que las pruebas unitarias pueden ser disfrutables durante cualquier período de tiempo sostenible.

Aceptar la realidad de que las pruebas unitarias no están ahí para disfrutarlas me ayuda mucho, haciéndome dar cuenta de que estoy buscando algo en un lugar donde nunca se suponía que debía estar.

En estas breves excursiones mentales cuando llego al punto de percibir que las pruebas unitarias son lo que realmente es, es decir, una tarea cruel, insoportable y aburrida, me pregunto si puedo permitirme dejarlas ir, es decir, no tener Altas garantías sobre la corrección funcional.

Invariablemente, la respuesta es un rotundo "no".

Al aceptar mi destino, sigo empujando estos objetos cuadrados con letras, números y símbolos en frente de mí, que llamamos teclado, sabiendo por experiencia de primera mano que con cada clic del teclado, el final de la prueba de la unidad está más cerca de lo que ha sido alguna vez.

Bugfoot
fuente
No todas las pruebas son buenas o útiles. Esto es algo que los TDD'ers y otros evangelistas de prueba generalmente no mencionan. Apuesto a que en algunos raros momentos disfrutas de las pruebas unitarias cuando sabes que prueba una lógica compleja, la prueba es elegante y no está acoplada a la implementación, y odias cuando te obligan a probar basura trivial solo para lograr algún objetivo de cobertura de código lunático requerido por pautas del proyecto.
KolA
@KolA Tiene razón en que existen pruebas unitarias desafiantes que requieren creatividad, pero escribir pruebas unitarias sin fin puede absorber incluso las más interesantes.
Bugfoot