如何将 Android (instrumentation) 测试文件放在项目目录之外?

How to place Android (instrumentation) test files outside of project directory?

我有一个 Android 项目(由 Cordova 生成),我想向其中添加(检测)测试。它只有一个 MainActivity.java 应该被测试。

通常这意味着向 build.gradle 添加一些依赖项并使用 MainActivityTest class 和一些测试方法创建一个文件 /src/androidTest/java/org/example/package/MainActivityTest.java。 (在 Android Studio 中,我什至可以使用 运行 -> "Record Espresso Test" 生成它们 - 非常简单且有效)。

不幸的是,我现在要求那些测试文件确实存在于项目目录之外。现有的 Cordova 项目应该只有最小的变化(因为它是作为构建工件重新生成和处理的)。 MainActivity.java 最好位于 Android 项目位于 /android.

的同一根文件夹中

我怎样才能做到这一点?


可以将 build.gradle 更改添加到真正的 build.gradle 已经包含的 build-extras.gradle 文件中,因此这会得到处理。

但我不知道如何将 MainActivityTest.java 放在项目文件夹结构之外,并且仍然能够 运行 它在项目中。

对于iOS,您可以link 将外部文件添加到具有绝对路径的项目中。类似的东西在这里也很完美。

我查看了 sourceSets,但我不确定如何将其集成到 Cordova Android 项目中,该项目已经具有此非默认值(我认为?)sourceSets

android {
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
            jniLibs.srcDirs = ['libs']
        }
    }
    ...
}     

有两种方式:

  1. 您可以仅使用 Android Studio 3.0。为此,我使用了:

    Android Studio 3.0 Beta 6

    Android Gradle Plugin: 'com.android.tools.build:gradle:3.0.0-beta6'

  2. 您可以为您的仪器测试创建一个单独的模块(您可以将其放在应用程序项目之外的任何文件夹中)。为此,您可以使用:

    With Android Studio 3.0.0

    With Android Gradle Plugin 3.0.0

    With Gradle Wrapper 4.2.1-all

    如果您收到 error 说明无法合并 instrumentation-test-module 和 app-module 的 AndroidManifest,则您可能仅限于旧 Gradle 版本

    Tested with Android Studio 2.3.3 and 3.0.0

    The highest Android Gradle Plugin will be 2.2.3

    Gradle Wrapper 3.3-all (or 3.4.1 / 4.2.1)

    注意:这对于 Android Gradle 插件 2.3.0!

  3. 已损坏

我创建了 SAMPLE PROJECT 来演示两种情况下的测试结构。


project/module的build.gradle必须使用这个插件:

// A plugin used for test-only-modules
apply plugin: 'com.android.test'

此插件使用 TestExtension (link to its DSL)。使用 TestExtension'com.android.test' 插件,您的 gradle 文件将如下所示:

apply plugin: 'com.android.test'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.2"
    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 26

        // The package name of the test app
        testApplicationId 'com.example.android.testing.espresso.BasicSample.tests'
        // The Instrumentation test runner used to run tests.
        testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
    }
    // Set the target app project. The module specified here should contain the production code
    // test should run against.
    targetProjectPath ':app'
}

dependencies {
    // Testing-only dependencies
    // Force usage of support annotations in the test app, since it is internally used by the runner module.
    compile 'junit:junit:4.12'
    compile 'com.android.support:support-annotations:25.4.0'
    compile 'com.android.support.test:runner:1.0.1'
    compile 'com.android.support.test:rules:1.0.1'
    compile 'com.android.support.test.espresso:espresso-core:3.0.1'
}

注意这里不支持"androidTestCompile"

不要忘记创建 AndroidManifest.xml。它看起来像:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.android.testing.espresso.BasicSample.tests">

<!-- Specify runner and target application package -->
<instrumentation
    android:name="android.support.test.runner.AndroidJUnitRunner"
    android:functionalTest="false"
    android:handleProfiling="false"
    android:label="Tests for com.example.android.testing.espresso.BasicSample"
    android:targetPackage="com.example.android.testing.espresso.BasicSample"/>

    <application>
        <uses-library android:name="android.test.runner" />
    </application>

</manifest>

注意测试源文件在“main”文件夹中(不是androidTest):

src->main->java->package.name.folders

然后你可以link这个测试项目到你在settings.gradle:

include ':module-androidTest'
project(':module-androidTest').projectDir = new File("../BasicSampleTests/test")

在 Android Studio 中,您必须创建“Android Instrumented Tests”运行 配置.它看起来像: 现在 运行 你的测试:

如果您的产品风味存在构建问题,那么您应该在应用程序的 build.gradle 中添加 publishNonDefault

android {
    ...
    defaultConfig {
       ...
    }
    publishNonDefault true
}