Get Beautiful Coverage Reports in your Android Projects!

Alejandro Vidal Rodriguez
AndroidPub
Published in
4 min readJun 26, 2018

--

By Alejandro Vidal Rodriguez

There are several steps you can take to improve the quality of your code:

  • Linter check highlights on IDE
  • Enforce a correct and clean architecture
  • Write unit tests for your business logic
  • Write the test before implementation

But how can you track your code coverage in an easy and beautiful way?

We can now get coverage (on Android Studio) by: right clicking in our project → Run Tests with Coverage. This will output our code coverage metrics.

Right click → Run Tests with Coverage

This will then output a report with our current coverage. After a few clicks you’ll find your package:

To avoid clicking around you can define a run/debug configuration under Android JUnit to specify your package and select a few include/exclude options:

Selecting Options

But how we can exclude our data-binding classes, our activities, and things that our unit test coverage should not track? We want to have a metric that we care about, is something to keep an eye on, and that will keep our code with at least 60% of coverage.

Our old friend JACOCO (java code coverage) can help us get something easy to run, configured, and that can even send reports to our SonarQube to keep track of our code quality.

So, let’s add our dependencies:

apply plugin: 'org.sonarqube'
apply plugin: 'jacoco'

When we add the JACOCO plugin our unit tests will be inspected, and JACOCO will output a .exec file with all the information regarding our coverage.

We also want specific reports that are readable and can give us feedback really fast, so let’s make a report task for our code with our exclusion rules for Android:

We will not unit test anything regarding the OS or UI, which means that we do not have any business logic in our activities, fragments, etc.

Our coverage task depends on our tests, which will change their names depending on the flavors we defined for our project.

When the test runs, the .exec will be generated. Then, it will be used as input for our report task, will output xml files that we can use on our CIs, and an html website for human readable results.

The last task is just a shortcut, execute ./gradlew getCoverage and then the test will run, a report will be generated, and the website will open with your results! 😎

I really need to improve the coverage of my sample :D

Cool! What if we want to use those same rules so that our SonarQube reports use the same configuration that we used to get our nice coverage report website? We probably want to exclude the files that we are not focusing on from our SonarQube report in the coverage section, but we still want SonarQube to run the linter, bug checks, etc.

That’s what the sonar.coverage.exclusions property is for and that’s why we defined our exclusion array with a wildcard in the extension. This way we can iterate on it for this property and can match both .java and .class files.

Bam! A task that can be run by our CI (after the .exec is generated) which will give us a nice history of our code coverage in our SonarQube report.

You can even enforce minimum coverage in your JACOCO task in your gradle tasks!

How do you enforce your code coverage? Are there any rules you follow to keep your business logics tested and secure outside of the UI components? Let me know in the comments! Happy coding!

Alejandro (Alex) Rodriguez is the Engineering Director at the TribalScale Dubai office. For 8+ years, Alex has been delivering mobile apps and backend solutions for companies all around the world. He’s worked in Telefonica R&D’s mobile department in Spain, a search engine company in San Francisco, NFC payment solutions in the Netherlands, and is now helping TribalScale’s engineering team build clean efficient software in Dubai. Alex is passionate about architecture, clean code, process, and people.

--

--