Kotlin + JaCoCo: Tuning Compiler to Skip Generated Code.

Andrey Fomenkov
Mar 26, 2018 · 3 min read

Update Sep/18: starting from version 0.8.2 JaCoCo has a bunch of new features for filtering out generated code. See changelog for more details: https://www.jacoco.org/jacoco/trunk/doc/changes.html

JaCoCo is a free and powerful library for generating comprehensive test coverage reports. Unfortunately for Kotlin developers the collected test information may appear unreadable and dirty.

There are two reasons for that:

  • Kotlin compiler generates a lot of bytecode even for a concise syntactic constructions;
  • From JaCoCo’s point of view there is no difference between developer and compiler generated code — it analyzes everything in bytecode when composing coverage reports.

Coverage report for Kotlin Data Class.

For instance let’s compile and analyze simple Kotlin Data class shown below:

Image for post
Image for post
Image for post
Image for post

JaCoCo reports about quite poor coverage. Actually we don’t need to worry about that because all methods are silently produced by Kotlin compiler and their implementations are assumed to be infallible — in JetBrains we trust!

From the bytecode there is no any “stop sign” for coverage analyzer telling which part of code should be skipped.

JaCoCo 0.8.0 and @Generated annotation.

In release 0.8.0 a new filter was introduced to handle special annotation used by project Lombok. All methods annotated with @lombok.Generated are now ignored by JaCoCo analyzer.

Nevertheless, Kotlin compiler still has no idea about this awesome feature!

Kotlin fork on GitHub.

Here you can clone a fork of the original JetBrains repository with patched compiler. See detailed description and supported features inside:

Image for post
Image for post

Link: https://github.com/andreyfomenkov/kotlin

Skipping equals(), hashCode(), toString(), copy() and componentN() for Data Classes.

Here is a coverage result for the User data class, but with patched compiler. As you can see some generated methods are gone and report looks better:

Image for post
Image for post
Wow! Enhanced code coverage without actual writing any additional unit tests!

Just for comparison with the old report let me duplicate the image:

Image for post
Image for post

Skipping generated methods for lateinit properties.

The following class Foo contains late-initialized property bar:

Image for post
Image for post

Compiler creates getBar() / setBar() methods for the property:

Image for post
Image for post

That’s why JaCoCo again reports about uncovered code. What a pity!

Image for post
Image for post

Let’s run with the patched compiler, analyze and decompile:

Image for post
Image for post
Image for post
Image for post
Awesome! Methods related to lateinit property are thrown away!

Another example — lateinit property is now not marked as “uncovered”:

Image for post
Image for post

And how it was before:

Image for post
Image for post

Conclusion.

Code architecture in the original repository is very clear and well-organized, that’s why implementing another patches for the compiler should not turn into a big problem. Feel free to contribute and propose improvements!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store