codeclimate / test-reporter

Code Climate Test Reporter
MIT License
154 stars 76 forks source link

Code coverage with Jacoco #490

Open VarshaBhatiaPapershift opened 2 years ago

VarshaBhatiaPapershift commented 2 years ago

Hello,

I have integrated jacoco in my project already and now on top of that, I want to set up code climate and upload the same test result over there.

Sharing my jacoco files below: Just want to understand how to show test coverage into code climate:

  1. jacoco.gradle
apply plugin: 'jacoco'

jacoco {
    toolVersion = "$version_jacoco"
}

tasks.withType(Test) {
    jacoco.includeNoLocationClasses = true
    jacoco.excludes = ['jdk.internal.*']
}

task jacocoTestReport(type: JacocoReport) {
    group 'Reporting'
    description "Generate Jacoco coverage reports."

    reports {
        xml.enabled = true
        xml.destination file("${rootProject.buildDir}/codecov-report/jacocoTestReport.xml")

        html.enabled = true
        html.destination file("${rootProject.buildDir}/coverage-report")
    }

    def javaClasses = []
    def kotlinClasses = []
    def javaSrc = []
    def kotlinSrc = []
    def execution = []

    def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*', '**/*Impl.*', '**/databinding/**/*.*', '**/di/**/*.*']

    rootProject.subprojects.each { proj ->
        javaClasses   << fileTree(dir: "$proj.buildDir/intermediates/javac/debug", excludes: fileFilter)
        kotlinClasses << fileTree(dir: "$proj.buildDir/tmp/kotlin-classes/debug", excludes: fileFilter)
        javaSrc       << "$proj.projectDir/src/main/java"
        kotlinSrc     << "$proj.projectDir/src/main/kotlin"
        execution     << fileTree(
                dir: proj.buildDir,
                includes: [
                        'jacoco/testDebugUnitTest.exec',
                        'outputs/code_coverage/debugAndroidTest/connected/**/*.ec'
                ]
        )
    }

    sourceDirectories.from = [javaSrc, kotlinSrc]
    classDirectories.from = [javaClasses, kotlinClasses]

    print execution

    executionData.from = execution

    doLast() {
        println "file://${reports.xml.destination}"
        println "file://${reports.html.destination}/index.html"
    }
}

2. update_coverage.rb

#!/usr/bin/ruby
require 'uri'
require 'net/http'
require 'net/https'
require 'json'

coverage_report = File.read 'build/codecov-report/jacocoTestReport.xml'

match_data = /\<\/package\>\<counter type="INSTRUCTION" missed="(\d+)" covered="(\d+)"/.match coverage_report

missed_instructions = match_data.captures[0].to_f
covered_instructions = match_data.captures[1].to_f

total_coverage = covered_instructions / (covered_instructions + missed_instructions) * 100
puts "Found total coverage of #{total_coverage}. Updating JSON for updated README badge ..."

color = case total_coverage
when 60...75
  "orange"
when 75...90
  "yellow"
when 90...100
  "green"
else
  "red"
end

uri = URI('https://api.jsonbin.io/b/***')
https = Net::HTTP.new(uri.host,uri.port)
https.use_ssl = true

request = Net::HTTP::Put.new(uri, 'Content-Type' => 'application/json', 'secret-key' => ENV['JSONBIN_SECRET_KEY'])
request.body = { schemaVersion: 1, label: 'Coverage', message: "#{total_coverage.round(1)}%", color: color }.to_json

result = https.request(request)
puts "Badge JSON update status: #{result.code}. Body:\n#{result.body}"

3. Github Action

    runs-on: ubuntu-latest
    needs: [ unit-tests, ui-tests ]

    steps:
      - uses: actions/checkout@v2

      - name: Download Kotlin classes
        uses: actions/download-artifact@v2
        with:
          name: kotlin-classes
          path: apiclient/build/tmp/kotlin-classes/debug

      - name: Download Unit Tests Exec File
        uses: actions/download-artifact@v2
        with:
          name: unit-tests-exec
          path: app_foldar/build/jacoco

      - name: Download UI Tests Exec File
        uses: actions/download-artifact@v2
        with:
          name: ui-tests-exec
          path: app_foldar/build/outputs/code_coverage/debugAndroidTest/connected

      - name: Generate Code Coverage Reports
        run: ./gradlew jacocoTestReport

      - uses: actions/upload-artifact@v2
        with:
          name: coverage_report
          path: build/coverage-report

      - name: Update Coverage Badge JSON
        run: ruby update_coverage.rb
        env:
          JSONBIN_SECRET_KEY: ${{ secrets.JSONBIN_SECRET_KEY }}

      - name: Post Coverage Data to Segment
        run: |
          coverage=$(./extract_coverage.rb)
          curl -X POST https://fn.segmentapis.com/?b=ID= \
            -H 'Content-Type: application/json' \
            -d "{\"team\": \"android\", \"app_name\": \"${{ env.PROJECT_NAME }}\", \"stat_type\": \"coverage\", \"stat_value\":\"$coverage\"}"

      - name: Delete temporary build artifacts
        uses: GeekyEggo/delete-artifact@v1.0.0
        if: always()
        with:
          name: |
            kotlin-classes
            unit-tests-exec
            ui-tests-exec

How to integrate code_climate with jacoco?