Android gradle teamcity testing - android

I've set my tests for my android projects to run automatically in team city. Tests are running and all is fine, but TeamCity doesnt seem to auto discover the test output. It doesn't catch that tests are being run (doesnt say x/x successfull for example). I've tried adding --info to the gradle connectedCheck target, but no luck. Any ideas how to achieve this?
I'm using the Gradle Teamcity-runner with the default instrumentation-config in Android Gradle.
Example output from build log for a couple of tests:
[10:11:20][:aproject:connectedInstrumentAFlavorDebug] com.test.sync.worker.SyncResponseValidatorTests > testPermanentErrorResponse[Galaxy Nexus - 4.2.1] [32mSUCCESS [0m
[10:11:20][:aproject:connectedInstrumentTestAFlavorDebug] com.test.sync.worker.SyncResponseValidatorTests > testSuccess[Galaxy Nexus - 4.2.1] [32mSUCCESS [0m

Related

"Unknown block type" reading JaCoCo execution data files from Android

I wanted:
Code coverage to run reliably against the instrumented tests
Tests to be isolated from each other
I'm new to Android development, but experienced with other development and tooling.
So I looked for the documented options and added the following to my build.gradle:
android {
defaultConfig {testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: 'true'
testInstrumentationRunnerArguments useTestStorageService: 'true'
}
buildTypes {
debug {
testCoverageEnabled true
}
}
I also have a custom task to generate the report:
task coverageReport(type: JacocoReport) {
sourceDirectories.setFrom(fileTree(
dir: "$project.buildDir/src/main/java"
))
classDirectories.setFrom(fileTree(
dir: "$project.buildDir/build/intermediates/javac/debug",
))
executionData fileTree(dir: project.buildDir, includes: [
"outputs/code_coverage/debugAndroidTest/connected/*/*.ec"
])
}
Now what I see when running the tests and generating the report, is that about 10% of the time it hits what looks like a corrupted .ec file. (the rest of the time, the report is fine)
> ./gradlew coverageReport
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:coverageReport'.
> Unable to read execution data file app/build/outputs/code_coverage/debugAndroidTest/connected/Nexus_S_API_33(AVD) - 13/com.example.coverage.ExampleInstrumentedTest#useAppContext.ec
Digging into the stack trace:
Caused by: : Unable to read execution data file app/build/outputs/code_coverage/debugAndroidTest/connected/Nexus_S_API_33(AVD) - 13/com.example.coverage.ExampleInstrumentedTest#useAppContext.ec
at org.jacoco.ant.ReportTask.loadExecutionData(ReportTask.java:518)
...
Caused by: java.io.IOException: Unknown block type 3.
at org.jacoco.core.data.ExecutionDataReader.readBlock(ExecutionDataReader.java:119)
at org.jacoco.core.data.ExecutionDataReader.read(ExecutionDataReader.java:93)
at org.jacoco.core.tools.ExecFileLoader.load(ExecFileLoader.java:60)
at org.jacoco.ant.ReportTask.loadExecutionData(ReportTask.java:516)
I've seen several other numbers in other projects for the unknown block type, but so far only 3 for this minimal example project.
MD5 sums are the same for the .ec files on and off the device:
> adb shell md5sum /data/media/0/googletest/internal_use/data/data/com.example.coverage/coverage_data/com.example.coverage.ExampleInstrumentedTest#useAppContext.ec
89c6b7ac8ad27d4d2f19dce0ac47f028 /data/media/0/googletest/internal_use/data/data/com.example.coverage/coverage_data/com.example.coverage.ExampleInstrumentedTest#useAppContext.ec
> md5sum app/build/outputs/code_coverage/debugAndroidTest/connected/Nexus_S_API_33\(AVD\)\ -\ 13/com.example.coverage.ExampleInstrumentedTest#useAppContext.ec
89c6b7ac8ad27d4d2f19dce0ac47f028 app/build/outputs/code_coverage/debugAndroidTest/connected/Nexus_S_API_33(AVD) - 13/com.example.coverage.ExampleInstrumentedTest#useAppContext.ec
Re-running the tests will generally clear the issue on this project. On a larger project, several tests fail like this on each run - different tests each time, though apparently some more than others. It doesn't appear to be linked to the running time of the test.
I tried different versions of:
Gradle (7.4, 7.5, 8.0-rc-1, 8.0-rc-2)
AGP (7.4, 8.1.0-alpha01)
Android Studio (Eel, Giraffe)
emulator SDK version (27, 31, 33)
with the same failing on each.
Syncing with Gradle files and cleaning/rebuilding don't help, and I've seen this happen on the first run of a new project.
I can see that:
Gradle support for Android lags (the new JaCoCo aggregate report plugin is explicitly not supported on Android)
Gradle's had and fixed some similar issues with JaCoCo in recent releases (e.g. https://github.com/gradle/gradle/issues/20532)
a similar issue's been seen with JaCoCo in other contexts (e.g. JaCoco MVN unknown block type which suggests the JVM's being hard-killed between tests)
Turning off clearPackageData doesn't stop these failures.
I was expecting code coverage of instrumented tests to be a core tool in my development process. So far it looks like either this error is a "me" problem, or Android devs don't see much value in having this working reliably. Any insights into why it's not that valuable or can be easily replaced would be as welcome as a fix.

Where is the Crashlytics log file located for the new Firebase Crashlytics SDK

For the previous Crashlytics SDK (Fabric) the file location of the logging was:
On Linux / Windows: /.crashlytics/com.crashlytics.tools/crashlytics.log
On Mac: ~/Library/Caches/com.crashlytics/com.crashlytics.tools/crashlytics.log
Since I started using the new Firebase Crashlytics SDK nothing is getting logged there anymore. I tried to search for other locations the file could be, but I couldn't find anything at all.
Firebaser here -
There is indeed no longer a crashlytics.log file. That information still exists if you invoke your symbol upload task with --debug. So if you have native symbol file upload enabled in Gradle, that may look like (all on Mac):
./gradlew app:uploadCrashlyticsSymbolFileDebug --debug
or
./gradlew app:assembleDebug --console=plain --debug
You may also see a lot of output irrelevant to Crashlytics. However your command looks, you may want to pipe a filter:
./gradlew ... | grep "[com.google.firebase.crashlytics]"
Finally, it can be inconvenient to be looking at the terminal or the logcat in Android Studio, so you may want to just save that output to a file:
./gradlew ... > crashlyticslog.txt

Re-run failed android tests

Is there a way to run only the failed set of tests on Android using Gradle?
At the moment, I run my tests as follows.
./gradle connectedDebugAndroidTest
There are tests that occasionally fail due to environment issues which are difficult to control and what I would like to do is be able to only run those failed tests and merge the result with the previous test results.
So for example, if I have 100 tests and 90 succeed, I would like to re-run the failing 10 tests. If those 10 pass the second time around, I would like to merge those results with the original test run.
It looks like this has been discussed several times for Gradle but there doesn't seem to be a solution yet.
https://github.com/gradle/gradle/issues/4068
https://github.com/gradle/gradle/issues/4450
https://github.com/gradle/gradle/issues/1283
Thanks!
The reason they don't have a way to only rerun failed tests is because it screws up the way Gradle currently works. This happens because on the first run, Gradle knows 90 tests passed. If you update the code, and then rerun only the 10 failed tests (using this new option you want them to add), then Gradle would think that all the tests have passed. However, this isn't the case because the tests which previously passed might've broken from the update which fixed the failing tests.
Despite this, the problem has been solved. Gradle reruns failed tests first, and provides a --fail-fast flag for the test task. This effectively does what you want (i.e., only reruns failed tests).
If you want to automatically rerun failed tests as part of the same build in which they failed, and succeed the build if they succeed on retry, you can use the Test Retry Gradle plugin. This will rerun each failed test a certain number of times, with the option of failing the build if too many failures have occurred overall.
plugins {
id 'org.gradle.test-retry' version '1.2.0'
}
test {
retry {
maxRetries = 3
maxFailures = 20 // Optional attribute
}
}

Android Unit test are giving wrong result

When I run a unit test for a new created project then it shows me the wrong result (Says All Tests are passed).
If you see in the image below 4 is expected while 6+2 surely not 4.
Now when I run the same test from Gradle right menu. It shows me the correct result that test has failed.
Did I do anything wrong or is this an android studio bug?
Edit
Run configuration image
You need to add -ea option in the "VM options" box in your 3rd image. This is to enable assertion feature for the JVM. Without this -ea, JVM just ignore assertion statement.
When you run the test with gradle, it used a default configuration so that's why your test was run correctly.

Jenkins failing robolectric test cases...!

I am trying to build my android project on Jenkins 2.0 server on Ubuntu machine.
I am running the following commands for that purpose:-
./gradlew clean (this is working fine)
./gradlew build (this is failing random number of test cases)
However I also install Jenkins 2.0 on my Windows 7 machine and run the same commands as above, and it was passing all test cases every time. I am not understanding what is wrong with that.
I did lot of debugging but could not find any solution, please help me to get rid out of this thing...!
This is my 34th build log on Jenkins
testPreCondition FAILED
java.lang.NullPointerException at ConfigurationFragmentTest.java:36
handleBackButtonPressing FAILED
java.lang.NullPointerException at ConfigurationFragmentTest.java:36
48 tests completed, 2 failed
:app:testDebugUnitTest FAILED
This is my 35th build log on Jenkins without making any code changes
> handleBackButtonPressing FAILED
java.lang.NullPointerException at ConfigurationFragmentTest.java:36
> testPreCondition FAILED
java.lang.NullPointerException at ConfigurationFragmentTest.java:36
> testPreconditions FAILED
java.lang.NullPointerException at UpdateTabFragmentTest.java:30
> testPreconditions FAILED
java.lang.NullPointerException at ServiceTabFragmentTest.java:29
> testPreConditionIsNotNull FAILED
java.lang.NullPointerException at HomeActivityTest.java:63
48 tests completed, 5 failed
:app:testDebugUnitTest FAILED
You should check the Jenkins console output for something like
"WARNING: No manifest file found " in the console output.
Those NPEs are typical for missing resources.
The most common source for failing robolectric builds on different environmnets is probably robolectric not beeing able to load any resources.
Since robolectric needs to know where your Android Manifest is, you may have to provide a extra robolectric.properties for the build
http://robolectric.org/configuring/

Categories

Resources