web-dev-qa-db-fra.com

Comment calculer la couverture de code des tests Selenium par rapport au code d'application Web

J'ai une exigence pour capturer la couverture de code de mes tests Selenium à la quantité de code source dans le code serveur (code source d'application Web) couvert.

Par exemple, les tests de fonctionnalité de connexion doivent capturer la quantité de code couverte dans l'application Web pour la fonction de connexion.

Sinon, vous devez savoir quel package ou quelle classe il a touché dans le code d'application Web pour un scénario effectué. Par exemple, une connexion

Je n'ai pas pu trouver de solution appropriée, bien que j'aie découvert l'outil de couverture de code Jacoco et essayé quelques exemples avec l'utilisation du plugin Jacoco Jenkins, mais il n'y a pas de succès.

Je ne suis pas conscient de la possibilité. Veuillez me fournir une suggestion sur la façon d'y parvenir, merci d'avance

26
Vigneshwaran

Assurez-vous de le faire. Notez bien si vous utilisez Gradle, Maven ou ANT. Mais le concept suivant est très similaire à tout système de construction.

  1. Vous devez avoir un artefact d'application .war/.ear que vous devez exécuter derrière Tomcat/similaire.
    • Vous devez également vous assurer que vous avez compilé votre code principal en mode débogage, sinon jacoco ne sera pas content.
    • Par exemple, l'option -g dans Java et une option de débogage similaire (si vous utilisez groovy).


