Jacoco has been a tool for testing test coverage for a long time, we often configure jacoco in an .gradle file and add it to the build.gradle of the app module when we want to check coverage.
Recently the gradle using kotlin in gradle kts makes it easier to configure with kotlin code instead of groovy as before.
However, currently gradle does not support adding jacoco from separate gradle.kts file, so we will need to add jacoco code to the gradle.kts file of module that needs check coverage.
Below is an example of a jacoco config for gradle kts that you can refer to
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | plugins <span class="token punctuation">{</span> <span class="token operator">..</span> <span class="token punctuation">.</span> jacoco <span class="token punctuation">}</span> jacoco <span class="token punctuation">{</span> toolVersion <span class="token operator">=</span> <span class="token string">"0.8.5"</span> <span class="token punctuation">}</span> <span class="token comment">/** There are two ways to see test result: * FIRST * To run this test coverage with buildTypes: Debug; Flavor: Dev * use command: ./gradlew clean testDevDebugUnitTestCoverage * * See result at: * app/build/reports/jacoco/testDevDebugUnitTestCoverage/html/index.html * * SECOND: * - Click Gradle on the right menu of Android Studio IDE * - At Project name, expand "app", expand "Tasks", expand "coverage" * - Run any test you want */</span> project <span class="token punctuation">.</span> <span class="token function">afterEvaluate</span> <span class="token punctuation">{</span> <span class="token comment">// Grab all build types and product flavors</span> <span class="token keyword">val</span> buildTypeNames <span class="token operator">:</span> List <span class="token operator"><</span> String <span class="token operator">></span> <span class="token operator">=</span> android <span class="token punctuation">.</span> buildTypes <span class="token punctuation">.</span> <span class="token function">map</span> <span class="token punctuation">{</span> it <span class="token punctuation">.</span> name <span class="token punctuation">}</span> <span class="token keyword">val</span> productFlavorNames <span class="token operator">:</span> ArrayList <span class="token operator"><</span> String <span class="token operator">></span> <span class="token operator">=</span> <span class="token function">ArrayList</span> <span class="token punctuation">(</span> android <span class="token punctuation">.</span> productFlavors <span class="token punctuation">.</span> <span class="token function">map</span> <span class="token punctuation">{</span> it <span class="token punctuation">.</span> name <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token comment">// When no product flavors defined, use empty</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> productFlavorNames <span class="token punctuation">.</span> <span class="token function">isEmpty</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> productFlavorNames <span class="token punctuation">.</span> <span class="token function">add</span> <span class="token punctuation">(</span> <span class="token string">""</span> <span class="token punctuation">)</span> productFlavorNames <span class="token punctuation">.</span> <span class="token function">forEach</span> <span class="token punctuation">{</span> productFlavorName <span class="token operator">-></span> buildTypeNames <span class="token punctuation">.</span> <span class="token function">forEach</span> <span class="token punctuation">{</span> buildTypeName <span class="token operator">-></span> <span class="token keyword">val</span> sourceName <span class="token operator">:</span> String <span class="token keyword">val</span> sourcePath <span class="token operator">:</span> String <span class="token keyword">if</span> <span class="token punctuation">(</span> productFlavorName <span class="token punctuation">.</span> <span class="token function">isEmpty</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> sourcePath <span class="token operator">=</span> buildTypeName sourceName <span class="token operator">=</span> buildTypeName <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> sourcePath <span class="token operator">=</span> <span class="token string">" <span class="token interpolation"><span class="token delimiter variable">${</span> productFlavorName <span class="token delimiter variable">}</span></span> / <span class="token interpolation"><span class="token delimiter variable">${</span> buildTypeName <span class="token delimiter variable">}</span></span> "</span> sourceName <span class="token operator">=</span> <span class="token string">" <span class="token interpolation"><span class="token delimiter variable">${</span> productFlavorName <span class="token delimiter variable">}</span></span> <span class="token interpolation"><span class="token delimiter variable">${</span> buildTypeName <span class="token punctuation">.</span> <span class="token function">capitalize</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token delimiter variable">}</span></span> "</span> <span class="token punctuation">}</span> <span class="token keyword">val</span> testTaskName <span class="token operator">=</span> <span class="token string">"test <span class="token interpolation"><span class="token delimiter variable">${</span> sourceName <span class="token punctuation">.</span> <span class="token function">capitalize</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token delimiter variable">}</span></span> UnitTest"</span> <span class="token comment">// Create coverage task of form 'testFlavorTypeCoverage' depending on 'testFlavorTypeUnitTest'</span> task <span class="token operator"><</span> JacocoReport <span class="token operator">></span> <span class="token punctuation">(</span> <span class="token string">" <span class="token interpolation"><span class="token delimiter variable">${</span> testTaskName <span class="token delimiter variable">}</span></span> Coverage"</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//where store all test to run follow second way above</span> group <span class="token operator">=</span> <span class="token string">"coverage"</span> description <span class="token operator">=</span> <span class="token string">"Generate Jacoco coverage reports on the <span class="token interpolation"><span class="token delimiter variable">${</span> sourceName <span class="token punctuation">.</span> <span class="token function">capitalize</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token delimiter variable">}</span></span> build."</span> <span class="token keyword">val</span> excludeFiles <span class="token operator">=</span> <span class="token function">arrayListOf</span> <span class="token punctuation">(</span> <span class="token string">"**/R.class"</span> <span class="token punctuation">,</span> <span class="token string">"**/R$*.class"</span> <span class="token punctuation">,</span> <span class="token string">"**/BuildConfig.*"</span> <span class="token punctuation">,</span> <span class="token string">"**/Manifest*.*"</span> <span class="token punctuation">,</span> <span class="token string">"**/*Test*.*"</span> <span class="token punctuation">,</span> <span class="token string">"android/**/*.*"</span> <span class="token punctuation">,</span> <span class="token string">"**/*_MembersInjector.class"</span> <span class="token punctuation">,</span> <span class="token string">"**/Dagger*Component.class"</span> <span class="token punctuation">,</span> <span class="token string">"**/Dagger*Component <span class="token interpolation variable">$Builder</span> .class"</span> <span class="token punctuation">,</span> <span class="token string">"**/*_*Factory.class"</span> <span class="token punctuation">,</span> <span class="token string">"**/*ComponentImpl.class"</span> <span class="token punctuation">,</span> <span class="token string">"**/*SubComponentBuilder.class"</span> <span class="token punctuation">,</span> <span class="token string">"**/*Creator.class"</span> <span class="token punctuation">,</span> <span class="token string">"**/*Application*.*"</span> <span class="token punctuation">,</span> <span class="token string">"**/*Activity*.*"</span> <span class="token punctuation">,</span> <span class="token string">"**/*Fragment*.*"</span> <span class="token punctuation">,</span> <span class="token string">"**/*Adapter*.*"</span> <span class="token punctuation">,</span> <span class="token string">"**/*Dialog*.*"</span> <span class="token punctuation">,</span> <span class="token string">"**/*Args*.*"</span> <span class="token punctuation">,</span> <span class="token string">"**/*Companion*.*"</span> <span class="token punctuation">,</span> <span class="token string">"**/*Kt*.*"</span> <span class="token punctuation">,</span> <span class="token string">"**/com/example/moviedb/di/**/*.*"</span> <span class="token punctuation">,</span> <span class="token string">"**/com/example/moviedb/ui/navigation/**/*.*"</span> <span class="token punctuation">,</span> <span class="token string">"**/com/example/moviedb/ui/widgets/**/*.*"</span> <span class="token punctuation">)</span> <span class="token comment">//Explain to Jacoco where are you .class file java and kotlin</span> classDirectories <span class="token punctuation">.</span> <span class="token function">setFrom</span> <span class="token punctuation">(</span> <span class="token function">fileTree</span> <span class="token punctuation">(</span> <span class="token string">" <span class="token interpolation"><span class="token delimiter variable">${</span> project <span class="token punctuation">.</span> buildDir <span class="token delimiter variable">}</span></span> /intermediates/classes/ <span class="token interpolation"><span class="token delimiter variable">${</span> sourcePath <span class="token delimiter variable">}</span></span> "</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">exclude</span> <span class="token punctuation">(</span> excludeFiles <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token function">fileTree</span> <span class="token punctuation">(</span> <span class="token string">" <span class="token interpolation"><span class="token delimiter variable">${</span> project <span class="token punctuation">.</span> buildDir <span class="token delimiter variable">}</span></span> /tmp/kotlin-classes/ <span class="token interpolation"><span class="token delimiter variable">${</span> sourceName <span class="token delimiter variable">}</span></span> "</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">exclude</span> <span class="token punctuation">(</span> excludeFiles <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">val</span> coverageSourceDirs <span class="token operator">=</span> <span class="token function">arrayListOf</span> <span class="token punctuation">(</span> <span class="token string">"src/main/java"</span> <span class="token punctuation">,</span> <span class="token string">"src/ <span class="token interpolation variable">$productFlavorName</span> /java"</span> <span class="token punctuation">,</span> <span class="token string">"src/ <span class="token interpolation variable">$buildTypeName</span> /java"</span> <span class="token punctuation">)</span> additionalSourceDirs <span class="token punctuation">.</span> <span class="token function">setFrom</span> <span class="token punctuation">(</span> <span class="token function">files</span> <span class="token punctuation">(</span> coverageSourceDirs <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token comment">//Explain to Jacoco where is your source code</span> sourceDirectories <span class="token punctuation">.</span> <span class="token function">setFrom</span> <span class="token punctuation">(</span> <span class="token function">files</span> <span class="token punctuation">(</span> coverageSourceDirs <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token comment">//execute file .exec to generate data report</span> executionData <span class="token punctuation">.</span> <span class="token function">setFrom</span> <span class="token punctuation">(</span> <span class="token function">files</span> <span class="token punctuation">(</span> <span class="token string">" <span class="token interpolation"><span class="token delimiter variable">${</span> project <span class="token punctuation">.</span> buildDir <span class="token delimiter variable">}</span></span> /jacoco/ <span class="token interpolation"><span class="token delimiter variable">${</span> testTaskName <span class="token delimiter variable">}</span></span> .exec"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> reports <span class="token punctuation">{</span> xml <span class="token punctuation">.</span> isEnabled <span class="token operator">=</span> <span class="token boolean">true</span> html <span class="token punctuation">.</span> isEnabled <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token function">dependsOn</span> <span class="token punctuation">(</span> testTaskName <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
You can refer to the source code here https://github.com/dangquanuet/The-Movie-DB-Kotlin/blob/develop/app/build.gradle.kts#L29
Then you can proceed to run test coverage as usual with jacoco before it is via the command line or gradle task.
This is the end of this post, see you later