Gradle - equivalent of test {} configuration block for android - android

Gradle has the test configuration block
https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html
```
apply plugin: 'java' // adds 'test' task
test {
// enable TestNG support (default is JUnit)
useTestNG()
// set a system property for the test JVM(s)
systemProperty 'some.prop', 'value'
// explicitly include or exclude tests
include 'org/foo/**'
exclude 'org/boo/**'
// show standard out and standard error of the test JVM(s) on the console
testLogging.showStandardStreams = true
// set heap size for the test JVM(s)
minHeapSize = "128m"
maxHeapSize = "512m"
// set JVM arguments for the test JVM(s)
jvmArgs '-XX:MaxPermSize=256m'
// listen to events in the test execution lifecycle
beforeTest { descriptor ->
logger.lifecycle("Running test: " + descriptor)
}
// listen to standard out and standard error of the test JVM(s)
onOutput { descriptor, event ->
logger.lifecycle("Test: " + descriptor + " produced standard out/err: " + event.message )
}
}
where one can set all sorts of test configuration (I am mostly interested in the heap size). Is there something similar for android projects?

There is a possibility to add them. Android Gradle plugin has parameter testOptions, which has parameter unitTests, which has option all.
So if you write:
android {
testOptions {
unitTests.all {
// apply test parameters
}
}
}
the tests will be executed with specified parameters.

Related

how to check the external dependency size in android studio

How can I check the exact size of the dependency that I installed in android studio, is there any website to check the size..?
I want to know the size of implementation 'com.google.android.exoplayer:exoplayer:2.X.X'
You could make a task to sum the size of all the files in a configuration. Then add the dependency or dependencies that you want to check to that configuration. (In addition to the implementation configuration or whatever other configuration it is that they are needed for.)
configurations {
justForSize
}
dependencies {
implementation 'com.google.android.exoplayer:exoplayer:2.X.X'
justForSize 'com.google.android.exoplayer:exoplayer:2.X.X'
}
tasks.register('dependencySize') {
doLast {
def depLength = 0L
configurations.justForSize.forEach {
println "${it} is ${it.length()} bytes"
depLength += it.length()
}
println "Total size of justForSize configuration is ${depLength}"
}
}
Then just run that task:
gradle dependencySize

Gradle Android: How to Display test results without using --info

I am running android tests using the Gradle Android plugin and want to see individual test results.
From answers to this Question Gradle: How to Display Test Results in the Console in Real Time? it seems I can either use --info (which prints a LOT of other verbose junk I don't care about) or use this closure which only works for the Java plugin (not the Android plugin)
test {
afterTest { desc, result ->
println "Executing test ${desc.name} [${desc.className}] with result: ${result.resultType}"
}
}
Is there some other option / closure I can use when I am running the connectedCheck task just to print the individual test results without all the other "verbosity".
Use Gradle info
This will print all information from Gradle:
gradle --info
or Use Android Gradle plugin:
android.testOptions.unitTests.all {
// Configure whether failing tests should fail the build
ignoreFailures false
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
}
}
or Use Gradle directly:
allprojects {
tasks.withType(Test) {
testLogging {
exceptionFormat "full"
showCauses true
showExceptions true
showStackTraces true
showStandardStreams true
events = ["passed", "skipped", "failed", "standardOut", "standardError"]
}
}
}
See: https://github.com/jaredsburrows/android-gradle-java-app-template/blob/master/gradle/compile.gradle#L20
Output:
io.github.hidroh.materialistic.data.SessionManagerTest > testView PASSED
io.github.hidroh.materialistic.data.SessionManagerTest > testIsViewFalse PASSED
io.github.hidroh.materialistic.data.SessionManagerTest > testIsViewNull PASSED
io.github.hidroh.materialistic.data.SessionManagerTest > testIsViewTrue PASSED
io.github.hidroh.materialistic.data.SessionManagerTest > testViewNoId PASSED
Source: https://github.com/hidroh/materialistic/blob/master/robolectric.gradle
Gradle Docs: https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/testing/logging/TestLogEvent.html
For me all the options mentioned in the other answer still printed a lot of verbose information. So despite the requirement that info should not be used, I successfully use the following. For example, if your tests are in the package com.example.android, you can use:
gradle --info connectedDebugAndroidTest | grep "com\.example\.android\..* >"
Will print e. g.:
com.example.android.login.LoginActivityTest > enterCredentialsTest[Testing_emulator(AVD) - 9] SUCCESS
And the word "SUCCESS" will be green, which is awesome.
For Android Studio (tested on com.android.tools.build:gradle:2.1.0 and gradle version gradle-2.10) I added the following section to print exceptions in full format as well as logging every executed test:
apply plugin: 'com.android.application'
android { ... }
dependencies { ...}
tasks.withType(Test) {
testLogging {
exceptionFormat "full"
}
afterTest { desc, result ->
println "Executing test ${desc.name} [${desc.className}] with result: ${result.resultType}"
}
}

Android Coverage launch with JaCoCo

We have an Android application that we are building with Gradle/Android Studio and are using JaCoCo to generate code coverage reports for our unit tests; this is working great. We are also interested in being able to generate coverage reports for manual tests as well; that is, show what code was covered in an arbitrary application launch. It appears that JaCoCo's predecessor EclEmma was capable of this, but I have not been able to find any confirmation one way or the other about JaCoCo (though I am beginning to assume it impossible from the lack of discourse).
I have tried using EclEmma from Eclipse just to have something, but the latest version fails with this error, and I couldn't immediately get older versions to work either.
Can anyone confirm whether or not it is possible to generate coverage data on an arbitrary application launch with JaCoCo? As in, run the app, press buttons, close the app and get a report on what code was exercised by the buttons you pushed. If not, is there another tool that can accomplish this?
Thanks!
apply plugin: 'jacoco'
def coverageSourceDirs = [
'../app/src/main/java'
]
jacoco{
toolVersion = "0.7.4.201502262128"
}
task jacocoTestReport(type: JacocoReport) {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
reports {
xml.enabled = true
html.enabled = true
}
classDirectories = fileTree("enter code here"
dir: './build/intermediates/classes/debug',
excludes: ['**/R*.class',
'**/*$InjectAdapter.class',
'**/*$ModuleAdapter.class',
'**/*$ViewInjector*.class'
])
sourceDirectories = files(coverageSourceDirs)
executionData = files("$buildDir/outputs/code-coverage/connected/coverage.exec")
doFirst {
new File("$buildDir/intermediates/classes/").eachFileRecurse { file ->
if (file.name.contains('$$')) {
file.renameTo(file.path.replace('$$', '$'))
}
}
}
}
// this is for the report
debug {
testCoverageEnabled true
}
// this is for offline
add these to the build.gradle file.
add directory "resources" to the app>src>main
add jacoco-agent.properties file to resources.
write destfile=/sdcard/coverage.exec to file jacoco-agent.properties
now add this class to your project .
public class jacoco {
static void generateCoverageReport() {
String TAG = "jacoco";
// use reflection to call emma dump coverage method, to avoid
// always statically compiling against emma jar
String coverageFilePath = "/sdcard/coverage.exec";
java.io.File coverageFile = new java.io.File(coverageFilePath);
try {
Class<?> emmaRTClass = Class.forName("com.vladium.emma.rt.RT");
Method dumpCoverageMethod = emmaRTClass.getMethod("dumpCoverageData",
coverageFile.getClass(), boolean.class, boolean.class);
dumpCoverageMethod.invoke(null, coverageFile, false, false);
Log.e(TAG, "generateCoverageReport: ok");
} catch (Exception e) {
new Throwable("Is emma jar on classpath?", e);
}
}
}
when your app is onDestroy call the function
jacoco.generateCoverageReport();
you can run your app . when test over you can use command
"adb pull /sdcard/coverage.exec yourapp/build/outputs/code-coverage/connected/coverage.exec".
the last operation run gradle task define above there "jacocoTestReport".
ok. all done. open the index.html in "yourapp/build/reports/jacoco/jacocoTestReport/html/".

How I can display Log files,System.out.println(), In Android test?

I did search a lot but unfortunately couldn't get it to work.
Based on my search I found that I need to add following code into build.gradle file. However, Gradle seems doesn't recognize it and always says Geadle DSL method not found: test()
test {
testLogging.showStandardStreams = true
testLogging.events("passed", "skipped", "failed", "standardOut", "standardError")
afterTest { desc, result ->
println "Executing test ${desc.name} [${desc.className}] with result: ${result.resultType}"
}
}
Update
I can confirm above code or better than that following code is working fine if you create a test project and move all your test cases inside that instead of src/test/java and src/androidTest/java in main project. It's because you can apply java plugin in build.gradle file. However, It's not possible to use following code in any build.gradle file that com.android.* has been defined. Since these two libraries are not compatible :(
apply plugin: 'java'
evaluationDependsOn(':YOUR-LIB')
test {
testLogging.showStandardStreams = true
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
exceptionFormat = 'full'
}
afterTest { desc, result ->
println "Executing test ${desc.name} [${desc.className}] with result: ${result.resultType}"
}
forkEvery = 5
maxParallelForks = java.lang.Runtime.runtime.availableProcessors() / 2
}
tasks.withType(Test) {
// Need Gradle to ignore classes that are inner class of Test classes but not actually Tests
scanForTestClasses = false
include "**/*Test.class"
}
So, my question is does anyone's INVENTED any way to print out logs under android plugin?

Using Gradle and AspectJ with Android product flavors that have their own source

I have searched a lot, but haven't seen an answer for this. I have source that's in different flavors. Something like:
App/src/flavorA/MyFlavor.java
App/src/flavorB/MyFlavor.java
App/src/flavorC/MyFlavor.java
And it works great, until I need to run my AOP step. I found it couldn't complete because it was unable to find this class, which is referenced from source in App/src/main/.
This doesn't find the MyFlavor class:
android.applicationVariants.all { variant ->
variant.javaCompile.doLast {
def androidSdk = android.adbExe.parent + "/../platforms/" + project.ext.android_version + "/android.jar"
def iajcClasspath = configurations.compile.asPath + ";" + androidSdk
// This add's project jars as well as support jars.
project.ext.tree = fileTree(dir: "${project.buildDir}/intermediates/exploded-aar", include: '**/*.jar')
project.ext.tree.each { jarFile ->
iajcClasspath += ":" + jarFile
}
ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties",
classpath: configurations.ajc.asPath)
ant.iajc(
source: "1.6",
target: "1.6",
destDir: "${project.buildDir}/intermediates/classes/${variant.dirName}",
fork: "true",
maxmem: "512m",
aspectPath: configurations.aspects.asPath,
inpath: configurations.ajInpath.asPath,
sourceRootCopyFilter: "**/.svn/*,**/*.java",
classpath: iajcClasspath
) {
sourceroots {
android.sourceSets.main.java.srcDirs.each {
pathelement(location: it.absolutePath)
}
pathelement(location: "${project.buildDir}/generated/source/r/${variant.dirName}")
pathelement(location: "${project.buildDir}/generated/source/buildConfig/${variant.dirName}")
}
}
}
}
I can get it working if I add in something like:
pathelement(location: "$`enter code here`{project.buildDir}/../src/flavorA/java")
But that's if I only want to build flavorA. Is there a better way of setting things up so that when the IAJC task runs, it can find the source that it needs for the particular variant that it's building? If I assembleFlavorARelease, my variant name is going to be something like flavorARelease and I can get the build type of "release" by doing variant.buildType.name but that's not going to help me. I need to point it to the source for the flavor I'm building.
I took the variant.name and subtracted the build type name off of it to be left with the "flavorA" part:
pathelement(location: "${project.buildDir}/../src/${variant.name.substring(0, variant.name.length() - variant.buildType.name.length())}/java")
Still seems wonky. What if I want to assembleRelease and build all flavors? There's got to be a better way of approaching this which I'm not seeing.
You can iterate over the available flavors for your particular variant using:
def currentFlavor;
variant.productFlavors.each { flavor ->
flavorToChoose = flavor
}
From here you can grab onto the flavor you want from the list and then add a path element similar to the "main" source set like:
android.sourceSets."${flavorToChoose}".java.srcDirs.each {
pathelement(location: it.absolutePath)
}
Make sure to stick this block in your sourceroots section.

Categories

Resources