Competencia de pruebas unitarias

12

Mis empleadores organizan una competencia mensual del día de prueba de la unidad. Un día entero se dedica a escribir pruebas unitarias, obviamente hacemos más pruebas durante todo el mes, pero este es un día completo, y el "ganador" de la competencia recibe un premio. Sin embargo, nos resulta difícil determinar quién es el ganador.

Estábamos asignando puntos para cada caso de prueba. Entonces, si escribiste una prueba unitaria como esta ...

for (int i = 0; i < 100; i++) {
  assertTrue(i*i, square(i));
}

Te darían 100 puntos. Obviamente, este es un ejemplo simplista, pero demuestra los problemas con la asignación de "puntos" a cada caso de prueba.

Somos principalmente una tienda Java y Javascript. Así que sugerí contar el número de ramas de código probadas como una métrica. Podemos contar fácilmente las ramas probadas a través de una herramienta de cobertura de código (como EclEmma). Sin embargo, no estoy seguro de cómo haríamos esto con nuestras pruebas de Selenium y obtener una cobertura de código en las fuentes de Javascript (¿alguna idea?)

¿Alguien tiene alguna sugerencia sobre cómo podríamos determinar mejor al ganador de esta competencia?

Editar

Sé cómo escribir pruebas unitarias, sé cómo escribir pruebas unitarias efectivas, no necesito ayuda para determinar qué probar. No tengo control sobre esta competencia, la competencia continuará. Entonces, agrego algo de información para mejorarlo o sigo jugando las pruebas (sí, las juego. Por supuesto que las juego. Hay premios que ganar)

Editar

Esta pregunta aquí obviamente no es un duplicado, aunque contiene información útil sobre cómo encontrar buenos casos de prueba, no proporciona ninguna métrica útil para evaluar la competencia.

Shaun
fuente
No exactamente. Me di cuenta desde el principio
Shaun
2
Parece que todavía no te das cuenta del alcance total. Cualquier medida de quién escribió los mejores casos de prueba será completamente subjetiva o tendrá estos problemas hasta cierto punto. La métrica que funcione mejor dependerá de sus objetivos para estas competiciones y de cuán maduros (es decir, poco probable que exploten la puntuación en lugar de escribir las mejores pruebas que puedan) son los concursantes.
De nuevo no. Me di cuenta de que se pueden jugar. No tengo control sobre esta competencia, pero me preguntaron "cómo podemos hacerlo mejor"
Shaun
13
¿Se consideraría una mejora no hacerlo una competencia? ¿Por qué todo tiene que ser una competencia? ¿Por qué no puedes colaborar? Quizás sería útil deshacerse de algunas de sus pruebas unitarias más inútiles y construir un buen conjunto de pruebas de regresión y humo útiles.
Thomas Owens
1
Estoy con Thomas ... el ganador debería ser el código base / cliente porque la calidad del código mejoró. Establezca un objetivo general / grupal basado en la cobertura del código de las pruebas unitarias ... + 5% sobre la corriente o lo que sea. ... y no juegues con el sistema por premios ... lo que sea que le haya sucedido a un trabajo bien hecho es su propia recompensa?
JeffC

Respuestas:

15

¿Alguien tiene alguna sugerencia sobre cómo podríamos determinar mejor al ganador de esta competencia?

Lo único que tiene sentido para mí es votar: cada desarrollador puede asignar algunos puntos a la prueba de cualquier otro desarrollador (excepto el suyo). Tal vez 3 puntos para la prueba, cree que es la "más efectiva", 2 puntos para el segundo y uno para el tercero. La prueba con más puntos gana. Puede dar mejores resultados cuando la asignación de puntos se realiza sin saber de antemano quién escribió la prueba en particular.

Como beneficio adicional, obtendrá todas sus pruebas revisadas por pares.

Doc Brown
fuente
2
Este fue mi pensamiento también. No hay otra forma de medir el valor de las pruebas.
Eric King
2
Sí, "una buena prueba" es algo tan subjetivo que necesita ser juzgado, ya sea por sus pares o por autoridades respetadas. La búsqueda de métricas solo conducirá a un gran esfuerzo desperdiciado y poco valor real. Puede ser interesante tener múltiples premios: la prueba más imaginativa, una prueba de "probar algo que antes se consideraba no comprobable", la mejor prueba de rendimiento, la prueba más efectiva, la prueba más oscura, la prueba más inteligente, la prueba más valiosa, la prueba más probable para los usuarios finales ...
timday
6

Entonces, si escribiste una prueba unitaria como esta ...

for (int i = 0; i < 100; i++) {
 assertTrue(i*i, square(i));
}

Te darían 100 puntos.

Le daría a esta persona 0 puntos (incluso si la prueba probara algo realmente relevante), porque las afirmaciones dentro de un bucle tienen poco sentido y las pruebas con afirmaciones múltiples (especialmente en forma de bucle o mapa) son difíciles de trabajar.

