如何使用Gradle覆盖android测试路径?

时间:2016-08-10 13:35:20

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

由于历史原因,检测测试未存储在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(instrumentation)测试?

这是我当前的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'.

3 个答案:

答案 0 :(得分:0)

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

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

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

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

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

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

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

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

可以在Configuring the Structure

上阅读更多Android Gradle详细信息

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

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

    println "androidTest.manifest.srcFile = ${androidTest.manifest.srcFile}"
    println "androidTest.java.srcDirs = ${androidTest.java.srcDirs}"
}

当您只是清理项目时,您将看到这些行被打印到控制台

答案 1 :(得分:0)

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

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源集。

答案 2 :(得分:0)

这是一个棘手的解决方案:使用实验性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) {}
}

library 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')
}