当前位置: 首页 > article >正文

Android 单元测试环境配置问题 Execution failed for task ‘:mergeDebugJavaResource‘.

背景和挑战

随着人工智能(AI)技术的迅猛发展,AI在各行各业的应用前景被普遍看好。无论是在医疗、金融、教育,还是在软件开发领域,AI都展示出了巨大的潜力。然而,尽管AI能够在许多方面提供支持和提升效率,但在软件开发尤其是Android单元测试过程中,AI并不能解决所有功能问题,特别还有开发环境的问题。

ChatGPT确实能提供方案,但是在单元测试领域,尤其是Android跟UI业务强相关的测试案例上,依然是更需要人工介入的设计。

AI在Android单元测试中的制约

在Android开发过程中,单元测试是确保代码质量和功能实现的重要环节。尤其在构建复杂应用时,开发者需要对大量的类和方法进行测试。然而,面对以下两类问题,AI工具往往显得力不从心:

  1. 业务逻辑复杂性:
    AI可能会在代码自动生成和测试用例建议方面提供帮助,但对于应用中复杂的业务逻辑,AI工具通常无法完全理解开发者的意图或业务场景。AI生成的测试用例可能覆盖面广,但由于缺乏对实际业务逻辑的深入理解,它们往往无法有效捕捉到潜在的逻辑错误和边缘情况。例如,考虑一个用户输入验证的功能,AI可能很难准确模拟用户的各种输入情境,导致某些逻辑分支未被测试到。

  2. 环境依赖性:
    Android开发环境的配置往往复杂多变,不同的Android Studio版本、SDK版本以及第三方库的依赖关系等都会影响到单元测试的运行结果。当开发环境没有正确配置时,AI工具提供的自动化测试方案可能无法如预期运行。此外,某些调试错误的产生,往往是由于环境不一致造成的,而AI工具无法直接解决这类依赖性问题。随着Android Studio以及相关工具的更新迭代,许多开发者在配置本地环境时常常面临不兼容或设置不当的问题,这可能会导致调试错误率显著上升。

应对措施

面对AI技术在Android开发中的局限性,开发者需要采取有效的措施来确保软件质量。

  1. 加强人工审查:
    尽管AI可以为代码和测试生成提供便利,开发者仍需在关键业务逻辑和边缘情况的测试上进行人工审查。这包括审查AI生成的测试用例,确保它们涵盖所有必要场景。

  2. 强化开发环境规范:
    围绕Android项目建立标准化的开发环境配置文档,并鼓励团队成员严格遵循,可以有效降低因环境配置不当引发的调试错误率。同时,使用容器化技术(如Docker)可以帮助创建一致的开发环境,减少环境依赖性问题。

  3. 积极学习与应对AI的负面影响:
    开发者应保持对AI技术动向的敏感,定期学习有关AI技术的最新研究和应用案例,合理利用AI工具的优势,同时意识到其局限性。

问题案例

环境配置

为什么编译会关联到其他app模块的报错?

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':mergeDebugJavaResource'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.MergeJavaResWorkAction
   > 4 files found with path 'META-INF/LICENSE-notice.md' from inputs:

      - E:\AndroidStudioCode\TestDemoU\.gradle\caches\transforms-4\bac8a02ec876d96f400e223a6f964115\transformed\jetified-junit-platform-engine-1.8.2.jar
      - E:\AndroidStudioCode\TestDemoU\.gradle\caches\transforms-4\3ddceeb372c20321054059e75b202cf1\transformed\jetified-junit-platform-commons-1.8.2.jar
      - E:\AndroidStudioCode\TestDemoU\.gradle\caches\transforms-4\1e6645cc7923ded6fc2e47df844244a4\transformed\jetified-junit-jupiter-engine-5.8.2.jar
      - E:\AndroidStudioCode\TestDemoU\.gradle\caches\transforms-4\5f005f3f5e87a878afdb727ca13fce01\transformed\jetified-junit-jupiter-api-5.8.2.jar
     Adding a packaging block may help, please refer to
     https://developer.android.com/reference/tools/gradle-api/8.4/com/android/build/api/dsl/Packaging
     for more information

问题分析:

如上错误提示显示在执行 :mergeDebugJavaResource 任务时,多个库中发现了相同的文件(在本例中是 META-INF/LICENSE-notice.md)。这是在 Gradle 构建过程中常见的资源合并冲突问题。

mergeDebugJavaResource 解决方案

1、使用 Gradle 的 packagingOptions:

  • 可以在 build.gradle 文件中使用 packagingOptions 来解决资源合并冲突。
    • 若不存在此项配置,请在build.gradle 新增 packagingOptions 块,用于排除重复文件。
  • 通过配置 exclude 来排除多余的文件。例如,在android 块内添加以下代码:

Groovy (Gradle)

android {
    ...
    packagingOptions {
        exclude 'META-INF/LICENSE-notice.md' //本案例是此问题,如下是相关配置
        exclude 'META-INF/LICENSE.md'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }
}

Note:Gradle 是基于 Groovy 的 DSL(领域特定语言),尽管 Gradle 使用 Groovy 作为其脚本语言,但它们在用途和功能上有显著的区别。

