AndroidJUnitRunner 单元测试执行速度非常慢

Sea*_*eau 6 android android-testing android-studio android-gradle-plugin android-junit

我在我的项目中使用了 AndroidJUnitRunner,但是单元测试在 Android Studio 和命令行中通过gradlew.

我正在使用这个开源项目的主分支 OneBusAway(截至本次提交):https : //github.com/OneBusAway/onebusaway-android

我看到所有 142 个测试的执行时间在实际运行时间中超过 3 分钟,但 Android 在它显示在“测试结果”下的执行时间中只注册了其中的一小部分。在切换到 AndroidJUnitRunner 之前,所有这些单元测试都在 20 秒内一致地执行。

下面是一个示例测试:

/**
 * Tests to evaluate utility methods related to math conversions
 */
@RunWith(AndroidJUnit4.class)
public class MathUtilTest {

    @Test
    public void testOrientationToDirection() {
        // East
        double direction = MathUtils.toDirection(0);
        assertEquals(90.0, direction);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是build.gradle配置:

android {
    dexOptions {
        preDexLibraries true
    }
    compileSdkVersion this.ext.compileSdkVersion
    buildToolsVersion "27.0.3"

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 21
        versionCode 93
        versionName "2.3.8"

        multiDexEnabled true

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

        // The following argument makes the Android Test Orchestrator run its
        // "pm clear" command after each test invocation. This command ensures
        // that the app's state is completely cleared between tests.
        testInstrumentationRunnerArguments clearPackageData: 'true'
    }
    ...
    testOptions {
        execution 'ANDROID_TEST_ORCHESTRATOR'
        unitTests.includeAndroidResources true
    }
...
}
dependencies {
...
    // Unit tests
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestUtil 'com.android.support.test:orchestrator:1.0.2'
...
}
Run Code Online (Sandbox Code Playgroud)

为什么这个运行单元测试这么慢?

Sea*_*eau 5

显然,速度减慢与包含对Android Test Orchestrator 的依赖有关,我不需要它(即使我在需要 Android 上下文的设备上运行测试)。从现有文档中我不清楚这些测试是否不需要 Orchestrator。

我从 中删除了以下行build.gradle,并且通过 Android Studio 的总执行时间回落到约 15 秒的范围内:

// The following argument makes the Android Test Orchestrator run its
// "pm clear" command after each test invocation. This command ensures
// that the app's state is completely cleared between tests.
testInstrumentationRunnerArguments clearPackageData: 'true'
...
execution 'ANDROID_TEST_ORCHESTRATOR'
...
androidTestUtil 'com.android.support.test:orchestrator:1.0.2'
Run Code Online (Sandbox Code Playgroud)

因此,这是在大约 15 秒内执行测试的新功能build.gradle

android {
    dexOptions {
        preDexLibraries true
    }
    compileSdkVersion this.ext.compileSdkVersion
    buildToolsVersion "27.0.3"

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 21
        versionCode 93
        versionName "2.3.8"

        multiDexEnabled true

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    ...
    testOptions {
        unitTests.includeAndroidResources true
    }
    ...
}
...
dependencies {
    ...
    // Unit tests
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
}
Run Code Online (Sandbox Code Playgroud)

我认为这可能testInstrumentationRunnerArguments clearPackageData: 'true'是导致清除包数据的执行时间增加的罪魁祸首,但单独删除该行并不会改变测试的总执行时间 - 我必须完全删除 Orchestrator 依赖项。

以下是 Github 上删除 Orchestrator 的提交: https://github.com/OneBusAway/onebusaway-android/commit/a1657c443258ac49b1be83a75399cf2ced71080e

  • 我们对编排器的经验是,我们的测试套件需要它来清理应用程序。但不幸的是现在的速度比你经历的要慢得多。希望 Android 开发团队能够在未来的版本中对此进行改进。 (4认同)