vicepresidencia ramas rama público publico politica poder organos legislativo legislativa justicia estructura ejecutiva división definicion colombia java testing switch-statement code-coverage eclemma

java - ramas - Cobertura de la rama de eclemma para el interruptor: 7 de 19 perdido



rama legislativa definicion (2)

Tengo este sistema de cambio y estoy usando eclemma para probar la cobertura de la sucursal. Estamos obligados a tener al menos el 80% en la cobertura de sucursales para todo, por lo que estoy tratando de probar lo más posible. Sin embargo, eclemma me dice que este sistema de cambio no está completamente probado en términos de cobertura de sucursales.

pos = p.getCurrentPosition().substring(0, 1); switch (pos) { case "G": goalkeepers++; break; case "D": defense++; break; case "M": midfield++; break; case "F": offense++; break; case "S": substitutes++; break; case "R": reserves++; break; }

Utilicé pruebas de JUnit directas para analizar cada uno de estos casos. Todavía el eclemma marca esto como amarillo y dice "7 de 19 ramas faltaron". Yo diría que solo hay 7 formas de pasar por este sistema de conmutación (los 6 casos individuales + todos indefinidos).

Intenté buscar preguntas similares en el desbordamiento de pila. Algunos de ellos tenían como soluciones para utilizar si / else para una cobertura completa. No estoy seguro si esta es la única forma posible de obtener esta cobertura.

¿Alguien puede explicar de dónde provienen estas 19 sucursales y cómo puedo probar estas 7 restantes para obtener una cobertura de sucursal del 100% en este caso de conmutador?


Consulte el siguiente enlace: http://sourceforge.net/p/eclemma/discussion/614869/thread/80e770df/

A continuación se muestra un fragmento del enlace anterior:

Esto para un ejemplo que tiene un interruptor con 3 casos:

Esta es una observación bastante interesante. Al observar el código de bytes, se puede ver cómo el compilador de Java maneja el conmutador en cadenas. En realidad es un proceso de 3 pasos:

  1. Encienda el código hash (3 ramas, 1 por defecto)
  2. Para cada código hash haga un igual (3 * 2 ramas)
  3. Haga un cambio final para la ejecución real de los casos (3 sucursales, 1 por defecto)

Así que tenemos un total de 14 sucursales que parecen extrañas desde el punto de vista del código fuente. Lo que parece aún más extraño es que te estás perdiendo tres. La explicación es el paso 2, donde el método de igualdad se aplica adicionalmente después del código hash. Para cubrir estas ramas también necesitarías encontrar otras cadenas con el mismo código hash. Esto es definitivamente algo que podría filtrarse de los informes de cobertura en futuras versiones de JaCoCo:
https://sourceforge.net/apps/trac/eclemma/wiki/FilteringOptions


El compilador de Java traduce el código de la caja del conmutador a un tableswitch oa un lookupswitch . El tableswitch se utiliza cuando solo hay unos pocos huecos entre los diferentes casos. De lo contrario, se utiliza el lookupswitch .

En su caso, se usa un tableswitch porque los códigos hash de sus casos están muy espaciados (a diferencia del código al que hace referencia Owaism):

16: tableswitch { // 68 to 83 68: 111 // ''D'' 69: 183 70: 141 // ''F'' 71: 96 // ''G'' 72: 183 73: 183 74: 183 75: 183 76: 183 77: 126 // ''M'' 78: 183 79: 183 80: 183 81: 183 82: 171 // ''R'' 83: 156 // ''S'' default: 183 }

Los números a la izquierda de los dos puntos son los códigos hash ordenados y los espacios vacíos entre ellos, los números a la derecha son los destinos de salto. (En Java, el código hash de un carácter es su valor ASCII).

68 es el código hash de "D" (el más bajo), y 83 es el código hash de "S" (el más alto). 69 es el valor de uno de los huecos entre los casos reales y saltará al caso predeterminado.

Sin embargo, asumo que EclEmma excluye estas ramas del cálculo de cobertura de un tableswitch de tableswitch (reduciría la cobertura aún más debido a las brechas). Así que tenemos 0 ramas (contadas) todavía.

A continuación, se realiza una comparación igual del valor de la cadena en cada destino de salto (excepto en el del caso predeterminado). Como su caja de conmutación consta de 6 casos, tenemos 6 seis destinos de salto con una comparación de iguales.

El código de bytes de la comparación para el caso "G" está debajo:

96: aload_3 97: ldc #10 99: invokevirtual #11 java/lang/Object;)Z 102: ifeq 183 105: iconst_0 106: istore 4 108: goto 183 111: aload_3

EclEmma cuenta dos ramas: o la cadena de entrada y la cadena de caso son iguales o no lo son. Por lo tanto, tenemos 6 * 2 ramas para las comparaciones. (El caso predeterminado no se ramifica.)

A continuación, si las dos cadenas son iguales, se almacenará el índice del caso (líneas de código de bytes 105-106 para el caso "G"). Luego se ejecutará un salto al segundo tableswitch . De lo contrario, el salto se ejecutará directamente.

185: tableswitch { // 0 to 5 0: 224 1: 237 2: 250 3: 263 4: 276 5: 289 default: 299 }

Este interruptor opera en el índice de caso previamente almacenado y salta al código en el caso (caso "G" tiene índice 0 , el caso predeterminado tiene -1 ). EclEmma cuenta con 7 sucursales (6 casos más el caso predeterminado).

En consecuencia, tenemos 0 ramas contadas en el primer tableswitch , 12 sucursales en las comparaciones de equals y otras 7 sucursales en el segundo tableswitch . Con todo, esto resulta en 19 ramas.

Sus pruebas no cubren ninguna de las 6 ramas diferentes. Para cubrir esto, necesitaría encontrar una cadena para cada caso que no sea igual a la condición del caso pero que tenga el mismo código hash. Es posible, pero definitivamente no sensible ...

Probablemente, el conteo de sucursales de EclEmma se ajustará en el futuro.

Además, creo que no tiene un caso de prueba que no coincida con ninguno de los casos (por lo tanto, el caso predeterminado (implícito) no está cubierto).