I'm looking to update Gradle from v4 to v5 but I'm getting the below warning on v4:
Gradle now uses separate output directories for each JVM language, but
this build assumes a single directory for all classes from a source
set. This behaviour has been deprecated and is scheduled to be removed
in Gradle 5.0.
So I believe I need to get rid of this warning before I can update to v5. Problem is I'm not really sure what it's asking me to do. How do I cahnge the build so that it doesn't assume a single directroy for all classes from a source set?
I tried adding the below to the build.gradle but I'm still getting the warning:
sourceSets {
main {
// Compiled Java classes should use this directory
java.outputDir = new File(buildDir, "classes/java/main")
}
}
You don't need to add anything to the build script.You just need to organize your project like this:
├── build.gradle
├── settings.gradle
└── src
└── main
├── java
│ └── HelloWorld.java
└── kotlin
└── Utils.kt
That deprecation message is shown when you use sourceSet.output.classesDir, which returns a File.
This has been replaced in Gradle 4.x, and removed in Gradle 5.x, by sourceSet.output.classesDirs (note the s at the end) which returns a FileCollection.
So you need to figure out where you use that in your buildscript and if not which plugin does. Note that the new method is already available in Gradle 4.x and so you should be able to upgrade your code or plugin version to make the deprecation message go away.
Good hunting!
I have 2 project modules: A, B and a library module. Both projects using a library. I also have some connected tests in both projects (UI Automator). That tests have common utility code that I'd like to move to the library. How can I do it?
What I've tried. First way:
Copy common code to library project to src/androidTest/java/xxx
folder
Add to library build.gradle UI automator dependencies under
androidTestCompile
Add to project build.gradle following:
dependecies {
...
androidTestCompile project(path: ':library', configuration: "debug")
...
}
That cause build issue in project because as I understand src/androidTest folder is not used during building debug configuration
Second way:
First 2 steps are same
Add to library build.gradle
task connectedTestsJars(type: Jar, dependsOn: "assembleXXXAndroidTest") {
classifier = 'connectedTests'
includes = ['com/**']
from "$buildDir/intermediates/classes/androidTest/XXX"
}
configurations {
connectedTestArtifact
}
artifacts {
connectedTestArtifact connectedTestsJars
}
Add to project build.gradle
dependencies {
...
androidTestCompile project(path: ':library', configuration: "connectedTestArtifact")
...
}
That way all compiles fine. It crashes during connected test runtime because of missing resources from library (it has a lot of common code and resources from both projects)
As I understand that happens because I am using only sources from the library, but I need to use aar file instead (aar with adding src/androidTest contents?).
What will be task type in that case? Or what actions I should make in my custom task to get aar file as result? Other way?
I understand that I can move connected tests common code to another (second) library module and use, but I'd like to avoid it to save compilation time.
Is there any way to keep current module structure and move connected tests common code to library module?
I did find a solution. Add to project's build.gradle:
android {
sourceSets {
androidTest {
java.srcDirs = ['../<LIBRARY_MODULE_NAME>/src/androidTest/java', 'src/androidTest/java']
}
}
...
}
I am sure there is a better solution since the common code will be compilated in both projects. Who knows it?
I have a multi-project build set-up with gradle that will contain multiple android apps and libraries.
Sample of the project structure:
root (Project Root)
| android
| module1 (Android Application)
| module2 (Android Library)
| ios (in the future)
I want to apply certain gradle plugins only to some subprojects. (Such as the android gradle plugin only to the android subproject)
Therefore I added the classpath dependency in the :android -> build.gradle and the plugin declaration to the two android subproject: :android:module1 -> build.gradle -> apply plugin: 'com.android.application'and:android:module2 -> build.gradle -> apply plugin: 'com.android.library'
The problem is that gradle cannot found the android gradle plugin:
Error:(1, 1) A problem occurred evaluating project ':Shoppr:presentation'.
Plugin with id 'com.android.application' not found.
Also it is not a version problem as in some other questions (Gradle Version 3.1; Android Gradle Plugin Version: 2.2.1) because when defining the classpath dependencies in :root -> build.gradle or :android:moduleX -> build.gradle all is working as expected.
:root -> build.gradle
allprojects {
repositories {
mavenCentral()
jcenter()
}
}
:android -> build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.1' <-- Should only be applied for android project
}
}
:android:module1 -> build.gradle
apply plugin: 'com.android.application' --> Plugin with id 'com.android.application' not found.
:android:module2 -> build.gradle
apply plugin: 'com.android.library'
I have seen such folder arrangements especially with google sample projects that include and android folder and also a web folder. What you can try is to import the project using the android folder as the project folder since you may not be using gradle to build Ios and web if you have the two more folders for you project.
So close the project and re-import it using the android folder as the project root, i believe this way, gradle should run fine. My project folder is also like this because i have both web and android project in a single repo but during build with android studio, i use the android folder as the project root for the android.
I had a somewhat similar problem. I went from having an android folder with 3 subtasks to dividing it into 3 folders with subtasks:
| android
| shared
-- generates aar
| device1
-- generates 2 apks
| device2
-- generates 1 apk
| gradle
gradlew.bat
gradlew
Both device1 and device2 want to use shared. So I removed settings.gradle and build.grade from the android folder. device1, device2, and shared have their own build.grade and settings.gradle. I build device1 and device2 separately. In order for them to include shared and build, I put symbolic links to shared, gradlew, gradlew.bat, and the gradle folder from the android folder into device1 and device2. And voila, it works! (I'm on an Ubuntu computer, but should be able to do the same on Windows and Mac.)
The disadvantage is that shared is built each time. In our case, that's not too bad, it's not very big.
android gradle [tag:multi-level projects]
I'm trying to get the Gradle Java plugin to execute jUnit tests that exist in an Android project. My solution was to create a second module that applies the Java plugin, and set the test sourceSet to the app module's src/test directory.
test-module's build.gradle:
apply plugin: 'java'
...
dependencies {
...
testCompile project(':app-module')
}
sourceSets {
test {
java.srcDirs += ["${appDir}/src/test/java"]
}
}
This works fine from the command line, but Android Studio refuses to import a project that has source sets outside the submodule. It throws the error: Can't register given path of type 'TEST' because it's out of content root.
.
├── app-module
│ ├── build.gradle
│ └── src
│ ├── main
│ └── test
├── test-module
│ └── build.gradle
├── build.gradle
└── settings.gradle
I tried configuring this from the parent build.gradle, but that didn't change anything. I can add app-module as a testCompile project dependency in test-module, but that doesn't cause test-module to add app-module's tests.
Any ideas for getting test-module to run app-module's tests without provoking Android Studio's limitation about remote source sets?
I am developing apps using Android Studio.
I was able to run the test code.
But, I do not know how to get code coverage in android studio.
I have already seen the following links.
Android Gradle Code Coverage
But I can't wait for update to v0.6 supporting emma.
Project configuration is as follows.
Main code
MyProject/AppName/src/main/java/mypackage/MyClass.java
Test code
MyProject/AppName/src/instrumentTest/java/mypackage/test/MyClassTest.java
Project configuration
MyProject
├─build.gradle
└─AppName
├─build.gradle
└─src
├─main
│ ├─java
│ │ └─mypackage
│ │ └─MyClass.java
│ ├─res
│ └─AndroidManifest.xml
└─instrumentTest
└─java
└─mypackage
└─test
└─MyClassTest.java
With the new Android Studio 1.2, you are able to run your unit tests and see the coverage all within the IDE.
First, you'll need to get your unit tests running in the IDE. (if you already can, then skip this step)
This guide and demo will help you.
Secondly, you'll need to create a JUnit Run configuration
Inside this configuraiton, you'll be able to choose
Test Kind: "All in Package"
Package: [the package where your tests reside, eg: "com.myapp.tests"]
Search for tests: Across Module Dependencies (could be diff for your
setup)
VM -options: -ea
Working Directory: [your project's directory]
Use classpath of mod: [select your module]
If you have any issue creating your JUnit Run Configuration, you should visit this guide for help.
Lastly, in the latest Android Studio, you should be able to run your JUnit-Run Configuration by clicking on the 'Run with Coverage' button.
In Android Studio 2.1.3 the is label Run Unit tests with Coverage where Unit test is the name of your test configuration as shown in the following screenshot:
There are so much answers showing how to apply jacoco plugin to Android studio project, which is outdated, and wasted me so much time to figure out the solution for recently Android studio(My Android Studio is version 2.1.2).
Jacoco plugin is built in for Android Studio gradle, what you need to do is just enable it like following:
buildTypes {
...
debug {
testCoverageEnabled true
}
}
After you do above, run unit test task
./gradlew testDebugUnitTest
Then create coverage files:
./gradlew createDebugCoverageReport
Coverage files will be created under <module>/build/reports/coverage/debug folder,include index.html, which you can open it with browser, and report.xml which you can use to get a report by jenkins jacoco plugin or other continues integration tools.
For those who got 0% coverage with jenkins jacoco plugin, be sure to use the right version.
quote from their site:
Unfortunately JaCoCo 0.7.5 breaks compatibility to previous binary
formats of the jacoco.exec files. The JaCoCo plugin up to version
1.0.19 is based on JaCoCo 0.7.4, thus you cannot use this version with projects which already use JaCoCo 0.7.5 or newer. JaCoCo plugin
starting with version 2.0.0 uses JaCoCo 0.7.5 and thus requires also
this version to be used in your projects. Please stick to JaCoCo
plugin 1.0.19 or lower if you still use JaCoCo 0.7.4 or lower
If you want to get your test coverage (for instrumented tests - When the 'Run the app with Coverage' is not enabled):
Put this into your top-level build.gradle:
buildscript{
ext.jacocoVersion = '0.8.2'
...
dependencies {
classpath "org.jacoco:org.jacoco.core:$jacocoVersion"
}
}
Into your app-level build.gradle:
...
apply plugin: 'jacoco'
jacoco {
toolVersion = "$jacocoVersion"
}
tasks.withType(Test) {
jacoco.includeNoLocationClasses = true
}
task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest', 'createDebugCoverageReport']) {
reports {
xml.enabled = true
html.enabled = true
}
def fileFilter = [
'**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*', '**/*$[0-9].*'
]
def debugTree = fileTree(dir: "$project.buildDir/tmp/kotlin-classes/debug", excludes: fileFilter)
def mainSrc = "$project.projectDir/src/main/kotlin"
sourceDirectories = files([mainSrc])
classDirectories = files([debugTree])
executionData = fileTree(dir: project.buildDir, includes: [
'jacoco/testDebugUnitTest.exec', 'outputs/code_coverage/debugAndroidTest/connected/**/*.ec'
])
}
android {
...
buildTypes {
debug {
testCoverageEnabled true
}
}
Then you should write your test, and tests have to passed. If you are sure, your tests passed, write that code into the terminal:
gradlew connectedCheck
It will run your tests.
If you did everything right, you should get a report file in
app -> build -> reports -> coverage.
You have to open the index.html file. (Right click on the file -> Open in Browser -> select a browser)
You should get something similar to this.
It's working in my project. Maybe there is a better and easier solution.
If I forgot something to write down here, pls write comment.
Enable testCoverage in your module build.gradle file
buildTypes {
debug {
testCoverageEnabled true
}
}
and then
Right click on the test -> java package and select Run Tests in Java with Coverage to run all tests with code coverage or right click on the particular test class and click Run SampleTest with Coverage
We use maven to build our app and cobertura for code coverage reporting
both are really easy to integrate
android maven integration:
http://www.vogella.com/tutorials/AndroidBuildMaven/article.html
Maven + Cobertura Code Coverage Example:
http://www.mkyong.com/qa/maven-cobertura-code-coverage-example/
I don't think you can see visual code coverage report inside Android Studio. But you could try Jacoco. You will need to integrate it in your build.gradle file. You can find the similar question & solution here
Have you tried using the Jacoco plugin for getting code coverage for your project? It is a good plugin giving you coverage based on your package or individual classes. I am not sure how you configure Jacoco to use with Gradle since i use Maven. Check the link: and see if it helps you
Android studio gradle has inbuilt Jacoco plugin which you can use to find code coverage. I have written as article to step by step configure jaococo to find code coverage for Espresso test case but you can use it for Robotium as well. check this out.
http://qaautomated.blogspot.in/2016/03/how-to-find-code-coverage-with-jacoco.html
You can just right click on the package you are curious about and select Run 'Tests in "package" with coverage'