You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Robotium测试无源码APK时启动失败,遇InitializerError

解决Robotium黑盒测试中的InitializerError问题

我看到你在用Android Studio 3.1.2 + Robotium对无源码的APK做黑盒测试时遇到了InitializerError,先帮你梳理下当前的代码配置和错误,再给出针对性的修复方案。

一、当前测试代码与配置

1. Robotium测试类代码

import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import com.robotium.solo.Solo;

@SuppressWarnings("rawtypes")
public class RobotiumTest extends ActivityInstrumentationTestCase2 {
    private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.example.hqsg.activities.HQSoundGuideActivity";
    private static Class launcherActivityClass;

    static {
        try {
            launcherActivityClass = Class.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public RobotiumTest() throws ClassNotFoundException {
        super(launcherActivityClass);
    }

    private Solo mDevice;

    @Override
    public void setUp() throws Exception {
        mDevice = new Solo(getInstrumentation(), getActivity());
        super.setUp();
    }

    @Override
    public void tearDown() throws Exception {
        mDevice.finishOpenedActivities();
        super.tearDown();
    }

    public void test() {
        mDevice.clickOnButton(0);
    }
}

2. Manifest配置

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.robotium">

    <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <uses-library android:name="android.test.runner" />
    </application>
</manifest>

3. Gradle配置

apply plugin: 'com.android.application'

android {
    signingConfigs {
        config {
            keyAlias 'androiddebugkey'
            keyPassword 'android'
            storeFile file('C:/Users/suman_A/Desktop/key.jks')
            storePassword 'android'
        }
    }
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.example.robotium"
        minSdkVersion 15
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testApplicationId 'com.example.hqsg'
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        signingConfig signingConfigs.config
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            signingConfig signingConfigs.config
        }
    }
    testOptions {
        unitTests.returnDefaultValues = true
    }
    buildToolsVersion '27.0.3'
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.0'
    debugImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support:support-annotations:27.1.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:rules:1.0.2'
    implementation 'com.jayway.android.robotium:robotium:5.6.1'
    androidTestImplementation 'com.jayway.android.robotium:robotium-solo:5.6.1'
    implementation 'com.squareup.okhttp3:okhttp:3.10.0'
    implementation 'com.android.support:multidex:1.0.3'
}

二、遇到的错误信息

java.lang.ExceptionInInitializerError
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at junit.framework.TestSuite.createTest(TestSuite.java:61)
at junit.framework.TestSuite.addTestMethod(TestSuite.java:294)
at junit.framework.TestSuite.addTestsFromTestCase(TestSuite.java:150)
at junit.framework.TestSuite.<init>(TestSuite.java:129)
at android.support.test.internal.runner.junit3.NonLeakyTestSuite.<init>(NonLeakyTestSuite.java:33)
at android.support.test.internal.runner.junit3.AndroidTestSuite.<init>(AndroidTestSuite.java:46)
at android.support.test.internal.runner.junit3.AndroidJUnit3Builder.runnerForClass(AndroidJUnit3Builder.java:87)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at android.support.test.internal.runner.AndroidRunnerBuilder.runnerForClass(AndroidRunnerBuilder.java:153)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at android.support.test.internal.runner.TestLoader.doCreateRunner(TestLoader.java:73)
at android.support.test.internal.runner.TestLoader.getRunnersFor(TestLoader.java:104)
at android.support.test.internal.runner.TestRequestBuilder.build(TestRequestBuilder.java:789)
at android.support.test.runner.AndroidJUnitRunner.buildRequest(Andro

三、问题分析与修复方案

ExceptionInInitializerError一般是静态代码块执行失败导致的,看你的测试类静态块里是在加载目标APK的启动Activity类,这里大概率是目标APK的类没有被正确加载,或者测试应用的配置有问题,针对你的场景,给你几个修复步骤:

1. 修正测试类的继承与构造方法

ActivityInstrumentationTestCase2是JUnit3的类,而你用的AndroidJUnitRunner是JUnit4的 runner,两者混用容易出问题。建议调整测试类结构:

public class RobotiumTest extends ActivityInstrumentationTestCase2 {
    private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.example.hqsg.activities.HQSoundGuideActivity";
    private static Class<?> launcherActivityClass;

    static {
        try {
            launcherActivityClass = Class.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("Could not load target activity class", e);
        }
    }

    public RobotiumTest() {
        super(launcherActivityClass);
    }
    // ... 其他代码不变
}

这里去掉构造方法的throws ClassNotFoundException,因为静态块已经处理了异常,避免重复抛出。

2. 修正Gradle中的测试配置

  • 你当前把robotium依赖放在了implementation,应该只放在androidTestImplementation,因为测试库不需要打包到主应用里:
// 移除这行
// implementation 'com.jayway.android.robotium:robotium:5.6.1'
androidTestImplementation 'com.jayway.android.robotium:robotium-solo:5.6.1'
  • testApplicationId需要设置为测试应用的包名后缀,而不是目标APK的包名,否则会导致类加载冲突:
defaultConfig {
    // ... 其他配置
    testApplicationId "com.example.robotium.test"
}

3. 确保目标APK已正确安装且签名一致

黑盒测试时,测试应用和目标APK必须使用相同的签名,否则无法获取目标应用的权限。如果目标APK是debug签名,建议你把测试应用的debug签名改成默认的debug签名,避免签名不匹配。

4. 调整Manifest配置

添加instrumentation节点指定目标包名,这是黑盒测试的必要配置:

<manifest ...>
    <!-- 已有的权限和application节点 -->
    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.example.hqsg" />
</manifest>

这个节点告诉测试runner要测试的目标应用包名,没有的话会找不到目标Activity。

5. 修正setUp方法的执行顺序

setUp方法里应该先调用super.setUp(),再初始化Solo,因为getActivity()需要在父类初始化之后才能获取到:

@Override
public void setUp() throws Exception {
    super.setUp();
    mDevice = new Solo(getInstrumentation(), getActivity());
}

四、验证步骤

  1. 确保目标APK已经安装在测试设备/模拟器上;
  2. 重新同步Gradle,清理并重建测试项目;
  3. 运行测试类,看是否能正常启动目标应用并执行测试。

内容的提问来源于stack exchange,提问作者Suman Ankali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:48:59