4 votes

Sonar + JaCoco ne comptant pas le code Groovy comme couvert

J'ai une classe Groovy avec une seule méthode statique :

class ResponseUtil {
    static String FormatBigDecimalForUI (BigDecimal value){
        (value == null || value <= 0) ? '' : roundHalfEven(value)
    }
}

Il a un ou plusieurs cas de test :

@Test
void shouldFormatValidValue () {
    assert '1.8' == ResponseUtil.FormatBigDecimalForUI(new BigDecimal(1.7992311))
    assert '0.9' == ResponseUtil.FormatBigDecimalForUI(new BigDecimal(0.872342))
}

@Test
void shouldFormatMissingValue () {
    assert '' == ResponseUtil.FormatBigDecimalForUI(null)
}

@Test
void shouldFormatInvalidValue () {
    assert '' == ResponseUtil.FormatBigDecimalForUI(new BigDecimal(0))
    assert '' == ResponseUtil.FormatBigDecimalForUI(new BigDecimal(0.0))
    assert '' == ResponseUtil.FormatBigDecimalForUI(new BigDecimal(-1.0))
}

Il en résulte 6/12 branches couvertes selon le Sonar/JaCoCo :

Half Code Coverage

J'ai donc modifié le code pour qu'il soit plus... verbeux. Je ne pense pas que le code original soit "trop intelligent" ou quelque chose comme ça, mais je l'ai rendu plus explicite et plus clair. Donc, le voici :

static String FormatBigDecimalForUI (BigDecimal value) {
    if (value == null) {
        ''
    } else if (value <= 0) {
        ''
    } else {
        roundHalfEven(value)
    }
}

Et maintenant, sans avoir changé quoi que ce soit d'autre, Sonar/JaCoCo déclare qu'il est entièrement couvert :

JaCoCo 100% Coverage

Pourquoi en est-il ainsi ?

3voto

Peter Niederwieser Points 36369

Je ne sais pas si cela s'applique à votre exemple concret, mais gardez à l'esprit que les outils de couverture de code ne fonctionnent généralement pas bien pour les langages alternatifs de la JVM, à moins qu'ils ne les prennent explicitement en charge. Cela est dû au fait que pratiquement tous ces langages génèrent du byte code supplémentaire qui ne peut être exécuté que dans certains cas. Par exemple, Groovy peut générer du code à octets pour un chemin lent et un chemin rapide, et peut décider de l'un ou l'autre automatiquement, sans que l'utilisateur ait son mot à dire.

La situation pourrait s'améliorer avec Groovy 3.0, qui sera conçu autour de Java invokedynamic, ce qui signifie qu'il faudra générer moins de code octet "magique". En attendant, j'ai entendu dire que Clover avait un support explicite de Groovy, bien que je ne sache pas s'il est à jour.

1voto

Richard Vowles Points 233

Il s'avère donc que le plugin Jacoco pour Sonar recherche explicitement du code Java. Je le sais, car je l'ai débogué. Il décode le fichier jacoco exec et suppose que tout fichier est un JavaFile, ce qu'il ne trouve pas, et dit alors que vous n'avez pas d'information de couverture.

Pour cette raison, j'ai récupéré le code source du plugin Jacoco (il a disparu de leur dépôt Subversion et n'est jamais apparu sur Github à ma connaissance) et l'ai intégré dans un nouveau plugin Groovy. Ma mise à jour utilise Codenarc 0.18.1 (qui augmente les Narc de 32 à 305) et reconnaît tout type de fichier Jacoco - le code du plugin existant est inutilement erroné.

La source est ici : https://github.com/rvowles/sonar-groovy - Il suffit de le compiler et de le placer dans votre répertoire d'extensions/plugins.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X