我遇到这样的情况,在一个带有工具测试的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检查任务树,但是找不到清除“砍树”的明确地方。
答案 0 :(得分:0)
到目前为止,我已经提出了这个(启发式)解决方案,它可以完成两件事:
我注意到浪费的大部分时间是由于工作不需要的子项目。因此,该解决方案提供了一种从{em> test 构建中排除HTML
的简便方法。
在列表中剩余的任务中,插件仍然迭代地强制禁用无关但仍在运行的任务。
它归结为以下帮助器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')
}
该脚本将应用其工作并减少总体构建时间。
此解决方案不是最佳解决方案:维护起来很棘手,不会遗漏所有不必要的工作。我很高兴看到更有效的解决方案。