web-dev-qa-db-fra.com

couverture de branche eclemme pour l’interrupteur: 7 sur 19 manquées

J'ai ce système de commutation et j'utilise eclemma pour tester la couverture des succursales. Nous devons avoir au moins 80% de couverture de branche pour tout, alors j'essaie de tester le plus possible ..__ Cependant, eclemma me dit que ce système de commutation n'est pas complètement testé en termes de couverture de branche.

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;
        }

J'ai utilisé des tests JUnit simples pour analyser chacun de ces cas. Still eclemma indique ceci en jaune et indique "7 branches sur 19 manquées" ... Je dirais qu'il n'y a que 7 façons de passer par ce système de commutation (les 6 cas individuels + tous les cas non définis). 

J'ai essayé de chercher des questions similaires sur le débordement de pile. Certains d'entre eux avaient comme solutions à utiliser si/sinon pour une couverture complète. Je ne suis pas sûr que ce soit le seul moyen possible d'obtenir cette couverture.

Quelqu'un peut-il expliquer d'où proviennent toutes ces 19 succursales et comment je pourrais tester les 7 autres pour obtenir une couverture à 100% sur ce commutateur?

25
Gaargod

Le compilateur Java convertit le code de cas de commutation en un tableswitch ou en un lookupswitch. Le tableswitch est utilisé lorsqu'il n'y a que quelques espaces entre les différents cas. Sinon, la lookupswitch est utilisée.

Dans votre cas, une tableswitch est utilisée parce que les codes de hachage de vos cas sont très proches les uns des autres (contrairement au code référencé par 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
      }

Les nombres à gauche des deux points sont les codes de hachage ordonnés et les espaces vides entre eux, les nombres à droite sont les destinations des sauts. (En Java, le code de hachage d'un caractère est sa valeur ASCII.)

68 est le code de hachage de "D" (le plus bas), et 83 est le code de hachage de "S" (le plus élevé) .69 est la valeur de l'un des espaces entre les cas réels et sautera au cas par défaut.

Cependant, je suppose que EclEmma exclut ces branches du calcul de la couverture de tableswitch (elle abaisserait encore plus la couverture en raison des lacunes) . Nous avons donc 0 (compté) branches pour le moment.

Ensuite, une comparaison égale de la valeur de chaîne est effectuée à chaque destination de saut (sauf à celle du cas par défaut). Comme votre commutateur se compose de 6 cas, nous avons 6 destinations de saut six avec une comparaison égal.

Le code d'octet de la comparaison pour le cas "G" est ci-dessous:

  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 compte deux branches: soit la chaîne d'entrée et la chaîne de casse sont égales, soit elles ne le sont pas. Ainsi, nous avons 6 * 2 branches pour les comparaisons. (Le cas par défaut ne crée pas de branche.)

Ensuite, si les deux chaînes sont égales, l’index de la casse sera stocké (lignes de code octet 105-106 pour la casse "G"). Ensuite, un saut à la seconde tableswitch sera exécuté. Sinon, le saut sera exécuté directement.

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

Ce commutateur fonctionne sur l'index de casse précédemment stocké et passe au code de la casse (le cas "G" a l'index 0, le cas par défaut est le -1). EclEmma compte 7 branches (6 cas plus le cas par défaut).

En conséquence, nous avons 0 branches comptées dans la première tableswitch, 12 branches dans les comparaisons equals et 7 autres branches dans la seconde tableswitch. Au total, ceci résulte en 19 branches.


Vos tests ne couvrent aucune des 6 branches non égales. Afin de les couvrir, vous devez trouver une chaîne pour chaque cas différent de la condition de cas, mais qui a le même code de hachage . C'est possible, mais définitivement insensé ...

Le nombre de branches d’EclEmma sera probablement ajusté à l’avenir.

De plus, je suppose que vous n'avez pas de scénario de test qui ne correspond à aucun des scénarios (ainsi, le cas par défaut (implicite) n'est pas couvert.)

31
nrainer

Consultez le lien suivant: http://sourceforge.net/p/eclemma/discussion/614869/thread/80e770df/

Ci-dessous un extrait du lien ci-dessus:

Ceci pour un exemple avec un commutateur avec 3 cas:

C'est une observation assez intéressante. En regardant l'octet code on peut voir comment le compilateur Java gère le commutateur sur les chaînes . En réalité, il s’agit d’un processus en 3 étapes:

  1. Activer le code de hachage (3 branches, 1 par défaut)
  2. Pour chaque code de hachage, faites un égal (3 * 2 branches)
  3. Effectuez une dernière commutation pour l'exécution réelle des cas (3 branches, 1 par défaut) 

Nous avons donc un total de 14 branches qui ressemble étrange du point de vue du code source. Ce qui semble encore plus étrange est que vous en manquez trois. L'explication est l'étape 2 où la méthode equals est appliquée en plus après le code de hachage . Pour couvrir ces branches, vous devez également trouver d'autres chaînes avec le même code de hachage. C'est certainement quelque chose qui pourrait être filtré des rapports de couverture dans les futures versions de JaCoCo:
https://sourceforge.net/apps/trac/eclemma/wiki/FilteringOptions

0
owaism