Cours Génie Logiciel Avancé


Gestion de notes (3/6)

Couverture de code par les tests

Il est utile de vérifier la couverture de code avec un outil externe à votre IDE comme IntelliJ IDEA. Vous pouvez faire cela grâce à Jacoco. Pour utiliser Jacoco via gradle, il faut :

  1. Rajouter les plugins pour jacoco au début du fichier build.gradle.kts de votre projet avec les lignes suivantes :

    plugins {
        id("jacoco")
        id("org.barfuin.gradle.jacocolog") version "4.0.0"
    }
  2. Configurer votre projet pour que la couverture soit automatiquement lancé après les tests en rajoutant les lignes suivantes au fichier build.gradle.kts :

    tasks.test {
        finalizedBy(tasks.jacocoTestReport) // report is always generated after tests run
    }
  3. Configurer votre projet pour que la couverture génère un fichier xml (build/reports/jacoco/test/jacocoTestReport.xml) et html (build/reports/jacoco/test/html/index.html) :

    tasks.jacocoTestReport {
        dependsOn("test")
        reports {
            xml.required = true
            html.required = true
        }
    }
  4. Modifier le fichier .gitlab-ci.yml à la racine de votre projet pour que les tests et la couverture soient lancés à chaque push.

Mocking pour les tests unitaires

On vous demande d’utiliser un framework de mocking pour écrire des tests unitaires. Un framework de mocking permet de simuler le comportement d’objets complexes ou externes, facilitant ainsi les tests unitaires en isolant les composants à tester.

Pour utiliser Mockito via gradle, il faut ajouter les lignes suivantes dans le fichier build.gradle.kts :

dependencies {
    testImplementation("org.mockito:mockito-junit-jupiter:5.21.0")
    testImplementation("org.mockito:mockito-core:5.21.0")
}

Afin d’éviter des warnings à l’exécution des tests, il est conseillé de modifier la configuration de la JVM pour les tests en modifiant les lignes suivantes dans le fichier build.gradle.kts :

tasks.test {
    finalizedBy("jacocoTestReport") // ligne déjà ajouté précédemment
    jvmArgs = listOf(
        "-XX:+EnableDynamicAgentLoading", "-Xshare:off"
    )
}

Les transparents du troisième cours donnent des explications pour utiliser Mockito.

Outils d’analyse de code

Sur un projet logiciel, il est important d’analyser statiquement le code afin de

  • déceler des bugs ou des failles potentielles ;
  • vérifier que le code respecte des bonnes pratiques.

On vous demande donc d’utiliser différents outils d’analyse de code afin d’améliorer votre code et

SpotBugs

SpotBugs est un analyseur statique de programmes Java. Il s’agit d’un fork du projet FindBugs, qui n’est plus aujourd’hui maintenu. Ils sont l’un comme l’autre libres de droit. SpotBugs comme de nombreux analyseurs statiques définit et utilise des motifs de bug et réalise donc une analyse approchée. Il est donc possible que certains bugs signalés n’en soit pas vraiment. Il s’agit de “faux positifs”. Il est donc possible que, malgré une écriture soignée du code, certains bugs signalés ne puissent pas être éliminés. SpotBugs travaille sur le bytecode Java et fonctionne donc qu’une fois le code compilé.

Pour lancer spotbugs via gradle, il faut :

  1. Rajouter le plugin au début du fichier build.gradle.kts de votre projet avec les lignes suivantes :

    plugins {
        id("com.github.spotbugs") version "6.4.8"
    }
  2. Spécifier la version utilisée du logiciel en rajoutant les lignes suivantes dans le fichier build.gradle.kts

    spotbugs {
      toolVersion = '4.9.8'
    }
  3. Lancer la tâche gradle spotbugsMain (dans verification) pour le code dans src/main et spotbugsTest pour le code dans src/test

PMD

L’analyseur PMD est un autre outil permettant l’analyse de code Java. Contrairement à SpotBugs, PMD travaille sur le code source Java du programme et est un outil fortement configurable puisque les règles servant à l’analyse sont définies extérieurement au logiciel dans un fichier xml.

Pour lancer PMD via gradle, il faut :

  1. Rajouter le plugin au début du fichier build.gradle.kts de votre projet avec les lignes suivantes :

    plugins {
        id("pmd")
    }
  2. Spécifier la version utilisée du logiciel et les règles utilisées en rajoutant les lignes suivantes dans le fichier build.gradle.kts

    pmd {
      isConsoleOutput = true
      toolVersion = "7.16.0"
      rulesMinimumPriority = 5
      ruleSets = listOf("category/java/errorprone.xml", "category/java/bestpractices.xml")
    }
  3. Lancer la tâche gradle pmdMain (dans other) pour le code dans src/main et pmdTest pour le code dans src/test

Sonarlint

SonarLint est un autre outil d’analyse de code qui permet de détecter des erreurs éventuelles dans votre code.

  1. Rajouter le plugin au début du fichier build.gradle.kts de votre projet avec les lignes suivantes :

    plugins {
        id("name.remal.sonarlint") version "7.0.1"
    }
  2. Lancer la tâche gradle sonarlintMain (dans verification) pour le code dans src/main et sonarlintTest pour le code dans src/test

Injection de dépendances

Une première amélioration de code est d’utiliser un outil d’injection de dépendance comme Guice. Pour utiliser Guice, il vous faut ajouter les lignes suivantes dans le fichier build.gradle.kts :

dependencies {
    implementation("com.google.inject:guice:7.0.0")
    implementation("com.google.guava:guava:33.5.0-jre")
}

Les transparents du troisième cours donnent des explications pour utiliser Guice. Vous pouvez vous inspirer du dépôt utilisé en cours pour montrer l’utilisation de Guice. L’idée sera d’utiliser Guice pour injecter le DAO dans la partie controller de votre applicationafin d’utiliser des DAO JDBC demandés dans le TP précédent pour le code de production et les DAO en mémoire pour les tests.