I’ve recently been working on an Android app that is 100% Kotlin with a full development CI pipeline. Having a good app means that the code is testable, which lead me to use Sonarqube for static code analysis and code coverage.

Since there is no official Kotlin plugin for Sonarqube yet, I looked at a third party plugin on github named, Sonar-Kotlin. This plugin is awesome, as it has another library called detekt integrated in it. Detekt is what does the static code analysis. What about the code coverage you ask? Well the Sonar-Kotlin plugin has the ability to give us code coverage reports, but there is some set up that needs to be done.

This is where my journey with Sonarqube code coverage began, with my Android app written in Kotlin.

i.e: This post assumes you have Sonarqube setup and some kind of CI.

Getting Started

Getting the Sonar-Kotlin plugin installed is very simple. I have a Vm running on Google Compute Engine that has Sonarqube installed in a Docker container. Then pretty much followed the steps on the plugins Github page and it was installed.

git clone https://github.com/arturbosch/sonar-kotlin

cd sonar-kotlin

./gradlew build

cp build/libs/sonar-kotlin-[enter_version].jar $SONAR_HOME/extensions/plugins

cd $SONAR_HOME/bin/[your_os]

./sonar.sh restart

The CI i’m using for the project is Bitrise. This is a pretty awesome CI for its workflow editor and all its third party integration. One of those third party tools Bitrise provides is Sonarqube scanner.

Within Bitrise we will add our scanner properties so when the Sonarqube scanner build step is invoked, those properties will be executed accordingly.

sonar.sources=.

sonar.login=$SonarToken

sonar.projectKey=$BITRISE_APP_TITLE

sonar.host.url=$SonarUrl

sonar.report.export.path=sonar-report.json

detekt.sonar.kotlin.config.path=default-detekt-config.yml

sonar.java.binaries=target/classes

sonar.sources=app/src/main/java

sonar.tests=app/src/test/java

sonar.java.coveragePlugin=jacoco

sonar.jacoco.reportPaths=app/build/jacoco/testDebugUnitTest.exec

So for us to get a sonar code coverage report for Java code, we need to have a gradle task that will generate a Jacoco report. This is the same for Kotlin.

I found this article to help you get started with Jacoco.

Once we have that set up within our workflow, we need to run the following gradle command before the Sonarqube scanner task runs.

./gradlew clean jacocoTestReport

The scanner needs a Jacoco report to show code coverage in Sonarqube and the command above provides that for us.

If we run a build now, we will see the following Sonarqube report.

As seen above, we do not have code coverage, even though I said in the beginning the plugin supports code coverage for kotlin code.

This is due to the Kotlin class files not being generated in the same location as Java class files. For us to get around this, we need to add the location of the Kotlin class files to the sonar.java.binaries property.

sonar.java.binaries=target/classes,app/build/tmp/kotlin-classes

This location can differ depending on your project. We need to keep the “target/classes” in order for the Java class files to be picked up as well.

We then run our CI build again and we get code coverage for our Kotlin code.

A lot of experimenting was done to get to this point. There is not much help out there in getting this working, which is the reason for me sharing my experience. I hope this helps everyone out there that is trying to solve the same problem I had.

Happy Sonarqube code coverage.

Get in Touch!

Peter John Welcome — Google+