在现实世界中,如果您要为android项目编写ui测试,请在从Android Studio中按“运行”后,它将组装两个应用程序:“your.cool.app”和“your.cool.app.test”。测试应用将在android中显示类似以下内容:
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="your.cool.app"/>
这实际上意味着,如果同时安装它们和您的测试应用程序,则它们将与真正的应用程序合并-所有依赖项(第三方库等)都将在一个运行时类路径中。因此,如果两个应用程序将具有某种类型的库,则无法将它们合并,因为不可能在运行时类路径中过多地包含多个类,否则您将获得重复的类异常。
这就是为什么您具有Android插件功能的原因,该功能允许您为测试应用程序
androidTestImplementation
添加依赖项。因此,如果添加两个类似的依赖项,例如:implementation 'com.google.android.material:material:1.0.0'
androidTestImplementation 'com.google.android.material:material:1.0.0'
Gradle将解决此类问题。因此,对于真正的应用程序,它将添加到编译和运行时类路径中;对于测试应用程序,它将仅添加到编译类路径中(这就是为什么您可以从测试类中的依赖项中导入所有内容的原因)
由于某种原因,我正在使用两个不同的应用程序。当我为这两个应用程序添加依赖项时:
implementation 'com.google.android.material:material:1.0.0'
我将有一个
Duplicate classes '...'
是的,最好的解决方案是制作一个单声道存储库,然后让Android Gradle Plugin解决此问题...
但是我不能,因为在这种情况下,没有主代码就无法共享测试代码。
是的,我们已经有一个'compileOnly',它可以完美工作(它只添加了一个依赖项来编译类路径),但是它仅适用于 JAR和。所以我需要一个像'compileOnly'这样的 Artifact 配置,但是对于 AAR
我已经尝试过的:
allprojects {
createCompileOnlyAarConfiguration(project)
}
def createCompileOnlyAarConfiguration(Project project) {
def compileOnlyAarConf = project.configurations.create('compileOnlyAar')
compileOnlyAarConf.visible = false
compileOnlyAarConf.transitive = false
project.gradle.addListener(new DependencyResolutionListener() {
@Override
void beforeResolve(ResolvableDependencies resolvableDependencies) {
compileOnlyAarConf.dependencies.each { dependency ->
project.dependencies.add('compileOnly', dependency)
}
project.gradle.removeListener(this)
}
@Override
void afterResolve(ResolvableDependencies resolvableDependencies) {
}
})
}
所以现在我可以做类似的事情:
dependencies {
compileOnlyAar 'com.google.android.material:material:1.0.0'
}
通过这种配置,我可以使用这些依赖关系中的所有类,但是在最终的dex文件中,其中没有使用过的方法的引用。这就是为什么我得到
java.lang.NoSuchMethodError: java.lang.NoSuchMethodError: No static method
我还发现了gradle plugin,实际上添加了一个'compileOnlyAar'配置,但它仅适用于Java模块
我在gradle环境中不是很好,所以如果有人可以指出我如何为AAR Artifact 制作“compileOnly”,那将很酷。
更新:
“出于某种原因,我正在使用两个不同的应用程序”-意味着我也有“your.cool.app”和“your.cool.app.test”应用程序。但是它们具有自己的gradle依赖关系,并且测试应用在AndroidManifest中具有
instrumentation
属性。 'your.cool.app'-主代码库,'your.cool.app.test'-所有ui测试。安装完两者后,我只是通过adb shell am instrument
运行测试。测试应用程序和主应用程序需要依赖项com.google.android.material:material:1.0.0
,因此它们都包含:dependencies {
implementation 'com.google.android.material:material:1.0.0'
}
因此,正如我所说,如果同时安装两个应用程序并通过
adb shell am instrument
启动测试,我将得到重复的类异常,因为两个二进制文件在运行时类路径中都将是两次。为什么我需要这种结构?没有主代码库,我只能共享测试应用程序。所以我没有办法制作标准的monorepo
最佳答案
在android studio的右侧,转到gradle>您的libraryapp>运行配置>组装.AAR将出现在您所选项目的输出文件夹中