返回

Sentry 7.6.0 中 Jacoco 覆盖率报告问题详解及解决指南

Android

如何在使用 Sentry 7.6.0 时解决 Jacoco 覆盖率问题

引言

使用最新版本的 Sentry 依赖项时,许多开发人员遇到了 Jacoco 覆盖率报告中的问题。特别是,他们遇到了“执行数据与类不匹配”的错误,破坏了覆盖率结果的准确性。本文旨在探索此问题,深入研究其原因,并提供逐步指南来解决它。

问题

在使用 Sentry 7.6.0 后,在运行 Jacoco 覆盖率报告时,某些类可能会导致错误,提示“执行数据与类不匹配”。该错误表明 Jacoco 使用的类文件与运行时使用的类文件不同,导致覆盖率数据不准确。

原因

Sentry 7.6.0 针对 Android 应用修改了字节码,以进行崩溃报告和错误跟踪。当 Jacoco 尝试生成覆盖率报告时,它会使用修改后的类文件,而这些类文件可能与运行时使用的原始类文件不匹配。这导致了执行数据和类之间的不匹配,从而产生了错误。

解决方法

为了解决此问题,需要配置 Jacoco 以使用原始类文件,而不是 Sentry 修改后的类文件。可以分三步完成此操作:

  1. 禁用 Sentry 的字节码修改

    在 app 的 build.gradle 文件中,将 Sentry 插件的 instrumentationEnabled 设置为 false

    buildTypes {
        debug {
            instrumentationEnabled false
        }
    }
  1. 生成原始类文件

    使用 shrinker Gradle 任务生成未修改的类文件。

    shrinker {
        keep **/*.class
        shrinkResources false
    }
  1. 配置 Jacoco

    在 Jacoco Gradle 插件中,指定 shrinkedJar 任务生成的输出目录。

    jacoco {
        toolVersion = "0.8.7"

        reportsDirectory.set(file("$buildDir/jacoco"))
        sourceDirectories.from = files([
            "src/main/java",
            "src/main/kotlin"
        ])

        classDirectories.from = files([
            "build/intermediates/classes/debug",
            "build/tmp/kotlin-classes/debug"
        ])

        executionData.from = files([
            "build/jacoco/testDebugUnitTest.exec",
            "build/outputs/apk/debug/app-debug.apk"
        ])

        includeNoLocationClasses = true
        excludes = ['jdk.internal.*']
    }

结论

通过禁用 Sentry 的字节码修改、生成原始类文件和配置 Jacoco 来使用原始类文件,可以解决 Jacoco 覆盖率报告中“执行数据与类不匹配”的错误。这将恢复覆盖率结果的准确性,使开发人员能够可靠地跟踪和改进其代码的测试覆盖率。

常见问题解答

  1. 为什么 Sentry 会修改字节码?
    Sentry 修改字节码以实现崩溃报告和错误跟踪功能。

  2. 为什么原始类文件很重要?
    原始类文件是运行时使用的类文件,Jacoco 需要使用这些类文件来生成准确的覆盖率报告。

  3. 我可以只禁用 Sentry 吗?
    虽然禁用 Sentry 可以解决问题,但它也会禁用崩溃报告和错误跟踪功能。

  4. 这个解决方案适用于所有版本的吗?
    此解决方案适用于 Sentry 7.6.0 及更高版本。

  5. 还有其他方法来解决这个问题吗?
    使用 ShadowJar 插件也可能有助于解决此问题。