【问题标题】:How to override android tests path with Gradle?如何用 Gradle 覆盖 android 测试路径?
【发布时间】:2016-08-10 13:35:19
【问题描述】:

由于历史原因,仪器测试未存储在androidTests 目录as required 中,并且我无法更改目录结构(实际上整个应用程序是对所用库的测试)。我能够使用 gradle 构建和安装 apk,但没有找到测试:

:app-tests:connectedDebugAndroidTest
Tests on test_avd(AVD) - 4.1.2 failed: Instrumentation run failed due to 'java.lang.ClassNotFoundException'

com.android.builder.testing.ConnectedDevice > No tests found.[test_avd(AVD) - 4.1.2] FAILED 
No tests found. This usually means that your test classes are not in the form that your test runner expects (e.g. don't inherit from TestCase or lack @Test annotations).
:app-tests:connectedDebugAndroidTest FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app-tests:connectedDebugAndroidTest'.
> There were failing tests. See the report at: file:///Users/asmirnov/Documents/dev/src/project/app-tests/build/reports/androidTests/connected/index.html

实际上测试在src文件夹中,正确编写并且可以使用Ant构建/运行:

public abstract class BaseTest extends AndroidTestCase
{
...

public class AppInfoTest extends BaseTest
{
    @Test
    public void testAllProperties()
    {
        ...

...

如何将 Gradle 进程 src 文件夹作为 android(仪器)测试?

这是我当前的 build.gradle 文件(它使用 experimental Android Gradle plugin 版本 0.7.2,因为我们有一个 NDK 库):

apply plugin: 'com.android.model.application'

allprojects {
    repositories {
        mavenLocal()
        mavenCentral()
    }
}

repositories {
    mavenLocal()
    mavenCentral()
}

model {
    android {
        compileSdkVersion 16
        buildToolsVersion "22.0.1"

        defaultConfig {
            applicationId "app.tests"
            minSdkVersion.apiLevel 9
            targetSdkVersion.apiLevel 16
            versionCode 359
            versionName "1.3"

            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }

        sources {
            main {
                // overriding paths from default ones to actual ones
                // what about 'androidTests' ?
                manifest { source {
                    srcDir '.'
                    include 'AndroidManifest.xml'
                } }
                java { source { srcDirs = ['src'] } }
                res { source { srcDirs = ['res'] } }
                jni {
                    dependencies {
                        project ":library" // native library dependency
                    }
                }
            }
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile project(':library')
}

更新 1(用于 sschuberth)

配置:

apply plugin: 'com.android.model.application'

allprojects {
    repositories {
        mavenLocal()
        mavenCentral()
    }
}

repositories {
    mavenLocal()
    mavenCentral()
}

model {
    android {
        compileSdkVersion 16
        buildToolsVersion "22.0.1"

        defaultConfig {
            applicationId "app.tests"
            minSdkVersion.apiLevel 9
            targetSdkVersion.apiLevel 16
            versionCode 359
            versionName "1.3"

            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }

        sourceSets {
            androidTest {
                manifest.srcFile 'AndroidManifest.xml' // error here
                java.srcDirs = ['src']
                res.srcDirs = ['res']
                assets.srcDirs = ['assets']
            }
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile project(':library')
}

错误

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/asmirnov/Documents/dev/src/project/app-tests/build.gradle' line: 32

* What went wrong:
A problem occurred configuring project ':app-tests'.
> Exception thrown while executing model rule: android { ... } @ app-tests/build.gradle line 16, column 5
   > Could not find property 'manifest' on source set 'android test'.

【问题讨论】:

    标签: java android unit-testing gradle android-instrumentation


    【解决方案1】:

    不完全确定这是否适用于您的方案,但您可以像这样更新androidTest sourceSet 的根目录

    android {
        sourceSets {
            androidTest.setRoot('src')
        }
    }
    

    还有一个 test 源集,如果它只是 Java 代码,没有特定于 Android 的。

    您也可以使用java.srcDir 设置...

    上述设置将查看您的文件的这些位置。

    <project>/<module>/src/AndroidManifest.xml
    <project>/<module>/src/java
    

    如果您想将两者都移动到/src 目录中,您可以使用

    sourceSets {
        androidTest {
            setRoot 'src'
            java.srcDirs = ['src']
        }
    }
    

    更多 Android Gradle 细节可以在Configuring the Structure阅读


    欢迎您使用此设置自行调试这些设置

    sourceSets {
        androidTest {
            setRoot 'src'
            java.srcDirs = ['./src']
        }
    
        println "androidTest.manifest.srcFile = ${androidTest.manifest.srcFile}"
        println "androidTest.java.srcDirs = ${androidTest.java.srcDirs}"
    }
    

    当你清理项目时,你会看到这些行被打印到控制台

    【讨论】:

    • &gt; Could not find method manifest() for arguments [build_5blgy0rxz915fycj6huh3b3bg$_run_closure3$_closure6$_closure8$_closure9$_closure10@46935c97] on source set 'main'. 可能是因为实验性 gradle 插件。我还检查了不是在“主”源集中添加它,而是在 SourceSets 中添加,就像链接上的示例一样
    • 不知道为什么您告诉我原始代码中存在的错误。我没有显示清单关闭
    • 是的,就像我说的那样,我不知道您的错误,因为它指的是 manifest 设置,我没有说什么。欢迎您查看我的答案中的链接,了解如何正确识别源集的清单文件
    • 我已经点击了链接,但它不像示例中那样工作
    • 是的,它需要一个清单,因为测试应用实际上是带有检测代码的常规应用。你的意思是什么错误?
    【解决方案2】:

    您应该使用sourceSets {}androidTest 源集来自定义测试源代码位置,而不是sources {}

    model { // Required for experimental plugin.
        android {
            sourceSets {
                androidTest {
                    manifest.srcFile '../AppTest/AndroidManifest.xml'
                    java.srcDirs = ['../AppTest/src']
                    res.srcDirs = ['../AppTest/res']
                    assets.srcDirs = ['../AppTest/assets']
                }
            }
        }
    }
    

    请注意,这不适用于单元测试。对于单元测试(如Robolectric),使用test 源集。

    【讨论】:

    • 不工作:* What went wrong: A problem occurred configuring project ':app-tests'. &gt; Exception thrown while executing model rule: android { ... } @ app-tests/build.gradle line 16, column 5 &gt; Could not find method manifest() for arguments [build_5blgy0rxz915fycj6huh3b3bg$_run_closure3$_closure6$_closure8$_closure9$_closure10@a3d6b33] on source set 'android test'. 还要注意实验性插件语法与主流不同。
    • 这不是实验性的插件语法,我从 2015 年就开始使用它。另外,源集应该被称为 androidTest 而不是 android test
    • 我正在使用实验性 gradle 插件(0.7.2),上面的代码不适合它
    • 我错过了外部 model 闭包。我已经编辑了我的答案。
    【解决方案3】:

    这是一个棘手的解决方案:使用实验性 gradle 插件来编译带有 NDK 的本机代码和用于测试应用程序的常规 gradle 插件。

    build.gradle:

    buildscript {
      repositories {
        mavenLocal()
        mavenCentral()
        jcenter()
      }
      dependencies {
        // experimental gradle plugin for the library to compile native code with NDK
        classpath "com.android.tools.build:gradle-experimental:0.7.2"
    
        // regular gradle plugin for the tests
        classpath 'com.android.tools.build:gradle:2.1.2'
      }
    }
    
    subprojects {
      task listAllDependencies(type: DependencyReportTask) {}
    }
    

    库 gradle(实验性):

    apply plugin: 'com.android.model.library'
    
    ...
    
    model {
    
        android {
          ...
          ndk {
              moduleName = "library-jni"
              cppFlags.add("-std=c++11")
              cppFlags.add("-fexceptions")
              stl = "c++_static"
    
              abiFilters.addAll(['armeabi-v7a', 'x86']) // supported abis only
           }
           ...
        }
        ...
    }
    

    app/build.gradle(常规):

    apply plugin: 'com.android.application'
    
    allprojects {
      repositories {
        mavenLocal()
        mavenCentral()
      }
    }
    
    repositories {
      mavenLocal()
      mavenCentral()
    }
    
    android {
      compileSdkVersion 16
      buildToolsVersion "22.0.1"
    
      defaultConfig {
        applicationId "app.tests"
        minSdkVersion 9
        targetSdkVersion 16
        versionCode 359
        versionName "1.3"
    
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
      }
    
      sourceSets {
        main {
          manifest.srcFile 'AndroidManifest.xml'
        }
    
        androidTest {
          manifest.srcFile 'AndroidManifest.xml'
          java.srcDirs = ['src']
    
          jni {
            dependencies {
              project ":library"
            }
          }
        }
      }
    }
    
    dependencies {
      androidTestCompile project(':library')
      androidTestCompile fileTree(include: ['*.jar'], dir: 'libs')
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-14
      • 1970-01-01
      • 1970-01-01
      • 2016-09-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多