我知道这个主题有很多问题(和答案),但我已经尝试过在SO和其他网站上找到的所有内容,但我还没有找到一种方法让JaCoCo包括使用Mockito的Android测试。
我的问题: 我想使用JaCoCo生成单元测试和仪器测试(androidTest)的代码覆盖。我使用Mockito来模拟一些课程。我在GitHub中找到了一个使用JaCoCo的样本并将其用作起点。
https://github.com/rafaeltoledo/unified-code-coverage-android
当我运行该示例中包含的自定义jacocoTestReport任务时,代码覆盖率报告已正确生成,代码覆盖率为100%。该报告包括单元测试和android测试。但是,该示例未使用Mockito(我需要),因此我将以下内容添加到app / build.gradle
dependencies {
...
androidTestCompile 'org.mockito:mockito-android:2.10.0'
}
我在app / src / main / java / net / rafaeltoledo / coverage / Util.java中添加了一个名为Util的非常简单的Java类
public class Util {
public int anIntMethod() {
return 0;
}
}
并将以下简单测试添加到app / src / androidTest / java / net / rafaeltoledo / coverage / MainActivityTest.java中的现有android测试
@Test
public void utilMethod() {
Util util = Mockito.mock(Util.class);
Mockito.doReturn(10).when(util).anIntMethod();
assertThat(util.anIntMethod(), is(10));
}
当我再次运行jacocoTestReport时,代码覆盖率降至88%,并且报告实际上显示我的测试未涵盖Util类,即使我显然有一个练习该类的测试。
(我想添加报告的截图,但我没有足够的声誉,所以这里是coverage report and execution report的链接,表明两个测试实际上都已执行了)
版本信息: Gradle插件:2.3.3 Jacoco:0.7.8.201612092310 Android Studio:2.3.3 Android构建工具:25.0.2
这是Jacoco限制还是我做错了什么?
答案 0 :(得分:5)
我做错了吗?
让我们放下Android,因为IMO显然对你对核心事物的期望/理解有些不对劲 - 嘲笑:
即使我显然有一个练习该课程的测试。
通过
@Test public void utilMethod() { Util util = Mockito.mock(Util.class); Mockito.doReturn(10).when(util).anIntMethod(); assertThat(util.anIntMethod(), is(10)); }
您没有对anIntMethod
进行测试,无论10
中实际写入的是什么,您都在测试始终返回anIntMethod
的内容。
Coverage显示已执行的内容,因此绝对正确anIntMethod
为零,因为它未执行。
模拟用于将测试中的类与其依赖项隔离,但不能替换它,否则您不会测试实际代码。
以下是正确使用模拟的示例:
src/main/java/Util.java
:
public class Util {
int anIntMethod(Dependency d) {
return d.get();
}
}
class Dependency {
int get() {
return 0;
}
}
src/test/java/UtilTest.java
:
import org.junit.Test;
import org.mockito.Mockito;
import static org.junit.Assert.assertEquals;
public class UtilTest {
@Test
public void utilMethod() {
Dependency d = Mockito.mock(Dependency.class);
Mockito.doReturn(10).when(d).get();
assertEquals(10, new Util().anIntMethod(d));
}
}
build.gradle
:
apply plugin: "java"
apply plugin: "jacoco"
repositories {
mavenCentral()
}
dependencies {
testCompile "junit:junit:4.12"
testCompile "org.mockito:mockito-core:2.10.0"
}
执行gradle build jacocoTestReport
覆盖后
部分嘲笑的情况:
src/main/java/Util.java
:
public class Util {
int get() {
return 0;
}
int anIntMethod() {
return get();
}
}
src/test/java/UtilTest.java
:
import org.junit.Test;
import org.mockito.Mockito;
import static org.junit.Assert.assertEquals;
public class UtilTest {
@Test
public void utilMethod() {
Util util = Mockito.mock(
Util.class,
Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS)
);
Mockito.doReturn(10).when(util).get();
assertEquals(10, util.anIntMethod());
}
}
在这两种情况下,模拟部件都显示为未覆盖,这是正确的。