gpt4 book ai didi

kotlin - Kotlin 协程的 Jacoco 代码覆盖率不正确

转载 作者:行者123 更新时间:2023-12-02 11:29:13 26 4
gpt4 key购买 nike

我正在使用Jacoco进行单元测试代码覆盖率。 Jacoco 生成的报告显示,我的 Kotlin 代码遗漏了很少的分支。我注意到根据 Jacoco 的说法,协程代码及其后面的代码没有被正确覆盖。我不确定是因为协程还是其他什么原因。使用 IntelliJ 代码覆盖率运行单元测试时,我的 Kotlin 类显示100% 覆盖率

我不知道为什么 Jacoco 的报道较少。我已经使用 Spock (Groovy) 编写了单元测试。

请引用以下图片:

错过的分支: enter image description here

enter image description here

原始代码: enter image description here

最佳答案

类似于“Why is JaCoCo not covering my String switch statements?”:

JaCoCo 执行字节码分析,而不是源代码。使用 kotlinc 1.3.10

编译 Example.kt
package example

fun main(args: Array<String>) {
kotlinx.coroutines.runBlocking { // line 4
}
}

生成两个文件 ExampleKt.classExampleKt$main$1.class,最后一个文件的字节码 (javap -v -p ExampleKt$main$1.class) class) 包含方法 invokeSuspend(Object)

  public final java.lang.Object invokeSuspend(java.lang.Object);
descriptor: (Ljava/lang/Object;)Ljava/lang/Object;
flags: ACC_PUBLIC, ACC_FINAL
Code:
stack=3, locals=4, args_size=2
0: invokestatic #29 // Method kotlin/coroutines/intrinsics/IntrinsicsKt.getCOROUTINE_SUSPENDED:()Ljava/lang/Object;
3: astore_3
4: aload_0
5: getfield #33 // Field label:I
8: tableswitch { // 0 to 0
0: 28
default: 53
}
28: aload_1
29: dup
30: instanceof #35 // class kotlin/Result$Failure
33: ifeq 43
36: checkcast #35 // class kotlin/Result$Failure
39: getfield #39 // Field kotlin/Result$Failure.exception:Ljava/lang/Throwable;
42: athrow
43: pop
44: aload_0
45: getfield #41 // Field p$:Lkotlinx/coroutines/CoroutineScope;
48: astore_2
49: getstatic #47 // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
52: areturn
53: new #49 // class java/lang/IllegalStateException
56: dup
57: ldc #51 // String call to 'resume' before 'invoke' with coroutine
59: invokespecial #55 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
62: athrow
LineNumberTable:
line 4: 3
line 5: 49

它与源文件的第 4 行关联并包含分支(ifeqtableswitch)。

虽然目前最新的 JaCoCo 版本 (0.8.2) 具有针对各种编译器生成的工件的过滤器,例如 switch 语句中的 String、Kotlin 编译器生成的字节码协程没有被过滤。变更日志可以在https://www.jacoco.org/jacoco/trunk/doc/changes.html查看以及其他:https://www.jacoco.org/research/index.html还有presentation about bytecode pattern matching显示/解释了许多编译器生成的工件。

<小时/>

您在 IntelliJ IDEA 中看到的 100% - 只是行覆盖率,因此您正在尝试比较两个完全不同的事物。作为证明 - 这是 IntelliJ IDEA 的屏幕截图,它显示 100% 的行覆盖率,但仅执行了 if 的一个分支(其中 args.size >= 0 计算结果为 true)

intellij

这是执行同一源文件时 JaCoCo 报告的相应屏幕截图

jacoco source level

进入包级别,您可以看到 100% 的线路覆盖率,但 50% 的分支覆盖率

jacoco package level

然后通过第一个链接进入类级别 ExampleKt.main.new Function2() {...} 您可以再次看到该方法 invokeSuspend(Object) 贡献错过的分支

jacoco class level

<小时/>

更新(2019 年 1 月 29 日)

JaCoCo version 0.8.3具有 Kotlin 编译器添加的用于挂起 lambda 和函数的分支过滤器:

before

after

关于kotlin - Kotlin 协程的 Jacoco 代码覆盖率不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53485360/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com