30

InstrumentationTestCase2純粋なテスト目的で、派生テスト ケースから外部 SD カードにファイルを書き込もうとしています。これは、テスト対象のアプリケーションandroid.permission.WRITE_EXTERNAL_STORAGEのファイルで構成されている場合は問題なく機能しますが、この設定がテスト プロジェクトAndroidManifest.xmlのファイルにのみ存在する場合は機能しません。AndroidManifest.xml

当然のことながら、この権限をメインのマニフェストに追加したくありません。機能テスト中にのみこの機能が必要になるからです。どうすればそれを達成できますか?

4

3 に答える 3

38

android:sharedUserIdつまり、アプリケーションのマニフェストとテスト プロジェクトのマニフェストの両方に同じものを追加し、テスト プロジェクトに必要な権限を宣言する必要があります。

この回避策は、Android が実際に許可を Linux ユーザー アカウント (uid) に割り当てるが、アプリケーション自体には割り当てないという事実に由来します (デフォルトでは、すべてのアプリケーションが独自の uid を取得するため、許可はアプリケーションごとに設定されているように見えます)。

ただし、同じ証明書で署名されたアプリケーションは、同じ uid を共有できます。結果として、それらは共通の権限セットを持ちます。たとえば、WRITE_EXTERNAL_STORAGE パーミッションを要求するアプリケーション A と、INTERNET パーミッションを要求するアプリケーション B を持つことができます。A と B の両方が同じ証明書によって署名されています (デバッグ 1 としましょう)。AndroidManifest.xml では、A と B のファイルがタグandroid:sharedUserId="test.shared.id"で宣言されています。<manifest>アクセス許可は uid ごとに割り当てられるため、必要なアクセス許可の一部しか宣言していなくても、A と B の両方がネットワークにアクセスして SD カードに書き込むことができます。もちろん、これは 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にあります。

于 2013-01-07T13:00:07.687 に答える
13

別の簡単な答えがあります。

で権限を設定しsrc/debug/AndroidManifest.xmlます。ファイルが存在しない場合は、作成します。

デフォルトでは、AndroidTest はdebugBuildType として使用するため、そこでテスト権限を定義すると、マニフェスト マージ プロセスによってこれらの権限が UI テスト ビルドに追加されます。

これは、新しい権限を持つマニフェストです。package優先度の低いマニフェストから継承されるため、属性を含めていないことに注意してください。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest>

また、これらのアクセス許可を 以外の buildType に適用する場合はdebug、新しいAndroidManifest.xmlものを必要なフォルダーに移動して、これを使用します。

android {
   ...
   testBuildType 'release' // or other buildType you might have like 'testUI'
}
于 2017-04-11T13:07:45.843 に答える
-5

生成されたデバッグ クラスのデバッグ モードは、これらの条件下でデバッグされるため、プログラムで実行します。

于 2013-01-07T11:41:37.997 に答える