如何仅为我的UI测试项目添加其他Android权限?

时间:2013-01-03 16:21:55

标签: android testing

我尝试在InstrumentationTestCase2派生的测试用例中将文件写入外部SD卡,以进行纯测试。在被测应用程序的android.permission.WRITE_EXTERNAL_STORAGE文件中配置AndroidManifest.xml时,这种方法很有效,但如果此设置仅出现在测试项目的AndroidManifest.xml文件中,则无效。 / p>

当然,我不想将此权限添加到主清单中,因为我在功能测试期间只需要此功能。我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:35)

简而言之,您应该为应用程序的清单和测试项目的清单添加相同的android:sharedUserId,并为测试项目声明必要的权限。

这种解决方法来自Android实际上为Linux用户帐户(uids)分配权限但不向应用程序本身分配权限(默认情况下,每个应用程序都有自己的uid,因此看起来每个应用程序都设置了权限。)

使用相同证书签名的应用程序可以共享相同的uid。因此,他们拥有一组共同的权限。例如,我可以拥有请求WRITE_EXTERNAL_STORAGE权限的应用程序A和请求INTERNET权限的应用程序B. A和B都由相同的证书签名(假设调试一个)。在AndroidManifest.xml中,A {和B android:sharedUserId="test.shared.id"的文件在<manifest>标记中声明。然后A和B都可以访问网络并写入SD卡,即使它们只声明了所需权限的一部分,因为每个uid分配了权限。当然,只有在实际安装了A和B的情况下,这才有效。

以下是如何在测试项目中进行设置的示例。应用程序的AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testproject"
    android:versionCode="1"
    android:versionName="1.0"
    android:sharedUserId="com.example.testproject.uid">

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name">
        <activity
            android:name="com.example.testproject.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />    
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

用于测试项目的AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testproject.test"
    android:sharedUserId="com.example.testproject.uid"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.example.testproject" />

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

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="android.test.runner" />
    </application>

</manifest>

此解决方案的缺点是,在安装测试包时,应用程序也能够写入外部存储。如果它意外地将某些内容写入存储器,则在发布时,如果使用不同的密钥对包进行签名,则可能会一直未被注意。

有关共享UID的一些其他信息,请访问http://developer.android.com/guide/topics/security/permissions.html#userid

答案 1 :(得分:11)

还有另一个简单的答案。

设置src / debug / AndroidManifest.xml的权限(如果不存在,则创建它)

默认情况下,AndroidTest使用debug作为BuildType。这就是为什么你在debug buildType下定义这些权限的原因。感谢合并过程,它将这些权限添加到您的UI测试版本中。 这是具有新权限的清单(请注意,我没有包含属性,因为它将从较低优先级清单继承)

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

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

现在,如果您要将这些权限应用于特定的buildType而不是debug

只需使用:

android {
   ...
   testBuildType 'release' // or other buildType you might have like 'testUI'
}

答案 2 :(得分:-5)

以编程方式执行,因为生成的Debug类的Debug模式将在这些条件下进行调试。