在 AndroidManifest 元数据中指定自定义 RunListener 不起作用

Aut*_*pps 2 junit android metadata android-manifest android-instrumentation

目标

RunListener使用 Espresso 运行 Android 仪器测试时,在测试失败时自定义执行自定义操作。

tl;博士

InstrumentationInfo.metaDatanull,即使ApplicationInfo.metaData有我的信息。为什么?

迄今为止的进展

我可以让我的 RunListener 使用以下 adb 命令:

adb shell am instrument -w -e listener com.myproject.test.runlisteners.CustomRunListener -e class com.myproject.test.ui.HomeActivityTest#testWillFail com.myproject.test/android.support.test.runner.AndroidJUnitRunner
Run Code Online (Sandbox Code Playgroud)

这是在此处的 AndroidJUnitRunner 文档中指定的。

但是,该文档还指出可以在AndroidManifest.xml元数据元素中指定 RunListener 。到目前为止,我一直没有成功地让它发挥作用。

AndroidManifest.xml

我在我的<application>元素中添加了以下内容main/AndroidManifest.xml

<meta-data
        android:name="listener"
        android:value="com.myproject.test.runlisteners.CustomRunListener" />
Run Code Online (Sandbox Code Playgroud)

这没有任何影响。通过各种方式,我发现这些代码行(由清单使用AndroidJUnitRunnerRunnerArgs从清单中获取自定义元数据参数)

InstrumentationInfo instrInfo = pm.getInstrumentationInfo(
    getComponentName(), PackageManager.GET_META_DATA);
Bundle b = instrInfo.metaData;
Run Code Online (Sandbox Code Playgroud)

...还我一个null捆绑包。

我注意到生成的debug/AndroidManifest.xml没有我的元数据标签,因此,作为实验,我也将它添加到我的androidTest/AndroidManifest.xml文件中。看起来像这样:

<application
    android:name=".BaseApplication">

    <meta-data
        android:name="listener"
        android:value="com.sirius.test.runlisteners.CustomRunListener" />

</application>
Run Code Online (Sandbox Code Playgroud)

...然后出现在生成的debug/AndroidManifest.xml像这样:

<application android:name="com.myproject.BaseApplication" >
    <meta-data
        android:name="listener"
        android:value="com.sirius.test.runlisteners.CustomRunListener" />

    <uses-library android:name="android.test.runner" />
</application>
Run Code Online (Sandbox Code Playgroud)

这也没有任何影响。

另一个实验

我创建了一个名为的自定义测试运行器CustomAndroidJUnitRunner,它扩展了 AndroidJUnitRunner 只是为了在幕后达到峰值。如果我这样做:

ApplicationInfo ai = packageManager.getApplicationInfo(
    getComponentName().getPackageName(), PackageManager.GET_META_DATA);
Bundle b = ai.metaData;
Object o = b.get("listener");
Log.d(TAG, "listener=" + o.toString());
Run Code Online (Sandbox Code Playgroud)

...logcat 会说:

D/CustomAndroidJUnitRunner: listener=com.myproject.test.runlisteners.CustomRunListener
Run Code Online (Sandbox Code Playgroud)

所以,ApplicationInfo.metaData有了。为什么没有InstrumentationInfo.metaData

Aut*_*pps 5

有时,直到您花时间彻底解释所有内容后,您才能最终了解问题所在。解决方案是将其添加到<manifest>元素中:

<instrumentation
    android:name="com.myproject.test.runner.CustomAndroidJUnitRunner"
    android:functionalTest="false"
    android:handleProfiling="false"
    android:label="Tests for com.myproject"
    android:targetPackage="com.myproject">

    <meta-data
        android:name="listener"
        android:value="com.myproject.test.runlisteners.CustomRunListener" />

</instrumentation>
Run Code Online (Sandbox Code Playgroud)

我只是<instrumentation>从生成的debug/AndroidManifest.xml文件中复制粘贴了元素。

我有点揭去,原来,因为两者CustomAndroidJUnitRunnercom.myproject分别以红色Android Studio中突出显示。但一切都编译得很好。

我希望这对其他人有帮助!