I have some Android instrumentation tests with a custom test runner that all seemed to work fine until at some point after I upgraded to Android Studio 2.1, bumped up some library versions, and did some other things over time. Now, my tests don't run anymore with the dreaded Unable to find instrumentation info for: ComponentInfo{} that has been asked about on StackOverflow a million times already.
Upon further investigation, it seems like Android Studio simply doesn't compile my test code, which then means its code is never included, so it can't find the ComponentInfo for the test runner. I verified that by adding compile errors in my test code, which never cause any issues when I try to run a test.
Furthermore, the test code seems to be treated like non-test code in the syntax highlighter? As an example, the test runner imports android.support.test.runner.AndroidJUnitRunner, but runner is highlighted in red as if that library is missing (but it's in the gradle file as androidTestCompile). If I change that to compile, the syntax highlighter is happy. However, the test code shows up in the project view in yellow, like test code would.
I'm not sure what determines what Android Studio compiles for a test. The setup is straightforward. My file hierarchy is
app
+--src
+ +--main
+ | +--java
+ | +--com/package/files
+ |
+ +--androidTest
+ +--java
+ +--com/package/files
In other words, there's app/src/main/java/com/... and app/src/androidTest/java/com.... Both the main app and the tests use the same package.
build.gradle (relevant parts):
apply plugin: 'com.android.application'
android {
compileSdkVersion 'Google Inc.:Google APIs:23'
buildToolsVersion '24.0.0 rc3'
defaultConfig {
multiDexEnabled = true
applicationId 'com.package'
minSdkVersion 10
targetSdkVersion 23
versionCode 2
versionName '0.8a'
signingConfig signingConfigs.release
testInstrumentationRunner 'com.package.TestRunner'
}
buildTypes {
release {
signingConfig signingConfigs.release
}
debug {
signingConfig signingConfigs.release
}
}
productFlavors {
}
dexOptions {
javaMaxHeapSize "4g"
}
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE-FIREBASE.txt'
exclude 'META-INF/NOTICE'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
lintOptions {
checkReleaseBuilds true
abortOnError true
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2'
androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
androidTestCompile 'com.android.support:support-annotations:23.1.1'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
[...]
}
apply plugin: 'com.google.gms.google-services'
The run/debug configuration for the test is straightforward as well - it's an Android Test, the instrumentation runner is com.package.TestRunner. I tried cleaning/rebuilding many times.
The answer is so embarrassing that I shouldn't post it.
The "Build Variant" for all my modules was set to "Release", so none of the test stuff was compiled. Setting it to "Debug" took care of the problem. Would be nice if Android Studio was a bit more vocal about it, like warning about running tests while using the release shards.
Related
So, the title pretty much sums up my problem. Anyone know how to fix it? Last time I build apk, it work fine on AS 2.X, but, I'm now developing with Kotlin so, I have to use AS 3.0.
I use AS 3.0 Canary 7 (This project is a fresh project)
This is my dummy class in my library (Stored in "domain".library.mylibrary)
class Test {
fun hello(): String {
return "hello"
}
}
And this is my (mylibrary) gradle:
apply plugin: 'com.android.library'
android {
compileSdkVersion 26
buildToolsVersion "26.0.0"
defaultConfig {
minSdkVersion 19
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation 'com.android.support:appcompat-v7:26.0.0-beta2'
testImplementation 'junit:junit:4.12'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" //Declared in project level gradle: ext.kotlin_version = '1.1.3-2'
}
My gradlew.bat clean build --info log: https://pastebin.com/bfTZ5s4e
Android Studio does not generate a jar by default, but rather an AAR file. If you want to get a jar output, you need to implement apply plugin: 'maven-publish' on top of your mylibrary/gradle.build file and read the following document: Chapter 36. Maven Publishing (new)
Another note, is that I would suggest you not to use ProGuard directly on your release artifact, but rather provide a consumer ProGuard file and let the users of your library to handle that task, otherwise they will have a hard time referencing obfuscated code. Read my answer on this here
While the build task may generate an output, it is known that the assemble task (or assembleRelease) is the one that will generate your aar output.
Try running the following command:
./gradlew clean assembleRelease
and check the output in /mylibrary/build/outputs/apk/release/ if I am not mistaken.
I am new in Instrumentation testing. I am trying basic testing with AndroidJUnitRunner. Here is my gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "25.0.0"
defaultConfig {
applicationId "com.kaushik.mycart.ui"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
jackOptions.enabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
..........................
..........................
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
}
Then I added a class named 'ProductListActivityTest' to test with AndroidJunitRunner. It is below:
package com.kaushik.myredmart.ui;
// all includes
#RunWith(AndroidJUnit4.class)
public class ProductListActivityTest {
#Rule
public ActivityTestRule<ProductListActivity> rule = new ActivityTestRule<>(ProductListActivity.class);
#Test
public void ensureListViewIsPresent() throws Exception {
ProductListActivity activity = rule.getActivity();
View viewByIdw = activity.findViewById(R.id.productListView);
assertThat(viewByIdw,notNullValue());
assertThat(viewByIdw, instanceOf(RecyclerView.class));
RecyclerView productListView = (RecyclerView) viewByIdw;
RecyclerView.Adapter adapter = productRecyclerView.getAdapter();
assertThat(adapter, instanceOf(ProductAdapter.class));
}
}
I have added no other file in 'androidTest'. I like to also mention that there is Application class file in my source code. Now every time I try to run the test, it is giving following error:
Started running tests
Test running failed: Instrumentation run failed due to 'java.lang.ClassNotFoundException'
Empty test suite.
Can anyone help me identifying the problem in my test code?
How are you running your tests?
If you are doing it from Android Studio:
Open Run menu -> Edit Configurations
Add a new Android Tests configuration
Choose a module
Add a specific instrumentation runner:
android.support.test.runner.AndroidJUnitRunner
From command-line via Gradle:
./gradlew connectedAndroidTest
I solved the problem. It is due to difference of Package names. I set all package name uniform and run again. It works. Thank you all for helping.
I upgraded Android Studio 2.2 -> 2.3 today and now have a compiler error when building my app in Android Studio that I didn't have before.
Error:No resource found that matches the given name (at 'versionName' with value '#string/BRAND_VERSION').
This is the string resource.
<string name="BRAND_VERSION">2.0</string>
This is the relevant section from the manifest.
<manifest package="com.metaswitch.cp.unbrandedpackage"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:versionCode="5"
android:versionName="#string/BRAND_VERSION">
According to Android documentation, string resources are allowed in the versionName in the manifest or in build.gradle.
This is not specific to my app. I can repro with this Android sample
It builds and installs fine for me. When I make this single line change to the versionName in build.gradle (picking a random string resource from strings.xml) it fails with the same error.
// versionName "1.0"
versionName "#string/add_task"
This is the build.gradle from the Android sample (note my edit to versionName).
apply plugin: 'com.android.application'
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
applicationId "com.example.android.architecture.blueprints.todomvploaders"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
// I really want to use a string resource here!
// versionName "1.0"
versionName "#string/add_task"
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
}
buildTypes {
debug {
minifyEnabled true
// Uses new built-in shrinker http://tools.android.com/tech-docs/new-build-system/built-in-shrinker
useProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguardTest-rules.pro'
}
release {
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguardTest-rules.pro'
}
}
// If you need to add more flavors, consider using flavor dimensions.
productFlavors {
mock {
applicationIdSuffix = ".mock"
}
prod {
}
}
// Remove mockRelease as it's not needed.
android.variantFilter { variant ->
if(variant.buildType.name.equals('release')
&& variant.getFlavors().get(0).name.equals('mock')) {
variant.setIgnore(true);
}
}
// Always show the result of every unit test, even if it passes.
testOptions.unitTests.all {
testLogging {
events 'passed', 'skipped', 'failed', 'standardOut', 'standardError'
}
}
buildToolsVersion '25.0.0'
}
/*
Dependency versions are defined in the top level build.gradle file. This helps keeping track of
all versions in a single place. This improves readability and helps managing project complexity.
*/
dependencies {
// App's dependencies, including test
compile "com.android.support:appcompat-v7:$rootProject.supportLibraryVersion"
compile "com.android.support:cardview-v7:$rootProject.supportLibraryVersion"
compile "com.android.support:design:$rootProject.supportLibraryVersion"
compile "com.android.support:recyclerview-v7:$rootProject.supportLibraryVersion"
compile "com.android.support:support-v4:$rootProject.supportLibraryVersion"
compile "com.android.support.test.espresso:espresso-idling-resource:$rootProject.espressoVersion"
compile "com.google.guava:guava:$rootProject.guavaVersion"
// Dependencies for local unit tests
testCompile "junit:junit:$rootProject.ext.junitVersion"
testCompile "org.mockito:mockito-all:$rootProject.ext.mockitoVersion"
testCompile "org.hamcrest:hamcrest-all:$rootProject.ext.hamcrestVersion"
// Android Testing Support Library's runner and rules
androidTestCompile "com.android.support.test:runner:$rootProject.ext.runnerVersion"
androidTestCompile "com.android.support.test:rules:$rootProject.ext.runnerVersion"
// Dependencies for Android unit tests
androidTestCompile "junit:junit:$rootProject.ext.junitVersion"
androidTestCompile "org.mockito:mockito-core:$rootProject.ext.mockitoVersion"
androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
// Espresso UI Testing
androidTestCompile "com.android.support.test.espresso:espresso-core:$rootProject.espressoVersion"
androidTestCompile "com.android.support.test.espresso:espresso-contrib:$rootProject.espressoVersion"
androidTestCompile "com.android.support.test.espresso:espresso-intents:$rootProject.espressoVersion"
// Resolve conflicts between main and test APK:
androidTestCompile "com.android.support:support-annotations:$rootProject.supportLibraryVersion"
androidTestCompile "com.android.support:support-v4:$rootProject.supportLibraryVersion"
androidTestCompile "com.android.support:recyclerview-v7:$rootProject.supportLibraryVersion"
androidTestCompile "com.android.support:appcompat-v7:$rootProject.supportLibraryVersion"
androidTestCompile "com.android.support:design:$rootProject.supportLibraryVersion"
}
I had the same problem after upgrading Android Studio. Turning off instant run in preferences helped the app to run again.
With reference to Google issue tracker,This has been fixed. This is available with Android studio 3.0.0-alpha6 build.
If any issue persists, please report at Google issue tracker they will re-open to examine.
I have an Android project and I use Android Studio. In this project, I have the main app (cdmandroidclient) and the SDK (cdmsdk) which is the core lib.
I added recently a library built with Java 8 into my Android project. So I had to change a few things into my Gradle files :
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "24.0.1"
defaultConfig {
applicationId "com.mycompany.cdmandroidclient"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
jackOptions {
enabled true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled false
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile project(path: ':cdmsdk')
compile 'com.android.support:appcompat-v7:24.2.0'
}
As you can see, I import into my app, the cdmsdk module, which is part of my project. Before using Jack, everything was fine.
Now, when I try to build the app I get errors for resolving dependencies of my module "cdmsdk" into my app "cdmandroidclient".
Exemple of an error :
Error:E:\Workspace\CDMAndroidClient\app\src\main\java\com\mycompany\cdmandroidclient\service\CdmService.java:16:
The import com.mycompany.cdmsdk.heartbeat.Security cannot be resolved
I don't understand what's happening, because the main app dependencies have not changed and still reference the SDK with :
compile project(path: ':cdmsdk')
The Gradle build fail as I said, during the task :app:compileDebugJavaWithJack
Any idea ? Thank you very much :) !
EDIT : It's the exact same thing as Javac and with Java 7... don't know what I've changed but my app can't use cdmsdk dependencies anymore ... wtf
My android application uses the following config:
Gradle - 0.12.+
Contents of build.gradle file
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.12.+'
}
}
repositories {
mavenLocal()
mavenCentral()
}
apply plugin: 'com.android.library'
apply plugin: "jacoco"
dependencies {
compile 'commons-collections:commons-collections:3.2.1'
compile 'org.slf4j:slf4j-android:1.6.1-RC1'
// dependency injection
compile('org.roboguice:roboguice:2.0') {
exclude module: 'cglib'
exclude module: 'aopalliance'
exclude module: 'guice'
}
compile files('libs/guice-3.0-no_aop.jar')
compile 'javax.inject:javax.inject:1'
/*
* Test dependencies.
*/
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.0'
}
android {
buildToolsVersion "20.0"
compileSdkVersion 19
buildTypes {
debug {
runProguard false
testCoverageEnabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
defaultConfig {
minSdkVersion 8
targetSdkVersion 19
versionCode 100
versionName "1.0.0"
}
/*
* Workaround for packaging bug in Android Gradle plugin regarding duplicate files.
*/
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'LICENSE.txt'
}
}
All my tests run successfully when property testCoverageEnabled is set to false. On setting it to true, the following exception is thrown when running the tests
Caused by: java.lang.VerifyError: *** Some class ***
at dalvik.system.DexFile.defineClass(Native Method)
at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:211)
at dalvik.system.DexPathList.findClass(DexPathList.java:313)
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:51)
at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
The error happens on the line when mocks are initialised within the tests.
Has anyone managed to generate code coverage metrics for android application which uses mockito library for testing?
The following link was very useful in explaining the problem I encountered: http://www.androidpuzzles.com/168_17620080/
I subsequently switched the source and target compatibility settings to Java 1.5 and I was able to run the unit and UI tests (which used both mockito and espresso) and generate code coverage report using Jacoco.
If I had to retain Java 1.7 settings, the workaround would have been to change the scope of private methods in the class being tested to either protected or public scope. This would have then allowed me to generate the code coverage report (overcoming the issue as identified in the link included).
Jacoco coverage support has been added to the gradle plugin since 0.10.0. See http://tools.android.com/tech-docs/new-build-system.
Not quite sure I understand why you have such a complex gradle file.
You need to compile against Java 1.5 version.
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_5
targetCompatibility JavaVersion.VERSION_1_5
}
https://code.google.com/p/android/issues/detail?id=69174
This issue has been fixed in build tools version 21+
android {
buildToolsVersion "21.1.2"
compileSdkVersion 19
...
}
Upgrade build tools to 21+ to retain Java 1.7 compatibility.