Groovy 和 Gradle 的区别
特性GroovyGradle
类型编程语言(一种基于 Java 的动态语言)构建自动化工具
基于Java 虚拟机 (JVM)Groovy
目的开发各种类型的应用、脚本和测试管理和自动化构建过程
语法灵活、简洁,支持动态类型基于 Groovy 的 DSL(领域特定语言)
使用领域应用开发、快速原型、测试项目构建、依赖管理
生态系统与 Java 完全兼容,广泛用于各种应用支持多种语言和框架,尤其是 Java 和 Android

2、查看冲突的依赖库:
确认冲突的文件来源于哪些库,并检查这些库的版本。如果某些库的版本过旧或不兼容,考虑升级它们。例如,可能会看到 junit-platform-engine 和 junit-platform-commons 的版本。不妨确保所有相关的 JUnit 依赖库都是相同的版本。

结果:但是如上报错的文件夹已经不存在了,还是会报错,没有采用这种方式解决,无法解除相关gradle 文件的依赖。

3、运行 Gradle 依赖报告:
使用以下命令生成依赖树,查看具体使用了哪些库及其版本:

# 查看使用的依赖库和版本
./gradlew app:dependencies

结果:可是本地环境始终有问题,是运行任何gradle都报错的版本冲突

  • apiElements
  • javadocElements
  • runtimeElements
./gradlew 报错1
./gradlew 报错1
./gradlew 报错2
./gradlew 报错2

* What went wrong:
A problem occurred configuring root project 'Demo'.
> Could not resolve all artifacts for configuration ':classpath'.
   > Could not resolve com.android.tools.build:gradle:8.4.0.

     Required by:
         project :
      > No matching variant of com.android.tools.build:gradle:8.4.0 was found. The consumer was configured to find a library for use during runtime, compatible with Java 8, packaged as a jar, and its dependencies declared externally, as well as attribute 'org.gradle.plugin.api-version' with value '8.7' but:
          - Variant 'apiElements' declares a library, packaged as a jar, and its dependencies declared externally:
              - Incompatible because this component declares a component for use during compile-time, compatible with Java 11 and the consumer needed a component for use during runtime, compatible with Java 8
              - Other compatible attribute:
                  - Doesn't say anything about org.gradle.plugin.api-version (required '8.7')
          - Variant 'javadocElements' declares a component for use during runtime, and its dependencies declared externally:
              - Incompatible because this component declares documentation and the consumer needed a library
              - Other compatible attributes:
                  - Doesn't say anything about its elements (required them packaged as a jar)
                  - Doesn't say anything about its target Java version (required compatibility with Java 8)
                  - Doesn't say anything about org.gradle.plugin.api-version (required '8.7')
          - Variant 'runtimeElements' declares a library for use during runtime, packaged as a jar, and its dependencies declared externally:
                  - Doesn't say anything about org.gradle.plugin.api-version (required '8.7')

JDK版本不对——修改Project Structure中的JDK版本也不对。

Project Structure - Modules
Project Structure - Modules

引出更多的配置问题了,有关于单个配置,也有多文件版本适配的问题。

直接在控制台使用./gradlew命令大概是全局环境的问题,而GUI里面的单独项目gradle看起来可以运行,可是没有任何输出

4、使用 implementation 或 api 而不是 compile:
确保在使用依赖时使用了最新的配置方法,比如 implementation 或 api,而不是过时的 compile。这有助于避免潜在的版本冲突。

5、清理和重建项目:
有时构建缓存可能导致问题,可以通过以下命令清理项目然后再次尝试构建项目

# 清理
./gradlew clean

# 重新构建
./gradlew assembleDebug

结果:尝试了清除和重新配置,都不可以。

测试用例设计

待完善


http://www.kler.cn/a/389728.html

相关文章:

  • 如何为电子课程创造创意
  • 云原生-docker安装与基础操作
  • Python的Web请求:requests库入门与应用
  • Java反序列化之CommonsCollections2链的学习
  • Android HandlerThread 基础
  • 华为网络设备这些“危险命令”,切记不能瞎操作!
  • J2EE平台
  • CompletableFuture:supplyAsync与runAsync
  • 【Spring】Spring框架中有有哪些常见的设计模式
  • macOS 下的 ARM 裸机嵌入式开发入门- 第二部分:实现第一个裸机应用并且调试
  • 深入提升Python编程能力的全方位指南
  • mac 安装指定的node和npm版本
  • 中间件安全
  • 大数据新视界 -- 大数据大厂之 Impala 性能优化:数据加载策略如何决定分析速度(上)(15/30)
  • 机器学习(基础1)
  • 基于springboot+小程序的鲜花管理系统(鲜花1)
  • 小马识途营销顾问谈百科词条建立的注意事项
  • 网络安全:构建坚固的数字堡垒
  • 【C++ 算法进阶】算法提升十三
  • HCIP小型园区网拓扑实验
  • Java基础Day-Seventeen
  • 【算法一周目】双指针(1)
  • Android Auto 不再用于旧手机
  • HTML5:网页开发的新纪元
  • 埃隆·马斯克的 AI 初创公司 xAI 推出了 API
  • 链式结构二叉树