我有一种情况,在带有仪器测试的 Android 项目中,我已经预编译了所有生产代码并准备作为 .apk
安装。 (一个 React Native 环境)。
每当我运行仪器测试时,我最初都会构建 AndroidTest .apk
通过运行使用 Gradle:
./gradlew assembleDebugAndroidTest -DtestBuildType=debug
(即以非常标准的方式)。
麻烦的是,尽管明确指定了
xxxAndroidTest
任务,所有生产代码组装 Gradle 任务也会运行。这对我来说非常浪费时间,因为——正如我所解释的,生产 apk
已经存在,因此代码编译(以及打包、签名等)很少。从本质上讲,我在生产代码中没有依赖于检测代码——甚至是
ActivityTestRule
。我使用的是动态创建的,并且不直接绑定(bind)到我的主要 Activity :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 检查任务树,但找不到一个明确的地方来“砍树”。
最佳答案
到目前为止,我已经提出了这个(启发式)解决方案,它做了两件事:
implementation
s 来自测试大楼。 它归结为这个帮助 Gradle 脚本:
// 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 '---------------------------------------'
}
}
即
dependenciesExcludeTest
启用排除不需要的子项目,并且任务图就绪回调执行禁用。 注意正则表达式列表是定制的,不是通用的 .这对我的项目很有意义,因为 react 原生项目有一个重量级的 JS bundle 任务,称为 bundleJsAndAssets
。 ,我也安装了新的遗物。然而,这可以很容易地适应任何项目。此外,
app.gradle
看起来像这样: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')
}
因此,当 gradle 像这样运行时(即使用自定义 TURBO_TEST_APK 属性):
./gradlew assembleDebugAndroidTest -DtestBuildType=debug -DTURBO_TEST_APK
该脚本将应用其工作并减少整体构建时间。
这个解决方案不是最优的:难以维护,不会省略 全部 的不必要的工作。我很高兴看到更有效的解决方案。
关于android - 隔离测试 APK 构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56948373/