I have some android instrumented tests under AndroidTests directory in Android Studio. Of course I can manually execute the tests but I need to execute all the tests in the suite after each build ("release" type of build, not during normal debug build). I need to do that because I'd like to validate the new code against the tests before releasing the new app's apk. How to do that? I google it but I didn't find a proper solution yet.
Any idea?
Finally I managed to do that. I have added the following configuration to my build.gradle file in my android studio project:
// execute android tests before realising a new apk
tasks.whenTaskAdded { task ->
if (task.name == 'assembleRelease')
task.dependsOn('connectedAndroidTest')
}
android {
signingConfigs {
release {
keyAlias 'key'
keyPassword 'password'
storeFile file('/path/to/release_keystore.jks')
storePassword 'password'
}
}
buildTypes {
debug {
signingConfig signingConfigs.release
}
release {
signingConfig signingConfigs.release
}
}
After doing that I'm able to run all android tests when building a release apk. If the tests are failing no apk is built.
In general you can define a dependencies for the task using the dependsOn method.
For example:
task A << {
println 'Hello from A'
}
task B << {
println 'Hello from B'
}
B.dependsOn A
You will obtain
> gradle -q B
Hello from A
Hello from B
In your case you can specify:
assemble.dependsOn test
If you would like to specify a dependency only for the release build:
assembleRelease.dependsOn test
Use:
connectedAndroidTest to run the tests on a connected emulator or device.
test to run the unit test on your local host.
I think you should dive in one certain topic: Continuous Integration.
This would allow you to run tests suites after every build or commit, build variants, publish on Google Play and much more... Start with classic Jenkins CI, which may not be the most polished and easy to use, I mean user-friendly tool, but in compare to Travis or Circle CI it provides huge configuration possibilities, nice app community and it's free to use.
Start with this article: http://www.vogella.com/tutorials/Jenkins/article.html
Other tools: I'm already using Travis for my Github projects, but Circle CI or Green House CI might be also good choice.
Hope it will help
Related
I have an app where I'd like to add an Android Wear app extension. The main app has three build types (debug, beta and release). Beta builds have an applicationIdSuffix which allows me to install the play-store version and the current development version in parallel on the same device. This all worked fine until I added the wear app.
The main app`s build.gradle looks like this:
apply plugin: 'com.android.application'
android {
...
defaultConfig {
...
applicationId "com.example.mainApp"
...
}
buildTypes {
debug {
applicationIdSuffix '.debug'
}
beta {
applicationIdSuffix '.beta'
}
release {
}
}
}
dependencies {
...
wearApp project(':wear')
}
The Wear-App has the same build types with the same applicationIdSuffix values. However, when I build the beta app (by calling gradle assembleBeta) the build process builds :wear:assembleRelease instead of :wear:assembleBeta which is why I get the following error message during build:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:handleBetaMicroApk'.
> The main and the micro apps do not have the same package name.
How can I tell the build process to build the correct build type when packaging the main app with build type beta?
Following the link posted by Scott Barta (http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication) I came up with this :
In the build.gradle of the wear app, add publishNonDefault true (to publish all variants):
android {
publishNonDefault true
}
In the build.gradle of the main app,
Replace
wearApp project(':wear')
By
debugWearApp project(path:':wear', configuration: 'debug')
releaseWearApp project(path:':wear', configuration: 'release')
You can't do what you want; the build variant of a module isn't propagated to the builds of dependent modules on build. This is tracked in https://code.google.com/p/android/issues/detail?id=52962
There's a facility to make one module depend on a specific variant of another one, as documented in http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication, but I don't think this mechanism can be extended to do differential packaging of Wear apps.
UPDATE
Now there is official support for build variants (see answer of Cyril Leroux). Hence this answer is deprecated.
I found a very (very) ugly solution which has some drawbacks but works for now until there is support for build variants for wear apps.
I set a global variable in the rootProject which contains the applicationIdSuffix of the currently built main app.
Within build.gradle of the main app I added the following:
// Set a global variable, depending on the currently built build-type.
// This allows us to set the applicationIdSuffix of the wear app depending on
// the build-type of the main app.
android.applicationVariants.all { variant ->
def task = variant.checkManifest
def suffix = variant.buildType.applicationIdSuffix
task.doLast {
rootProject.ext.currentApplicationIdSuffix = suffix
}
}
In the build.gradleof the wear app I added the following snipped:
android.applicationVariants.all { variant ->
def task = variant.generateBuildConfig
task.dependsOn(propagateApplicationIdSuffix)
}
task propagateApplicationIdSuffix << {
project.android.buildTypes.all { type ->
if (rootProject.hasProperty('currentApplicationIdSuffix')) {
type.applicationIdSuffix = rootProject.ext.currentApplicationIdSuffix
}
}
}
This has several drawbacks:
You can't build multiple variants (i.e. gradle assembleBeta assembleRelease) because the wear app is only built once and hence the second build type fails
gradle check fails because of reason 1
The wear app is still built with build type release but the package name is just changed according to to application id suffix of the main app
Don't worry, you CAN do what you want to do. I just did it for the enterprise app I work on.
The key is NOT to use wearApp project(':wear'), since that only works when you have the same applicationId in your wear app as your main app. And let's face it, how often in real life does that situation happen? If it happens, you probably aren't using Gradle to the best of it's ability.
You want to follow the instructions for Package Manually in the google wear docs
https://developer.android.com/training/wearables/apps/packaging.html#PackageManually
Unfortunately, this will require you to build your wear app with the same applicationId as the particular build variant you are making at the time, but it does allow you to successfully package the wear app inside an app with multiple applicationId.
Also, one trick I do that helps is to not put the wear apk inside /res/raw, but in /assets, that way you don't have to deal with Andriod Studio compressing the apk.
Hope this helps! Drove me crazy for a couple days finding a solution. And the only tutorial out there is in French, and I had to translate the website to read it!
https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=http%3A%2F%2Fblog.octo.com%2Fpackager-une-application-android-wear-dans-la-vraie-vie%2F
In Android is there a way to generate signed APKs for all modules in a project.
E.g. I have following project
Project
-- Library Module
-- Module 1
-- Module 2
-- Module 3
I want to generate APKs for all 3 modules in one command. Currently I have to separately use Generate Dialog for all 3 which takes a lot of time.
Yes you can generate multiple apk files with gradlew.
Open Terminal Window in Android Studio and run following commands:
1- Navigate to root folder of the project, where gradlew file is located
cd ..
2- Give executable permissions to gradlew (this needs to be done only once, no need to repeat again)
chmod a+x gradlew
3- Generate debuggable apks of all underlying modules.
./gradlew assembleDebug
You can also generate release apk files for all modules, by using this command instead
./gradlew assembleRelease
for more details, run the following command to see list of all tasks that can be run on gradlew
./gradlew tasks
Note: Running ./gradlew first time might result in terminal downloading the gradle files from server, wait for the downloading to complete before moving forward!
Hope that helps!
Update:
For providing signing information in grade file, Open your module specific build.grade file and update it to contain this code:
signingConfigs {
playstore {
keyAlias 'KEY_ALIS_NAME_HERE'
storeFile file('/PATH_TO_KEYSTORE_FILE_HERE/app.keystore')
keyPassword 'KEY_PASSWORD_HERE'
storePassword 'STORE_PASSWORD_HERE'
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles 'proguard-file.txt'
proguardFile 'proguard-file.txt'
debuggable false
signingConfig signingConfigs.playstore
}
}
After that you can simply run ./gradlew assembleRelease to do the work :)
I have a project with three different build types: debug, beta, and release. My test package is always created for debug builds, but QA uses the beta build and we want QA to run these tests on their vast array of devices.
I'm trying to create a testing apk for QA that is signed by the same key as the beta build. Looking through the Android-Gradle documentation, I don't see anything telling me that I can't do this, but I don't see anyway to configure this. Is there anyway I can configure which keystore is used when assembling a test apk? Or is there a way to create an unsigned test apk?
You can now point this to a different target, I don't know when this happened, but from the docs:
Currently only one Build Type is tested. By default it is the debug
Build Type, but this can be reconfigured with:
android {
...
testBuildType "staging"
}
This is an incomplete answer to your question in that it documents what you can't do, but the connectedAndroidTest task, which is what runs the androidTest tests in your project, is hardcoded to run against the debug build type, and I don't see a way to point it at a different build type.
Taking the advice from Is there a way to list task dependencies in Gradle? and examining the task dependency tree, if you run:
./gradlew tasks --all
you get this in your output:
Verification tasks
------------------
app:check - Runs all checks. [app:lint]
app:connectedAndroidTest - Installs and runs the tests for Build 'debug' on connected devices. [app:assembleDebug, app:assembleDebugTest]
app:connectedCheck - Runs all device checks on currently connected devices. [app:connectedAndroidTest]
app:deviceCheck - Runs all device checks using Device Providers and Test Servers.
The documentation for the connectedAndroidTest task claims it runs tests against debug, and the task dependencies (which you see with the -all flag) confirm that the task depends on assembleDebug.
Adding additional build types and flavors doesn't seem to affect the dependency on the built-in debug type.
It's possible that with greater Gradle-fu than mine, you could rewire the tasks to make the tests depend on a different build type, but doing this is likely to be fragile since it's bound to depend on things that aren't supported API in the Android Gradle plugin.
To answer your question most directly, though, if all you want is to run tests against a build with a different certificate, you could change the signing config on your debug build to use the beta certificate:
android {
signingConfigs {
beta {
keyAlias 'key'
keyPassword 'password'
storeFile file('/path/to/beta_keystore.jks')
storePassword 'password'
}
}
buildTypes {
debug {
signingConfig signingConfigs.beta
}
beta {
signingConfig signingConfigs.beta
}
}
}
I tested it and I am able to run androidTest targets against debug builds that use a custom keystore in this way. However, I doubt this solves your problem, because I suspect you want to run your tests against the beta build, not a debug build with the beta certificate.
To add a testing source set for your build variant, follow these steps:
In the Project window on the left, click the drop-down menu and
select the Project view.
Within the appropriate module folder,
right-click the src folder and click New > Directory.
For the directory name, enter "androidTestVariantName." For example,
if you have a build variant called "MyFlavor" then the directory name
shoulbe "androidTestMyFlavor." Then click OK.
Right-click on the new directory and click New > Directory. Enter
"java" as the directory name, and then click OK.
Now you can add tests to this new source set by following the steps above to add a new test. When you reach the Choose Destination Directory dialog, select the new variant test source set.
The instrumented tests in src/androidTest/ source set are shared by all build variants. When building a test APK for the "MyFlavor" variant of your app, Gradle combines both the src/androidTest/ and src/androidTestMyFlavor/ source sets.
Another way is to put following line your in default config.
Currently only one Build Type is tested. By default it is the debug Build Type, but this can be reconfigured with:
android {
...
testBuildType "staging"
}
Using Android Studio how do I get a signed, non-debug and zip aligned APK?
So far I can get a signed one but it gets rejected because it has debugging in it.
I can get a non debug release apk but it gets rejected because it's not zip aligned.
I can zip align it but then I can't upload it because that one is not signed.
Edit: I should mention that I'm on windows. Most everything I've looked at is linux based and difficult to separate linux paths from config paths.
Edit2: Things are on hold at the moment. I updated Android Studio and that killed everything because it comes with gradle 1.9 dependancies but doesn't install gradle 1.9 properly. So I thought I'd download the full installer with gradle 1.9 but the download link gives me the version I started with. I know. I should have known better than to update but given the issues I thought it might actually contain a fix.
Edit3: Problem solved. I have a full answer typed up ready to post but SO won't let me post it until tomorrow.
All builds are signed, even debug ones (which are signed with a debug key). It's just a matter of setting it up to sign your release builds with the correct key. You can set up a signing config via the Project Structure dialog, or you can edit the build.gradle file by hand, following the instructions in the Gradle Plugin User Guide
Once your build file is set up, you can either generate the release APK from the command line with the command
./gradlew assembleRelease
on Linux or Mac, or on Windows:
gradlew.bat assembleRelease
or in the GUI, you can generate the release build by choosing it from the Build Variants view:
building the APK, and signing it using the wizard.
I have solved the problem
Part 1 : k3v1n4ud3's link did help a lot to coalesce the information. Thank you for that.
Here is my entire build.gradle located under the project folder:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.6.+'
}
}
apply plugin: 'android'
repositories {
mavenCentral()
}
android {
compileSdkVersion 19
buildToolsVersion "19.0.0"
signingConfigs {
debug {
storeFile file("debug.keystore")
}
release {
storeFile file("D:\\AndroidStudioProjects\\KeyStore\\Keystore_password1.jks")
storePassword "password"
keyAlias "MyAppName"
keyPassword "password"
}
}
productFlavors {
free {
packageName "com.mypackage.myappname"
}
paid {
packageName "com.mypackage.myappname"
}
}
buildTypes {
debug {
signingConfig signingConfigs.release
}
release {
signingConfig signingConfigs.release
debuggable false
zipAlign true
}
/*
alpha {
packageNameSuffix ".alpha"
}
beta {
packageNameSuffix ".beta"
}*/
}
defaultConfig {
minSdkVersion 7
targetSdkVersion 19
}
}
android.applicationVariants.all { variant ->
if (variant.buildType.name == "release") {
switch (variant.name) {
case "FreeRelease":
variant.mergeResources.doFirst {
android.sourceSets.debug.setRoot("src/free")
}
break;
case "PaidDebug":
variant.mergeResources.doFirst {
android.sourceSets.debug.setRoot("src/paid")
}
break;
}
}
else if (variant.buildType.name == "debug") {
switch (variant.name) {
case "FreeDebug":
variant.mergeResources.doFirst {
android.sourceSets.debug.setRoot("src/debug/free")
}
break;
case "PaidDebug":
variant.mergeResources.doFirst {
android.sourceSets.debug.setRoot("src/debug/paid")
}
break;
}
}
}
dependencies {
compile 'com.android.support:appcompat-v7:+'
}
Part 2: I used the keystore created when I initially used the Build->Generate Signed APK... wizard. Pay attention to the keyalias used. After half a day of banging my head against the wall i had forgotten what I'd typed :-)
Part 3: This thread helped me set up the source folders and understand the flavors. Folder naming convention for gradle build variants
Part 4: With just one AndroidManifest.xml I couldn't use the suffixes on the package names. With suffixes it was rejected when uploading to the device. That becomes a problem when pretty much every example of build.gradle includes suffixes.
Part 5: Use View->Tool Windows->BuildVariants to bring up the build variants. The second column is actually a drop down. Select what you want to build here otherwise it's just going to keep building the debug version. (Why on earth it's not under the build menu or the run/debug configurations is a mystery???)
Part 6: The future... I have to try and work out the flavors and how to set them up as I would eventually like to deploy a free and a paid version off the same code base. I will start signing the debug versions with my own key as well.
It is possible to take any existing Android Studio gradle project and build/sign it from the command line without editing any files. This makes it very nice for storing your project in version control while keeping your keys and passwords separate and not in your build.gradle file:
./gradlew assembleRelease -Pandroid.injected.signing.store.file=$KEYFILE -Pandroid.injected.signing.store.password=$STORE_PASSWORD -Pandroid.injected.signing.key.alias=$KEY_ALIAS -Pandroid.injected.signing.key.password=$KEY_PASSWORD
If you are using different gradle build version rather than in which you developed your keystore file, at that time it may affect.
I also faced this problem in my project i do following changes:
set classpath
from classpath 'com.android.tools.build:gradle:2.2.0-alpha3'
to
classpath 'com.android.tools.build:gradle:2.1.2'
Recently change to Android Studio from Eclipse and I have also changed the JDK from java-open-jdk to jdk1.7.0_45.
Now I'm trying to run my first app and I get this message:
Installation failed since the APK was either not signed, or signed incorrectly.
If this is a Gradle-based project, then make sure the signing configuration
is specified in the Gradle build script
Edit:
When I'm running from Android Studio I get the error displayed above. When I'm running it from the command line I don't get an error (well the app is running and I get an error but nothing to do with gradle).
I got the code from here
You can check build.gradle here at google repo
UPDATE 2:
I added this code
signingConfigs {
release {
storeFile file("john.keystore")
storePassword "john"
keyAlias "johnkeystore"
keyPassword "john"
}
}
just above the buildTypes code block in the build.gradle file.
File john.keystore is on the root of my Project. I'm running gradlew assembleRelease and I'm getting a xxx-release-unsigned.apk.
If you indeed runing build with gradle you need to configure signingConfigs. Android can configure your debug signingConfig automatically. You can make release signingConfig in a next manner:
android {
signingConfigs {
release {
storeFile file('android.keystore')
storePassword "pwd"
keyAlias "alias"
keyPassword "pwd"
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
Check manual on this topic here: http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Signing-Configurations
If you still have issues, please update question with your build.gradle. Most likely issue is laying here. I'm using JDK 1.7 and gradle builds are working fine.
I had the same problem, i went to Build->Clean Project and re-execute the project and it worked.
I have been struggling for a while with Android Studio esp. gradle and build variants.
I have change this from the build types as defined:
debug
release
As I ran into the same problem (while developing and running tests), I went to Build -> Rebuild Project and then re-launched the emulator. That worked for me.
None of the answers worked for me, even after uninstalling app from phone, I could not deploy it. What worked was installing the app o a different device, and then when I tried to deploy it on the previous device, it miracleously worked.
If your goal is not to create a custom build for your application you might want to clean all the data about it from your test device, in case you are using emulator just wipe all the data from device. Go to -> Tools -> Android -> AVD Manager -> [Device you wanna wipe] (In actions tab) -> Wipe Data.
In case of actual device just uninstall the app and all related data.
Reason is that unsigned APK has a signature, so device sees you're trying to install something with the same package name that was generated not here.
Hope this saves you some time.
In case your device has multiple users, before installing signed APK, check if the same app is not installed for other users. If it is there remove it.
For me this was the root cause of rejecting installation of signed APK.
Just to Build -> Rebuild Project and then re-launched the emulator. That worked for me.