I run ./gradlew connectedAndroidTest
and I need my test APK to have a permission which should not be in any non-testing APK (debug, release). I have created a manifest with permission:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mypackage">
<uses-permission android:name="android.permission.SET_ANIMATION_SCALE"/>
</manifest>
Then I have copied this manifest to src/androidTest
directory, as release notes from gradle android plugin suggest:
0.13.0 (2014/09/18) Requires Gradle 2.1 It is now possible to provide a manifest for test apps (src/androidTest/AndroidManifest.xml)
However, the permission is not applied during my connected tests.
If I create a src/debug
directory and move this manifest there -- the permission is applied correctly during connected tests (but also during regular debug builds, which is undesirable).
Am I doing something wrong or is there a bug?
The problem stems from my misunderstanding of how connectedAndroidTest
gradle task works. It creates and deploys 2 android applications - a testable (your project) and a tester (an app which simulates a user who interacts with the testable app). My intent was to add the permission to the testable app. However, adding a manifest to src/androidTest
resulted in adding the permission to the tester app. Here's how I figured that out:
If I execute
adb shell pm list packages -f -3
(-3
means to list only third-party packages) I can see something like this
package:/data/app/SmokeTestApp.apk=com.android.smoketest package:/data/app/GestureBuilder.apk=com.android.gesture.builder package:/data/app/com.mycompany.myapp-2.apk=com.mycompany.myapp package:/data/app/SoftKeyboard.apk=com.example.android.softkeyboard package:/data/app/org.libsdl.app-2.apk=org.libsdl.app package:/data/app/SmokeTest.apk=com.android.smoketest.tests package:/data/app/com.mycompany.myapp.test-1.apk=com.mycompany.myapp.test
The app with test-1 suffix is the tester app, another one is my testable app. Checking their permission gives:
root@generic_x86:/ # aapt d permissions /data/app/com.mycompany.myapp-2.apk
package: com.spredfast.android
uses-permission: android.permission.INTERNET
uses-permission: android.permission.WRITE_EXTERNAL_STORAGE
root@generic_x86:/ # aapt d permissions /data/app/com.mycompany.myapp.test-1.apk
package: com.spredfast.android
uses-permission: android.permission.SET_ANIMATION_SCALE
So the permission, SET_ANIMATION_SCALE
, which I was intending to put into my testable app is put into the tester app. No wonder that moving the manifest from src/androidTest
to src/debug
would put the permission into the testable app (correct, but too broad).
Here's how I solved the original problem - putting the permission into the application only in case of the application being run inside connectedAndroidTest
task.
I have created an empty build flavor to be used with integration tests:
productFlavors {
/**
* This flavor is to be run only using connectedAndroidTestAnimcontrol
*/
animcontrol {}
regular {}
}
Moved src/androidTest/AndroidManifest.xml
with the single permission into src/animcontrol/AndroidManifest.xml
Executed connected tests as
./gradlew connectedAnimcontrolDebugAndroidTest
That did the trick, now I have AndroidManifest.xml
which will be merged with main app's manifest only when being run as connectedAndroidTest.
Hope this helps someone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With