tasks.withType(Compile) {
    options.debug = true
    options.compilerArgs = ["-g"]
}


  1. Disons que vous avez le .war et que vous utilisez Tomcat. Puis lors du démarrage de Tomcat.
    • Dans le script de démarrage de Tomcat, assurez-vous d'indiquer à la JVM de Tomcat où se trouve le fichier jacocoagent.jar et de transmettre d'autres paramètres. CECI est le PRINCIPAL point manquant que nous voyons parfois (alias ne pas attacher jacoco à la session JVM cible et essayer d'obtenir une couverture de code).

Par exemple: je démarre mon script Tomcat avec le paramètre suivant passé à Tomcat (-Dxxxx = chemin de valeur)

PROJ_EXTRA_JVM_OPTS=-javaagent:Tomcat/jacocoagent.jar=destfile=build/jacoco/ST/jacocoST.exec,append=false

Fondamentalement, le script de démarrage de Tomcat aurait -Dparameter = valeur, vous pouvez passer le paramètre ci-dessus (Linux/Unix export la variable) à la portée de la JVM Tomcat/Target.

La ligne de paramètres ci-dessus, lorsqu'elle est envoyée à Tomcat, attachera le fichier .jar de l'agent JACOCO au "TARGET" (alias Tomcat JVM). Ici, vous dites à Tomcat d'aller chercher le fichier jacocoagent.jar d'un réalisateur appelé "Tomcat" sous votre espace de travail. Il va créer un fichier jacoco .exec nommé "jacocoST.exec" (alias fichier jacoco exec pour Selenium Test) sous le dossier build/jacoco/ST (j'utilise Gradle donc Gradle crée un dossier "build" à chaque fois que vous exécutez une compilation/compilation/test/integrationTest/customSeleniumTaskThatYouMightHaveCreated).

REMARQUE: Cela signifie que vous n'avez PAS besoin de spécifier la section jacoco dans la tâche de test (car cela s'exécutera dans la JVM de vos systèmes BUILD Gradle ou Maven ou ANT quoi que vous ayez).

//We don't need jacoco for non-unit tests type of tasks as Jacoco won't be able to find any coverage if done this way. Jacoco agent file needs to be attached/visible to the TARGET's JVM (where you run your application via a .war / .ear etc).

jacoco { 
  //  ... As Gradle runs Unit tests (while doing build), they run free, in the same JVM where Gradle runs the build so Unit test have visibility to the main classes in the same JVM (which Gradle is using to run the build). Thus, you can use jacoco section in Gradle for running unit tests. BUT,
  // ... Don't use this section for running Integration, Acceptance, Selenium tests which run on a target JVM. Instead attach jacocoagent.jar and specify jacoco parameters to the target JVM.
}
  1. Une fois que vous avez votre Tomcat opérationnel, vous exécutez maintenant vos tests Selenium. REMARQUE: - J'utilise Jenkins sur une machine Linux/Unix et le plugin "xvfb" est très pratique, c'est-à-dire que je peux maintenant exécuter des tests GUI Selenium en mode HEADLESS et je ne bogue plus aucun utilisateur sur une machine où les tests sont exécutés par faire apparaître les pages de tests pendant l'exécution des tests GUI.

    - si vous utilisez le plugin "xvfb" dans Jenkins, vous D'ABORD devez démarrer " Xvfb "service sur le serveur (Linux/Unix) où vous exécutez les tests.

    - Si vous exécutez vos tests non unitaires (aka Intégration/Selenium, etc.) sur une machine Windows, vous pouvez voir les tests GUI apparaître lorsque vous exécutez vos tests. Si vous ne voulez pas voir les fenêtres contextuelles, votre instance Jenkins peut exécuter le processus esclave (votre machine Windows) en tant que service ("Installer en tant que service"). Si vous créez votre machine Windows en tant qu'esclave, lorsque vous exécutez l'installation JLNP sur votre machine, vous verrez une fenêtre contextuelle indiquant que Jenkins a démarré avec succès un processus esclave, en cliquant sur Fichier> Installer en tant que service exécutera votre esclave sur une machine Windows. comme "HEADLESS".

  2. Pendant que vos tests s'exécutent, vous remarquerez que cette fois, jacoco créera une structure de dossiers/fichier exécutable selon votre valeur définie pour le paramètre destfile mais ce sera toujours 0 ou une petite taille.

  3. Une fois vos tests Selenium/non unitaires terminés, vous devez "ARRÊTER" Tomcat/cible JVM. Cela RINTERA toutes les informations de couverture jacoco dans ce fichier jacocoST.exec (fichier personnalisé que vous vouliez que jacoco crée). - Remarque: Si vous souhaitez que le fichier jacocoST.exec soit vidé à la volée (sans que la JVM/session Tomcat ne s'arrête, vous pouvez consulter la documentation de jacoco pour y parvenir, il y a un sujet qui en parle, De cette façon, votre application peut continuer à fonctionner et vous n'avez pas à arrêter votre application/webservice).

  4. Exécutez la tâche jacocoTestReport et vous verrez la couverture du code jacoco.

    • Assurez-vous de spécifier où sont vos sources/classes pour le code principal.

par exemple:

  jacocoTestReport {
      group = "Reporting"
      description = "Generate Jacoco coverage reports after running tests."
      ignoreFailures = true


      //UT=is for Unit tests, IT=integrationTest, AT=acceptanceTest, ST=Selenium GUI tests.
      //executionData = files('build/jacoco/UT/jacocoUT.exec')
      //executionData = files('build/jacoco/IT/jacocoIT.exec')
      //executionData = files('build/jacoco/UT/jacocoUT.exec', 'build/jacoco/IT/jacocoIT.exec')

      //executionData = files(['build/jacoco/UT/jacocoUT.exec', 'build/jacoco/IT/jacocoIT.exec'])
      //OR use the following way for all.
      executionData = fileTree(dir: 'build/jacoco', include: '**/*.exec')

      reports {
             xml{
                 enabled true
                 //Following value is a file
                 destination "${buildDir}/reports/jacoco/xml/jacoco.xml"
             }
             csv.enabled false
             html{
                 enabled true
                 //Following value is a folder
                 destination "${buildDir}/reports/jacoco/html"
             }
      }

      //sourceDirectories = files(sourceSets.main.allJava.srcDirs)
      sourceDirectories = files('src/Java')
      //sourceDirectories = files(['src/Java','src/groovy'])
      classDirectories =  files('build/classes/main')

      //------------------------------------------
      //additionalSourceDirs = files(['test/Java','test/groovy','src/Java-test', 'src/groovy-test'])
      //additionalSourceDirs += files('src/Java-test')
}

N'hésitez pas à me cingler si vous voyez toujours des problèmes. Vous pouvez également voir quelques-uns de mes messages ici sur stackoverflow sur la façon dont j'ai réalisé cela et publier également la même couverture sur SonarQube.

16
Arun Sangal

La couverture peut fonctionner.

Ceci est une bibliothèque JavaScript.

Vous annotez les importations dans votre page HTML avec l'attribut 'data-cover':

<script src="sourceScript.js" data-cover></script>

... et la couverture remplace vos fichiers JS par des copies annotées qui rapportent les statistiques à lui-même.

L'étape non triviale consiste à obtenir les statistiques de couverture de code à partir d'une couverture, mais si je ne me trompe pas, Selenium a une interface qui vous permet d'exécuter des fonctions JavaScript dans le moteur de navigateur. L'API est là:

https://github.com/alex-seville/blanket/blob/master/docs/advanced_browser.md

1
Bobby Marinoff