When running Espresso tests with ./gradlew connectedDebugAndroidTest, we're having this issue:
com.android.build.api.transform.TransformException:
com.android.ide.common.process.ProcessException:
java.util.concurrent.ExecutionException:
com.android.dex.DexIndexOverflowException: method ID not in [0,
0xffff]: 65536
As we're using Multidex at the main app and just adding the Espresso dependencies on the instrumented test one, we don't get why it doesn't work :·( In addition, if we run the tests via IntelliJ instead of Gradle, it works :·|
By the way, we need to run them via Gradle to automate them on the CI tool.
More information? There's a link to a related issue on Google's issue tracker: https://issuetracker.google.com/issues/37017515 :sad:
The task connectedDebugAndroidTest will try to build test apks for every module in the project, so if you project has multiple modules, you need to enable multidex in every one of them. This is usually done setting
android.defaultConfig.multiDexEnabled true
in build.gradle for each module.
You could skip all of this for modules that don't have any tests if you just don't try to execute the task in those. e.g, if only the app module has instrumentation tests, you could execute app:connectedDebugAndroidTest instead to avoid the possible multidex errors. This is actually what the run configuration created by Android Studio does by default, and probably the reason why your tests are running just fine when you launch them form the IDE.
Related
I have a project using dynamic feature module, and I want to run my unit test in feature module via gradle task (for my CI purpose):
./gradlew :feature_product:test
But it always gives me NoClassDefFoundError for tests that have dependencies on classes from the base module:
com.example.android.feature.product.ProductViewTest > on vote change to negative FAILED
java.lang.NoClassDefFoundError: app.BaseView
ProductView class from the feature module extends BaseView from the base module.
Oddly, it succeeds when run in Android Studio, it works fine.
Then I notice something different in the logs, when I run via command line and when I run Android Studio. The first line in the Android Studio is generateDebugSources, something which absent when I run ./gradlew test
Executing tasks: [:lib_ui:generateDebugSources, ...]
How do I fix this? Does Android Studio has different command with the provided command ./gradlew test when I press Ctrl+Shift+R ?
After searching further about this issue, I found it also being reported in the android-test and app-bundle-samples projects and there is also an issue in the issue tracker.
It turns out this issue fixed in the Android Gradle Plugin 4.1.0 as per comment in the issue tracker.
If you don't want to update AGP to 4.1.0 which is still in alpha, adding this to the feature module's build.gradle fixed the issue for me, as per this comment:
testRuntimeOnly(files("$projectDir/../b_app/build/intermediates/app_classes/debug/classes.jar"))
If it is a missing task that you believe is necessary then calling it first like below should do the trick:
./gradlew :lib_ui:generateDebugSources :feature_product:test
I would even go full on and assemble the dependencies if necessary though that might take more time:
./gradlew :lib_ui:assemble :feature_product:assemble :feature_product:test
I am currently testing my sample app using Android instrumentation test. By default, the project creates AndroidTest folder for me. I simply just added more test cases into the folder.
I used to use expresso to trigger the UI buttons, but now I want to test use androidTest only, However, the androidTest does not seem to test my release build. I have two variants productionRelease and stageDebug in this case.
Every time I started the project by
./gradlew mysample:connectedCheck
or
./gradlew mysample:connectedAndroidTest
it tests only
Task :mysample:connectedStageDebugAndroidTest
If I want to manually start a task
./gradlew mysample:connectedProductionReleaeAndroidCheck
It complains tasks not found in mysample
* What went wrong:
Task 'connectedProductionReleaseAndroidTest' not found in project ':mysample'.
Isn't connectCheck supposed to test all the variants in my project? (StageDebug and ProductionRelease)
from task --all
mysample:connectedCheck - Runs all device checks on currently connected devices.
mysample:connectedAndroidTest - Installs and runs instrumentation tests for all flavors on connected devices.
Just tried... one can simply run ./gradlew mysample:testDebugUnitTest and ./gradlew mysample:testReleaseUnitTest - which runs the tests for either debug or release build. one can add the annotation #RequiresDevice to tests, in case eg. one requires hardware sensors.
productionRelease and stageDebug seem over-complicated (and it also not matches the rest of the naming - unless there would be productionDebug and stageRelease as well), resulting in even longer task names, would suggest to shorten...
buildTypes {
debug {}
release {}
}
Here when I run ./gradlew mysample:connectedAndroidTest I rather get a
Execution failed for task ':mysample:connectedDebugAndroidTest'.
com.android.builder.testing.api.DeviceException: No connected devices!
After closing Android Studio (and the ADB daemon it started), I can run the tests on hardware device. there only is a installDebugAndroidTest task, but no installReleaseAndroidTest task. testBuildType 'release' might run the tests against the release build - the problem is just that androidTestImplementation most likely is not contained then (quite useless).
When I am trying to run Android tests by executing:
./gradlew connectedDebugAndroidTest
The following error occurs:
com.android.builder.testing.ConnectedDevice > No tests found.[devicename] FAILED
No tests found. This usually means that your test classes are not in the form that your test runner expects (e.g. don't inherit from TestCase or lack #Test annotations).
:connectedDebugAndroidTest FAILED
FAILURE: Build failed with an exception.
I have not made any changes to build.gradle or gradle-wrapper.properties files.
The issue can't be solved by updating everything to the latest version (gradle, android plugin, build tools, etc.)
All tests were previously successful. What could cause this mystic regression? Thanks.
One possible reason for this error message is that you get a crash in the app early in the test Runner. In such cases the exception stack will be in logcat but not in the gradle output.
I had the issue, try upgrading the test runner. Upgrading it to 0.5 from 0.4.x solved it. Ensure you have these lines in your build.gradle:
androidTestCompile "junit:junit:4.12"
androidTestCompile "com.android.support.test:runner:0.5"
I faced this exact issue today. Please do feel free to use all the other worthy solutions as mentioned above but what specifically worked for me was to delete the ".gradle" folder (found under the project panel on the left in Android Studio) entirely, followed by a clean build. A simple clean build didn't work for me.
This can happen if the tests are placed in the test or androidTest directory without a package. The path should be something like /src/androidTest/kotlin/yourPackageName/yourTestClass.
You can check if individually, all tests pass. Could be some test(s) is(are) failing. Had a similar issue and that was my case
I solved this by deleting androidTests folders from unneeded modules - /common and /data in my case.
When I make changes to Dagger 2 components, I'd like it to rebuild the injection classes. But I don't want to run a whole project Rebuild because that takes 5 minutes, even with the gradle daemon.
In some cases it automatically rebuilds, but in other cases it doesn't.
What gradle task can I run to just re-create the Dagger 2 files?
You need to generate the source files by running the apt plugin. This happens while compiling your sources. Use gradlew compileDebugSources to trigger the compilation or use Make Project in your IDE.
If you want to check the sources, you can see that it attaches itself to the javaCompile tasks.
Also see How to trigger the minimal task on Gradle to run apt plugin.
I'm trying to incorporate more unit tests, specifically Robolectric test into my project. Right now I already have some functional test that are in my androidTest package. The problem is that if I add a Robolectric Test Class to that package then when I execute ./gradlew test all the functional test are ran along with the Robolectric/Unit Tests.
Is best practice to be using a different test package for my unit tests? And if that's the case then will I have to configure the Gradle test task to look at only the unit test package?
I should mention that I'm on Android Studio 1.0, Gradle 1.0, and Robolectric 2.4.
./gradle test runs all the test in your project. You will likely have (at least) two modules in your project, lets call them app and robolectric-tests.
You can tell Gradle to run a task on a specific module by using ./gradlew :module:task. So in your case, you could run ./gradlew :robolectric-tests:test to run only your Robolectric tests.