I have a requirement to capture the code coverage of my selenium tests to the amount of source code in the server code (web application source code) covered .
For example the tests for login functionality should capture the amount of code covered in web application for the login function.
Else need to know which package or class it has touched in web application code for a scenario done . Eg a login
I couldn't find a suitable solution , although i came to know about Jacoco code coverage tool and tried some samples with the use of Jacoco Jenkins plugin , but there is no success .
I am not aware of the possiblity. Please provide me a suggestion on how to achieve this , Thanks in advance
To calculate the code coverage percentage, simply use the following formula: Code Coverage Percentage = (Number of lines of code executed by a testing algorithm/Total number of lines of code in a system component) * 100.
Code CoverageIt measures the number of lines covered by the test cases, reporting total number of lines in the code and number of lines executed by tests. Essentially it's the degree to which the source code of a program is executed when a test suite runs.
Code coverage tools are available for many programming languages and as part of many popular QA tools. They are integrated with build tools like Ant, Maven, and Gradle, with CI tools like Jenkins, project management tools like Jira, and a host of other tools that make up the software development toolset.
Make sure you do this. Note sure if you are using Gradle, Maven or ANT. But the following concept is very similar to any build system.
tasks.withType(Compile) { options.debug = true options.compilerArgs = ["-g"] }
For ex: I start my Tomcat script with the following parameter passed to Tomcat (-Dxxxx=value way)
PROJ_EXTRA_JVM_OPTS=-javaagent:tomcat/jacocoagent.jar=destfile=build/jacoco/ST/jacocoST.exec,append=false
Basically, Tomcat start script would have -Dparameter=value, you can pass the above parameter (Linux/Unix export the variable) to Tomcat/Target JVM's scope.
The above parameter line when sent to Tomcat, will attach JACOCO agent .jar file to the "TARGET" (aka Tomcat JVM). Here you are telling Tomcat that go look for jacocoagent.jar file from a director called "tomcat" under your workspace. It's gonna create a jacoco .exec file named "jacocoST.exec" (aka jacoco exec file for Selenium Test) under build/jacoco/ST folder (I'm using Gradle so Gradle creates "build" folder anytime you run a build/compile/test/integrationTest/customSeleniumTaskThatYouMightHaveCreated).
NOTE: This means, that you DON'T have to specify jacoco section in the test task (as that'll run in your BUILD systems' JVM either Gradle or Maven or ANT whatever you have).
//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. }
Once you have your Tomcat up and running, now you run your Selenium tests. NOTE: -- I'm using Jenkins on Linux/Unix machine and "xvfb" plugin is very handy i.e. now I can run Selenium GUI tests in HEADLESS mode and I won't bug any user on a machine where the tests are running by popping up the tests pages while the GUI tests are running.
-- if you end up using "xvfb" plugin in Jenkins, you FIRST need to start "Xvfb" service on the server (Linux/Unix) where you are running the tests.
-- If you are running your non-units tests (aka Integration/Selenium etc) on a Windows machine, then you can see the GUI tests pop up when you run your tests. If you don't want to see the popup windows, then your Jenkins instance can run the slave (your windows machine) process as a service ("Install as a Service"). If you create your windows machine as a slave, when you run the JLNP installation on your machine, You'll see a popup that Jenkins has successfully started a slave process, clicking File > Install as a service will run your slave on a windows machine as "HEADLESS".
While your tests are running, you'll notice that this time, jacoco will create a folder structure/exec file as per your defined value for destfile parameter but it'll still be 0 or some small size.
Once your Selenium/non-unit tests are complete, you have to "STOP" Tomcat / target JVM. This will FLUSH all jacoco coverage info to this jacocoST.exec file (custom file that you wanted jacoco to create). -- Note: If you want jacocoST.exec file to be flushed on the fly (without requiring the Tomcat JVM/session to stop, then you can look into jacoco documentation how to do that, there is one topic there which tells about this, this way your application can continue to run and you dont have to stop your application/webservice).
Run jacocoTestReport task and you'll see jacoco code coverage.
for ex:
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') }
Feel free to ping me if you still see any issues. You can also see few of my posts here on stackoverflow on how I achieved this and also publishing the same coverage to SonarQube.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With