手动测试,收集代码覆盖测试报告的一点胡思乱想

引文

How to get Code Coverage during Manual Testing for Android App

有一篇博客 How to get Code Coverage during Manual Testing for Android App(下文用 ManualJacoco 指代它),里面提到一种方法,就是编译后手动点,在手机上把执行的信息存到文件中,然后再拉回gradle编译出报告。细节方法看连接里的文章吧。这篇文章是对操作之后的一点思考。

我在前一篇文章中,花了不少时间把gradle的包装去掉,但是真的落地用的时候。发现pitest、cobertura都没有jacoco这么简单的集成&&完整的支持,完整的支持 看起来是一个可以研究的点。

好奇gradle到底做了什么?后来发现,准确的说这两个插件做了什么?

org.gradle.testing.jacoco.plugins.JacocoPluginExtension
com.android.tools.build:gradle

一点表象

根据 ManualJacoco 做了一波之后,脚本执行的有几行指令

# step 1
# build && apply jacoco offline instrument %% generate apk
./gradlew assembDebug && \
adb install app/build/outputs/apk/debug/app-debug.apk

# step 2
# do manual ui test in android‘phone ,and dump exec message into file

# step 3
# pull exec info ,according local code generate html report
mkdir -p app/build/outputs/code-coverage/connected && \
adb pull /sdcard/coverage.exec app/build/outputs/code-coverage/connected/coverage.exe && \
./gradlew jacocoTestReport

先打开debug开关,然后从日志来分析

./gradlew assembDebug -d

说几个看到的信息

1,用到org.gradle.testing.jacoco.plugins.JacocoPluginExtension 这个插件

2,配置之后,用到了这里的配置

…/Android/sdk/extras/m2repository/org/jacoco/org.jacoco.agent/0.7.9/org.jacoco.agent-0.7.9.pom
…/Android/sdk/extras/android/m2repository/org/jacoco/org.jacoco.agent/0.7.9/org.jacoco.agent-0.7.9.pom
…/Android/sdk/extras/google/m2repository/org/jacoco/org.jacoco.agent/0.7.9/org.jacoco.agent-0.7.9.pom

3,jacoco的几个jar包好像有被打进dex中,包括

org.jacoco.agent-runtime.jar
org.jacoco.report.jar
org.jacoco.core.jar
org.jacoco.agent.jar
org.jacoco.ant.jar

用AS的工具分析下,AS -> build -> analyze apk…

确实是有吧jacoco的代码打进dex包中,所以这里就不用担心分包的问题了。但是很迷的是,因为没有显性的引用,写代码的时候,引用import org.jacoco.agent.rt.RT 会报错,导致这里只能用反射去拿jacoco才能dump执行信息到文件 :(

有没有办法不用反射就能拿到jacoco?或者是只能通过反射调用,有什么好处?

当然是可以有的。但是不这样做,应该是考虑到这个是一个优化功能。正式版本都不会用到。所以做成反射去用是最好的。
看到天娇也是这样做的。一开始没get到他为什么要这么做。昨晚突然想通了,就是要这样做,无感知最好。只用这个插件,只需要把开关打开,要不要反射调用是你的事情,我不污染你的代码。

扯远了,我一开始也是对gradle这个完全没概念,补了一波背景,写了一个stay alone 插件之后,才知道这个东西是怎么work的。现在开始进入正文。

如何生成Jacoco(代码覆盖测试)的报告

插件JacocoPluginExtension实现了这部分的功能。

git clone https://github.com/gradle/gradle.git

JacocoReport.java

new AntJacocoReport(getAntBuilder()).execute(
    getJacocoClasspath(),
    getProject().getName(),
    getAllClassDirs().filter(fileExistsSpec),
    getAllSourceDirs().filter(fileExistsSpec),
    getExecutionData(),
    getReports()
);

看起来是用了ant的生成报告,这里我确实没找到它时怎么调用进ant的(PS : key world应该是 jacocoagent.jar)

我用这段代码也顺利的生成的网页报告.

# 
java -jar jacococli.jar report \
app/build/outputs/code-coverage/connected/coverage.exec \
--classfiles app/build/intermediates/classes/debug \
--sourcefiles app/src/main/java \
--html out

需要注意的是,

1,kotlin生成的class文件放在了 app/build/tmp/kotlin-classes/debug 这个需要合并过去。

2,生成出来的文件也许会有点杂乱,但是可以把一些无关的内部类去掉,显示就清晰许多了,这个方面可以修改下jacoco的报告,美化小报告的效果。

关键的信息有几个:

  • exec文件
    如何生成,见ManualJacoco
  • 编译之后的class文件
    这里的class未被插桩 eg:
    app/build/intermediates/classes/debug
    app/build/tmp/kotlin-classes/debug/
  • 源码
    apk也可以获取源码,因为代码没有混淆,很简单就可以反编译出来

如何进行代码覆盖测试

Android Plugin for Gradle 实现了这部分的功能

git clone https://android.googlesource.com/platform/tools/base
git checkout gradle_3.1.2

TaskManager.java

if (baseVariantData.getVariantConfiguration().getBuildType().isTestCoverageEnabled()) {

    Configuration jacocoAntConfiguration =
            JacocoConfigurations.getJacocoAntTaskConfiguration(
                    project, getJacocoVersion(variantScope));
    JacocoReportTask reportTask =
            taskFactory.create(
                    new JacocoReportTask.ConfigAction(
                            variantScope, jacocoAntConfiguration));

    reportTask.dependsOn(connectedTask.getName());

    variantScope.setCoverageReportTask(reportTask);
    baseVariantData.getScope().getCoverageReportTask().dependsOn(reportTask);

    taskFactory.configure(
            CONNECTED_ANDROID_TEST,
            connectedAndroidTest -> connectedAndroidTest.dependsOn(reportTask.getName()));
}

从日志上来看,生成class之后,插桩放到目录

app/build/intermediates/transforms/jacoco/debug/0

当前3.1.2用的jacoco版本是0.7.9

Jar input /Users/yeshen/.gradle/caches/modules-2/files-2.1/org.jacoco/
org.jacoco.agent/0.7.9/a6ac9cca89d889222a40dab9dd5039bfd22a4cff/
org.jacoco.agent-0.7.9-runtime.jar

原理可以看这篇文章

打通Android Gradle编译过程的任督二脉

猜你喜欢

转载自blog.csdn.net/yeshennet/article/details/80260967
今日推荐