隔离测试APK版本

时间:2019-07-09 08:28:48

标签: android gradle android-gradle apk android-instrumentation

我遇到这样的情况,在一个带有工具测试的Android项目中,我已经预编译了所有生产代码,并准备作为.apk(React Native环境)安装。

每当我运行仪器测试时,我都会先通过运行以下命令使用Gradle构建AndroidTest .apk

./gradlew assembleDebugAndroidTest -DtestBuildType=debug

(即以一种非常标准的方式)。

问题在于,尽管仅明确指定了xxxAndroidTest任务,但是所有生产代码汇编Gradle任务也都在运行。这对我来说是一个极端的时间浪费,因为-正如我所解释的,生产apk已经存在,因此代码编译(以及包装,签名等)稀缺。

从本质上讲,我不依赖于规范代码中的生产代码,即使我使用的ActivityTestRule是动态创建的,也不直接绑定到我的 main 活动:< / p>

Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(launchIntent, 0);
Class<?> activityClass = Class.forName(resolveInfo.activityInfo.name);
ActivityTestRule<?> activityTestRule = new ActivityTestRule(activityClass, false, false);

问题是:如何隔离/限制Gradle的工作,使其仅包含与测试相关的任务?我什至尝试使用this Gradle plugin检查任务树,但是找不到清除“砍树”的明确地方。

1 个答案:

答案 0 :(得分:0)

到目前为止,我已经提出了这个(启发式)解决方案,它可以完成两件事:

  1. 我注意到浪费的大部分时间是由于工作不需要的子项目。因此,该解决方案提供了一种从{em> test 构建中排除HTML的简便方法。

  2. 在列表中剩余的任务中,插件仍然迭代地强制禁用无关但仍在运行的任务。

它归结为以下帮助器Gradle脚本:

implementation

也就是说,// turbo-test-apk.gradle def isEnabled = System.getProperty('TURBO_TEST_APK') != null project.ext.dependenciesExcludeTest = { depsClosure -> if (!isEnabled) { dependencies(depsClosure) } } gradle.taskGraph.whenReady { graph -> if (isEnabled) { def disabledTasks = new ArrayList<Task>(graph.allTasks.size()) [/.*JsAndAssets.*/, /package.*Release/, /package.*Debug/, /compile.*/, /.*[Pp]roguard.*/, /.*[Nn]ew[Rr]elic.*/, /.*AndroidTest.*/].forEach { regex -> graph.allTasks.findAll { it.name ==~ regex }.forEach({ task -> disabledTasks.add(task) task.enabled = false }) } graph.allTasks.findAll { it.name ==~ /.*AndroidTest.*/ }.forEach({ task -> task.enabled = true }) println '--- Turbo test build: task scanning ---' disabledTasks.forEach { task -> if (!task.enabled) { println 'Force-skipping ' + task } } println '---------------------------------------' } } 启用了不需要的子项目的排除,而task-graph-ready回调则禁用了该子项目。 请注意,正则表达式列表是自定义的,并非通用。对我的项目而言,这很有意义,因为react本机项目有一个名为dependenciesExcludeTest的重量级JS捆绑任务,并且我还安装了新的版本。不过,可以轻松地将其定制为任何项目。

此外,bundleJsAndAssets看起来像这样:

app.gradle

因此,当gradle这样运行时(即使用自定义的TURBO_TEST_APK属性):

apply plugin: 'com.android.application'

apply from: './turbo-test-apk.gradle'

dependencies {
    implementation "org.jetbrains.kotlin:$kotlin_stdlib:$kotlinVersion"
    implementation "com.android.support:support-v4:$supportLibraryVersion"
    implementation "com.android.support:appcompat-v7:$supportLibraryVersion"
    // etc.
}
// These will be excluded when executing test-only mode
dependenciesExcludeTest {
    implementation project(':@react-native-community_async-storage')
    implementation project(':any-unneeded-sub-project')
}

该脚本将应用其工作并减少总体构建时间。

此解决方案不是最佳解决方案:维护起来很棘手,不会遗漏所有不必要的工作。我很高兴看到更有效的解决方案。