SonarQube for Multi-Module Android App

Ketan Vichare
The Startup
Published in
3 min readSep 18, 2020

Writing test cases is an essential part of the development cycle. It helps to detect potential bugs early in the lifecycle. Critical code reviews are necessary to ensure proper code practices and observe code smells. Code coverage gives us a good idea about how much code is covered by the test cases. SonarQube report informs all of the above.

It is quite straight forward to get coverage of a single module Application. But, most of the enterprise Android Applications are divided into submodules. Let’s see how can we get the combined code coverage of an entire project consisting of various submodules.

Here, similar to app/build.gradle, every submodule has build.gradle. e.g., features/feature1/build.gradle. app module calls methods in submodules.

Each submodule has the below hierarchy.

Structure of the submodule

In build.gradle file, add below Gradle task. Task will be of type JacocoReport. This Gradle task will be responsible for generating test execution data, which in turn will generate .exec file.

Each submodule’s build.gradle will have this task in it. .exec file for each submodule will be stored in its respective jacoco/ folder. Now, we have the test execution data for all the modules.
We need to add up all test execution data and generate combined code coverage. For that, we need to make changes in parent level build.gradle. Let’s modify parent level build.gradle.

Here, we are adding a task rootCodeCoverageReport, which depends on codeCoverageReport tasks from submodules. This task will extract all the values of kotlinClasses and sourceDirectories from their submodules. Importantly, test execution data of submodules will be fetched from /jacoco paths of their submodules. Now, we have combined the code coverage data from all the submodules.

The next part is integrating it with SonarQube.
We need to define sonarqube properties. You can add org sonar.host.url and sonar.login. Add localhost url, if you want to run locally. Follow docs for sonarqube project set up guide.

We don’t want to add generated classes as a part of code coverage. Also, there could be some classes that we may not wish to analyze. We can exclude such classes from code coverage by mentioning a list of classes in sonar.coverage.exclusions property. We can exclude code analysis of desired classes by using property sonar.exclusions.
Finally, run the code coverage by calling sonarqube task. This will initiate a code coverage process.
Run -> ./gradlew sonarqube

Open the browser and enter a value for sonar.host.url. We can see our project listed in the Projects view. Further, if we detail it down, that gives us more information about classes, methods and conditions covered by test cases. Report also informs code smell and potential bugs.

Now, we know the exact coverage percentage of the complete App code. Also, we have a better picture of an App code quality.

Feel free to post your thoughts on this article in the comment section below. Have a great day!

--

--

Ketan Vichare
The Startup

Android | Father of this Champ | Learner | Dreamer