El problema es esencialmente tener una métrica que no pueda ser engañada [fácilmente]. Una métrica que se basa exclusivamente en el número de afirmaciones es exactamente la misma que los desarrolladores de pago por LOC escrito. Al igual que con el pago por LOC que conduce a un código enorme e imposible de mantener, su política real de la compañía conduce a pruebas inútiles y posiblemente mal escritas.

Si el número de afirmaciones es irrelevante, el número de pruebas también es irrelevante. Este es también el caso de muchas métricas (incluidas las combinadas) que uno podría imaginar para este tipo de situaciones.

Idealmente, estaría aplicando un enfoque sistémico. En la práctica, esto difícilmente puede funcionar en la mayoría de las empresas de desarrollo de software. Entonces puedo sugerir algunas otras cosas:

  1. Usar revisiones de pares para las pruebas y tener algo similar al número de métricas de WTF por minuto .

  2. Mida el impacto de esas pruebas a lo largo del tiempo en la cantidad de errores . Esto tiene varios beneficios:

    • Parece justo,
    • En realidad, se puede medir si recopila suficientes datos sobre informes de errores y su destino,
    • Realmente vale la pena!
  3. Use la cobertura de sucursal , pero combínela con otras métricas (así como también una revisión). La cobertura de sucursales tiene sus beneficios, pero probar el código CRUD solo para obtener una mejor calificación no es la mejor manera de pasar el tiempo de los desarrolladores.

  4. Decidan todos juntos cuáles son las métricas que desean aplicar por el momento (tales decisiones pueden no ser bienvenidas o incluso posibles en algunas empresas y equipos). Revise y cambie las métricas con frecuencia, escoja las que sean más relevantes y asegúrese de que todos entiendan claramente qué se mide y cómo.

Arseni Mourzenko
fuente
1
+1 por cero puntos. Otras objeciones serían AAA: organizar, actuar, afirmar; Pruebas parametrizadas; Sin copia del código de la implementación ...
thepacker
5

Supongo que su empleador organiza este día de prueba de la unidad para darle incentivos a las personas para que encuentren errores, para lograr una mayor cobertura del código y también para terminar teniendo más pruebas, que son útiles para siempre.

Por lo tanto, creo que tendría sentido que el ganador sea el desarrollador que encuentre la mayoría de los errores, o el desarrollador cuyas pruebas logran el mayor aumento en la cobertura del código.

Una prueba le otorgaría un punto si provoca que se abra una nueva entrada en su sistema de seguimiento de problemas / errores / defectos. Si una entrada ya está abierta para ese problema, no cuenta. Además, como se sugiere en los comentarios, los errores en su propio código no cuentan; solo los errores en el código de otras personas deben contar. Desafortunadamente, este enfoque no ofrece una gratificación instantánea porque pueden pasar algunos días hasta que todas las pruebas fallidas se analicen y se abran los problemas correspondientes. Además, esto puede no funcionar siempre; A medida que su sistema madure, puede comenzar a ser extremadamente raro descubrir errores agregando pruebas.

El aumento en la cobertura del código podría proporcionar una medición más objetiva de la mejora representada por las nuevas pruebas. Primero, la cobertura total del código deberá registrarse el día anterior a la competencia. Luego, cada desarrollador deberá mostrar de alguna manera el aumento en la cobertura del código que resulta de sus pruebas solo, sin tener en cuenta el aumento en la cobertura del código resultante de las pruebas escritas por otros desarrolladores. Esto significa que probablemente necesitará un árbitro que irá a la máquina de cada desarrollador y registrará la nueva cobertura del código antes de que se hayan realizado las pruebas de nadie.

Por cierto, tener en cuenta la cobertura del código proporciona una recompensa justa a las personas que escriben pruebas reales, en lugar de hacer cosas tontas como el ejemplo que proporcionó en la pregunta.

Mike Nakis
fuente
2
Suena prometedor ... pero luego el comportamiento de "jugar con el sistema" se convierte en una buena colección de errores conocidos para ser "descubiertos" en la próxima competencia de pruebas ... dilbert.com/strip/1995-11 -13
timday
3
Una opción es otorgar solo puntos por errores en el código que alguien más escribió.
Cel Skeggs
@ col6y tienes razón, eso también es bastante importante. Desafortunadamente, todavía hay formas de manipular el sistema. Por ejemplo, si su código invoca mi código para hacer su trabajo, mi código podría asegurarse de que su código sufra un "accidente".
Mike Nakis
3
Estoy en desacuerdo. Las pruebas unitarias, cuando se escriben recientemente, no son para encontrar errores en primer lugar , eso es una falacia. Pueden encontrar regresiones semanas o meses después de que se escribieron, pero lo más probable es que sea demasiado tarde para proporcionar una métrica útil para la competencia. Por lo general, escribe una prueba unitaria después de que se haya producido un error específico para asegurarse de que no obtendrá el mismo tipo de error más adelante en el futuro.
Doc Brown