I've been trying to do it for a few days, with no result. I need to set up Robolectric in Android Studio (0.8.9, latest version).
I followed different tutorials Android Unit and Integration testing, Roboelectric installation for Unit testing, Android Gradle app with Roboelectric, How to run Roboelectric JUnit tests but always got some kind of error.
So I created module specially for testing:
Kedzoh (Project) build.gradle:
// Top-level build file where you can add configuration options common to all sub- projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.12.+'
classpath 'org.robolectric:robolectric-gradle-plugin:0.12.+'
}
}
allprojects {
repositories {
jcenter()
}
}
app build.gradle:
apply plugin: 'com.android.application'
apply plugin: 'android'
android {
compileSdkVersion 19
buildToolsVersion '19.1.0'
defaultConfig {
applicationId 'com.dev.kedzoh'
minSdkVersion 9
targetSdkVersion 19
versionCode 14
versionName '1.6.7'
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors {
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:19.+'
compile 'com.google.android.gms:play-services:4.2.42'
compile 'com.squareup.retrofit:retrofit:1.6.1'
compile 'com.squareup.okhttp:okhttp:2.0.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.0'
compile 'com.google.code.gson:gson:2.2.4'
compile 'com.squareup.picasso:picasso:2.3.3'
// You must install or update the Support Repository through the SDK manager to use this dependency.
compile 'com.android.support:support-v4:19.+'
compile 'com.google.guava:guava:18.0-rc1'
compile 'com.sothree.slidinguppanel:library:+'
compile 'com.larswerkman:HoloColorPicker:1.4'
}
kedzoh-tests build.gradle:
apply plugin: 'java'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.squareup.retrofit:retrofit:1.6.1'
compile 'com.squareup.okhttp:okhttp:2.0.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.0'
compile 'com.google.code.gson:gson:2.2.4'
compile 'com.squareup.picasso:picasso:2.3.3'
// You must install or update the Support Repository through the SDK manager to use this dependency.
compile 'com.google.guava:guava:18.0-rc1'
compile 'com.sothree.slidinguppanel:library:+'
compile 'com.larswerkman:HoloColorPicker:1.4'
testCompile 'junit:junit:4.+'
testCompile 'org.robolectric:robolectric:2.2'
}
At this point I cannot import Robolectric classes, it gives me error. When I add apply plugin: 'robolectric' to kedzoh-tests build.gradle, it asks for 'android' plugin. After I add it, it complains there is no Manifest and fails to build.
I'm not sure that this is the right configuration, since it never worked really. Could anyone give some advice how to set Robolectric in Android Studio, please?
EDIT:
I tried the answer below, but still stuck with "Class not found" error:
There already different project templates for robolectric. Did you try https://github.com/nenick/android-gradle-template ?
I think you maybe making your life more difficult and complicated by creating your test module outside of the main 'app' module. Most of the tutorials I have seen have an androidTest folder in the app module that can contain your Robolectric tests. All of the older tutorials based around Eclipse I have seen, seem to instruct us to create test modules separate to the main project.
If I were using Robolectric I would setup the project like I have created for you https://github.com/marcthomas2013/Kedzoh. I would use the androidTest folder to put my tests and configure the gradle files as follows.
Note that the dependencies for the tests are included using the androidTestCompile declaration and application dependencies are declared using just compile.
Another item in this gradle file is the robolectric section where it is including and excluding classes in the androidTest folder. Anything that isn't in the espresso folder will be run using the gradlew test target and everything including the espresso folder will be run when calling gradlew connectedAndroidTest target.
app gradle file
apply plugin: 'com.android.application'
apply plugin: 'robolectric'
android {
packagingOptions {
exclude 'LICENSE.txt'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE'
}
compileSdkVersion 19
buildToolsVersion "19.1.0"
defaultConfig {
minSdkVersion 18
targetSdkVersion 18
versionCode 2
versionName "1.0.0-SNAPSHOT"
testInstrumentationRunner "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"
}
buildTypes {
release {
runProguard false
}
}
sourceSets {
androidTest {
setRoot('src/androidTest')
}
}
}
robolectric {
include '**/*Test.class'
exclude '**/espresso/**/*.class'
}
dependencies {
repositories {
mavenCentral()
}
compile 'com.sothree.slidinguppanel:library:2.0.1'
androidTestCompile('junit:junit:4.11') {
exclude module: 'hamcrest-core'
}
// Espresso
androidTestCompile files('libs/espresso-1.1.jar')
androidTestCompile files('libs/testrunner-1.1.jar')
androidTestCompile files('libs/testrunner-runtime-1.1.jar')
androidTestCompile 'com.google.guava:guava:14.0.1'
androidTestCompile 'com.squareup.dagger:dagger:1.1.0'
androidTestCompile 'org.hamcrest:hamcrest-integration:1.1'
androidTestCompile 'org.hamcrest:hamcrest-core:1.1'
androidTestCompile 'org.hamcrest:hamcrest-library:1.1'
androidTestCompile('org.robolectric:robolectric:2.3') {
exclude module: 'classworlds'
exclude module: 'commons-logging'
exclude module: 'httpclient'
exclude module: 'maven-artifact'
exclude module: 'maven-artifact-manager'
exclude module: 'maven-error-diagnostics'
exclude module: 'maven-model'
exclude module: 'maven-project'
exclude module: 'maven-settings'
exclude module: 'plexus-container-default'
exclude module: 'plexus-interpolation'
exclude module: 'plexus-utils'
exclude module: 'wagon-file'
exclude module: 'wagon-http-lightweight'
exclude module: 'wagon-provider-api'
}
androidTestCompile 'com.squareup:fest-android:1.0.+'
}
project build file
Here we include the robolectric class path so that we can use the robolectric gradle commands in the config file above.
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.12.2'
classpath 'org.robolectric:robolectric-gradle-plugin:0.11.+'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
mavenCentral()
}
}
Can you explain what errors that you are having as there could be many possible errors based on how you are working, also is there a particular reason for creating a separate test module.
The project that I have provided is based on the deck-gradle setup (https://github.com/robolectric/deckard-gradle) there are a number of tips in here about JUnit conflicts etc. that you could be having trouble with.
Once you have got this far in order to be able to debug the unit test in the application you will have to manually tweak the classpath when launching the test (Not Pretty at all!), based on the information in this article https://github.com/codepath/android_guides/wiki/Robolectric-Installation-for-Unit-Testing
You will need to run your unit test, wait for it to fail, copy the -classpath parameter and it's value (It will be quite long and starts and finishes with ") and copy this into your VM Options in your run configuration, then at the end of that classpath add a ; or a : depending on your OS path delimeter and add the path to your test classes which will be something like <ABSOLUTE_PATH_TO_PROJECT>/build/test-classes this will add your test classes to the class path and then Android Studio should be able to run them.
This is also assuming that the steps to run the gradle testClasses has been done from the article http://blog.blundell-apps.com/how-to-run-robolectric-junit-tests-in-android-studio/
Related
I have searched online about this error and the issue always seems to end up being some sort of dependency conflict. I think I am supposed to add exclude after certain dependencies, but I am unsure which one(s). It's also unclear based on the error which dependency I should actually exclude; all I know is that the group is probably com.android.support...
Here's what I've tried:
Adding multiDexEnabled true to my defaultConfig block in build.gradle.
Cleaning the project in Android Studio.
Manually deleting (from the file system) the entire .gradle directory.
I've made sure compileSdkVersion and targetSdkVersion are the same.
I've made sure all my Android dependencies use the same version (namely 26.1.0).
Despite all this, I still get this error when I build:
Program type already present: android.support.compat.R$bool
and from the Java compiler:
Caused by: com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:
F:\ExampleProject\app\build\intermediates\transforms\dexBuilder\debug\115,
F:\ExampleProject\app\build\intermediates\transforms\externalLibsDexMerger\debug\0
Here is my module's build.gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.myapp.exampleproject"
minSdkVersion 17
targetSdkVersion 26
versionCode 1
versionName "1.2"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support:design:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:support-v4:26.1.0'
implementation 'com.android.support:support-compat:26.1.0'
implementation 'com.android.volley:volley:1.1.0'
implementation 'com.github.bumptech.glide:glide:4.1.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.1.0'
}
and lastly, my project's build.gradle file:
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Any help in rectifying this would be greatly appreciated.
This is a problem with Glide 4.1.0. Use the version 4.1.1 instead which fix the bug by remove the R*.class file from their dependencies. (source)
This is probably because of Glide library. Try to exclude the support library from it with:
// add support-fragment removed from Glide.
implementation "com.android.support:support-fragment:26.1.0"
implementation ('com.github.bumptech.glide:glide:4.1.0') {
exclude group: 'com.android.support'
exclude module: 'support-fragment'
exclude module: 'appcompat-v7'
}
You can see the support library inside Glide at Glide build.gradle
Solution:
implementation ('com.github.bumptech.glide:glide:4.1.0') {
exclude group: 'com.android.support'
exclude module: 'support-fragment'
exclude module: 'appcompat-v7'
}
I am trying to write a test case using Espresso.
I am using Android Studio 1.5.1 (Stable channel), Gradle plugin 1.5, Gradle 2.7.
The problem is that Android Studio doesn't recognize any import related to Espresso (and not only)
So, I tried to clean the project, rebuild, invalidate cache and restart, but nothing.
I added these dependencies in my app module:
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
androidTestCompile 'com.android.support:support-annotations:23.1.1'
androidTestCompile 'com.android.support.test:runner:0.4.1'
androidTestCompile 'com.android.support.test:rules:0.4.1'
I added the runner in defaultConfig:
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
I created the test suite class under androidTest folder:
What am I doing wrong please?
UPDATE
Here is (part) of my build.gradle:
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
android {
compileSdkVersion 23
buildToolsVersion '23.0.2'
defaultConfig {
minSdkVersion 15
targetSdkVersion 23
versionCode 5
versionName '1.4'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
buildTypes {
//my build type configs
}
packagingOptions {
exclude 'META-INF/services/javax.annotation.processing.Processor'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
}
lintOptions {
disable 'InvalidPackage'
}
dexOptions {
incremental true
preDexLibraries = false
jumboMode = false
javaMaxHeapSize "2g"
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.viewpagerindicator:library:2.4.1'
compile project(':libraries:RITracking')
compile 'com.android.support:support-v4:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:support-annotations:23.1.1'
compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'com.android.support:cardview-v7:23.1.1'
compile 'com.android.support:gridlayout-v7:23.1.1'
compile 'com.google.code.gson:gson:2.5'
compile 'com.google.android.gms:play-services-plus:8.4.0'
compile 'com.google.android.gms:play-services-base:8.4.0'
compile 'de.greenrobot:eventbus:2.4.1'
compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.squareup.okhttp:okhttp:2.7.2'
compile 'com.facebook.android:facebook-android-sdk:4.9.0'
compile 'com.cocosw:bottomsheet:1.2.0#aar' //Bottom Sheet that implement material design used for ShareDialog
compile 'com.github.bumptech.glide:glide:3.6.1' //Glide library
compile 'com.googlecode.libphonenumber:libphonenumber:7.2.3' //Library used to parse/merge phones number to E164 format
compile 'me.leolin:ShortcutBadger:1.1.3#aar' //Used to show badge on application icon, library is optimized to work on most of devices
compile 'com.stripe:stripe-android:1.0.3' //Stripe payment gateway, used to integrate credit card payment
provided 'org.projectlombok:lombok:1.16.6'
apt "org.projectlombok:lombok:1.16.6"
compile 'com.jakewharton:butterknife:7.0.1'
apt "com.jakewharton:butterknife:7.0.1"
compile 'de.greenrobot:greendao:2.1.0' //Green Dao library is ORM implementation for Android SQL lite
compile files('libs/libammsdk.jar')
compile files('libs/apptimize-android-2.9.1.jar')
testCompile 'junit:junit:4.12'
androidTestCompile "com.android.support:support-annotations:23.1.1"
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.1'
androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.1') {
exclude group: 'com.android.support', module: 'appcompat'
exclude group: 'com.android.support', module: 'support-v4'
exclude module: 'recyclerview-v7'
}
androidTestCompile 'com.android.support.test:runner:0.4.1'
androidTestCompile 'com.android.support.test:rules:0.4.1'
}
Perhaps your Build Variant is on "release" mode. you have to change it to debug.
UPDATE 30/11/2016
Just like #Jaymes Bearden said in comment below.
Use testBuildType. Android Studio 2.2, gradle 2.2.2
android {
testBuildType "yourBuildType"
}
OLD ANSWER
I found not solution but some source of problem. In my project I have, a lot of BuildTypes. Especially more than one debug build.
Everything works only in default debug build type. I think that this is some internal Android Studio error.
My AS version - 2.1
You need to use debug build variant. With other build options espresso will not be recongnised.
I'm pretty sure, that you're something missing in your configuration. compare your build.gradle with mine below
def ASVersion = '23.1.1'
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'io.fabric.tools:gradle:1.+'
}
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
apply plugin: 'com.neenbedankt.android-apt'
repositories {
maven { url 'https://maven.fabric.io/public' }
}
android {
dataBinding {
enabled = true
}
compileSdkVersion 23
buildToolsVersion '23.0.2'
defaultConfig {
applicationId "com.piotr.awesome"
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
androidTestCompile "com.android.support:support-annotations:$ASVersion"
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.1'
androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.1') {
exclude group: 'com.android.support', module: 'appcompat'
exclude group: 'com.android.support', module: 'support-v4'
exclude module: 'recyclerview-v7'
}
androidTestCompile 'com.android.support.test:runner:0.4.1'
compile "com.android.support:appcompat-v7:$ASVersion"
compile "com.android.support:support-v4:$ASVersion"
compile "com.android.support:design:$ASVersion"
}
Also choose File -> Invalidate cache/restart and try first option.
Hope it help
In 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
Also try to update the Android Support Library from SDK Manager.
Hope this helped.
You can also try this topic: link
Good luck!
I had the same problem. Here is how i fixed it:
Go the src directory of your project in finder/explorer, select the directory containing your test.
Rename the directory with the prefix "androidTest" followed by the name of the flavor you are trying to test.
Open Android Studio, Invalidate Caches and Restart.
ive recently upgraded to android studio 1.2.1.1 and all of a sudden when I run my project iam getting the error "local path doesnt exist"?
this is due to the fact that the debug .apk file is not in the location the IDE is looking.
local path: C:\Users\eoin_a\AndroidStudioProjects\XmppTest\app\build\outputs\apk\app-debug.apk
ive searched myself and the apk isn't there. In fact i cant seem to find the .apk file in my project at all?
Ive tried a number of solutions Ive seen on previously asked questions but Iam getting no joy here. Ive tried syncing with gradle and clean the project with no luck.
Ive tried in cmd "gradlew clean packageDebug" to no avail.
i would try adding this to the project .iml file
<option name="APK_PATH" value="/build/apk/apk file name" />
inside tags.
but I dont have a .apk file or I cant find it.
If anyone could help me out here that would be awesome!
also withing my dependencies in gradle I have gradle plugin version 1.2.3
classpath 'com.android.tools.build:gradle:1.2.3'
EDIT:
just thought id put up my gradle.build files as they may be of use. Iam still not sure whats going on
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.example.eoin_a.xmpptest"
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
compile ("org.igniterealtime.smack:smack-android:4.1.0-rc1")
{
exclude(group: 'xpp3', module: 'xpp3')
exclude(group: 'org.apache.httpcomponents', module: 'httpclient')
}
compile ("org.igniterealtime.smack:smack-tcp:4.1.0-rc1")
{
exclude(group: 'xpp3', module: 'xpp3')
exclude(group: 'org.apache.httpcomponents', module: 'httpclient')
}
// optional features
compile ("org.igniterealtime.smack:smack-android-extensions:4.1.0-rc1")
{
exclude(group: 'xpp3', module: 'xpp3')
exclude(group: 'org.apache.httpcomponents', module: 'httpclient')
}
compile 'javax.annotation:jsr250-api:1.0'
apt 'com.google.dagger:dagger-compiler:2.0'
compile 'com.google.dagger:dagger:2.0'
compile 'org.glassfish:javax.annotation:10.0-b28'
testCompile 'junit:junit:4.12'
testCompile "org.assertj:assertj-core:1.7.0"
testCompile('org.robolectric:robolectric:3.0-rc2') {
exclude group: 'commons-logging', module: 'commons-logging'
exclude group: 'org.apache.httpcomponents', module: 'httpclient'
}
}
and
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
classpath 'org.robolectric:robolectric-gradle-plugin:1.0.1'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenCentral()
}
}
Could you see if you have in this way your settings:
1.In build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
2.In gradle-wrapper.properties make sure to use gradle 2.2.1
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
3.Sync project with gradle files by pressing the button to the left of the avd button
4.Try to build project again. If still having issues possibly try File > Invalidate Caches/Restart
Doing this way worked for me
I follow this https://stackoverflow.com/a/19496969/2091181
com.android.dex.DexException: Multiple dex files define Lorg/hamcrest/Description
occurring while trying to do a debug build/test either via Android Studio or via Gradle command-line on my application.
The release build (without tests) works fine but as soon as testing is included (hamcrest being a testing library), the build fails with the above error.
I've checked my module dependencies and there's no duplicate requirements which gradle -q dependencies corroborates.
Project settings.gradle
include ':[library module]'
include ':[main module]'
Project build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.9.+'
classpath 'org.robolectric.gradle:gradle-android-test-plugin:0.9.+'
}
}
allprojects {
repositories {
mavenCentral()
}
}
[library module] build.gradle
apply plugin: 'android-library'
android {
compileSdkVersion 19
buildToolsVersion "19.0.0"
defaultConfig {
minSdkVersion 14
targetSdkVersion 19
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
}
}
dependencies {
compile 'com.google.zxing:core:3.0.+'
compile 'com.bugsnag:bugsnag-android:2.1.1+'
}
[main module] build.gradle
apply plugin: 'android'
android {
signingConfigs {
release {
[...]
}
}
sourceSets {
main {
manifest.srcFile 'src/main/AndroidManifest.xml'
res.srcDirs = ['src/main/res']
}
androidTest {
setRoot('src/test')
}
instrumentTest {
}
}
compileSdkVersion 19
buildToolsVersion '19.0.0'
defaultConfig {
minSdkVersion 14
targetSdkVersion 19
testPackageName "[main.packageName].tests"
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
}
}
apply plugin: 'android-test'
androidTest {
// configure the set of classes for JUnit tests
include '**/*Test.class'
// configure max heap size of the test JVM
maxHeapSize = "2048m"
}
repositories {
maven { url 'https://repo.commonsware.com.s3.amazonaws.com' }
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}
dependencies {
androidTestCompile 'junit:junit:4.10'
androidTestCompile 'org.robolectric:robolectric:2.3-SNAPSHOT'
androidTestCompile 'com.squareup:fest-android:1.0.+'
compile project(':[library module]')
compile 'com.github.gabrielemariotti.changeloglib:library:1.4.+'
compile 'com.google.code.gson:gson:2.2.4'
compile 'com.google.android.gms:play-services:+'
compile 'com.android.support:appcompat-v7:+'
compile ('de.keyboardsurfer.android.widget:crouton:1.8.+') {
exclude group: 'com.google.android', module: 'support-v4'
}
compile files('libs/CWAC-LoaderEx.jar')
compile 'com.squareup.okhttp:okhttp:1.5.+'
compile 'com.octo.android.robospice:robospice:1.4.11'
compile 'com.octo.android.robospice:robospice-cache:1.4.11'
compile 'com.octo.android.robospice:robospice-retrofit:1.4.11'
compile 'com.commonsware.cwac:security:0.1.+'
compile 'com.readystatesoftware.sqliteasset:sqliteassethelper:+'
}
I solved the error by looking in Android Studio for the exact class called 'Description'. It turned out to be present in 3 jars. One from junit, one from a direct dependency and one from mockito.
It turns out that junit, instead of a normal dependency, includes the Hamcrest classes in the junit jar.
To be able to solve the problem include junit-dep instead of junit.
so change
androidTestCompile('junit:junit:4.8.+')
to
androidTestCompile('junit:junit-dep:4.8.+')
Mockito has the same problem/solution: use mockito-core.1.9.5.jar instead of mockito-all.1.9.5.jar
My project had a dependency on json-simple version 1.1.1, which for some reason has a run-time dependency on junit version 4.1.0, which itself has a dependency on Hamcrest. I could see this if I ran gradle dependencies or alternatively by inspecting the json-simple POM.xml.
// compile - Classpath for compiling the main sources.
\--- com.googlecode.json-simple:json-simple:1.1.1
\--- junit:junit:4.10
\--- org.hamcrest:hamcrest-core:1.1
Excluding the junit artifact from json-simple allowed me to build.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile ('com.googlecode.json-simple:json-simple:1.1.1') {
exclude module: 'junit'
}
}
Robolectric 2.3 depends on JUnit 4.8.1 (version explicit). You're importing JUnit 4.10 (version explicit). Hamcrest is probably simply the first of many duplicates that dex is choking on - try changing your JUnit requirement version to 4.8+ (or excluding JUnit from the Robolectric dependency).
exclude module: junit
if you are using json:simple dependency
I'm trying to use Robolectric in a project build with gradle inside the new Ide for android: Android studio, but I'm facing a strange problem, I've correctly imported all the libraries and created the "test" folder inside "src", the fact is that whenever I run the tests the ide keep saying "Class not found: "com.example.myandroidproject.test" what I'm doing wrong? i need to change something in the gradle.build? here's my directory structure:
#Aldo Borrero, finally it seems that someone has found the way to test android projects under "Android Studio" using Robolectric and Gradle.
Please, take a look at this answer Robolectric with Gradle
Update:
The guys from square have released a plugin to make Robolectric work out of the box with Gradle and Android Studio, this feature will be integrated with Robolectric in v2, meanwhile you can grab the plugin here: Gradle Android test Plugin
I tried different appraoaches to combine android studio & robolectric & espresso. I ended with this example project setup https://github.com/nenick/android-gradle-template
Here some explanation for the different approaches:
application module + espresso + robolectric
There is an example https://github.com/robolectric/deckard-gradle supported by robolectric maintainers.
This is based on the plugin https://github.com/robolectric/gradle-android-test-plugin. But this have a drawback with dependency pollution reported at https://github.com/robolectric/gradle-android-test-plugin/issues/17 which results in slow esspresso tests compile time and execution time.
build.gradle snippet which combines all
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.10.+'
classpath 'org.robolectric.gradle:gradle-android-test-plugin:0.10.+'
}
}
apply plugin: 'android'
apply plugin: 'android-test'
android {
defaultConfig {
testInstrumentationRunner "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"
}
}
androidTest {
include '**/*Test.class'
exclude '**/espresso/**/*.class'
}
dependencies {
androidTestCompile('junit:junit:4.11')
androidTestCompile('org.robolectric:robolectric:2.3-SNAPSHOT')
androidTestCompile 'com.jakewharton.espresso:espresso:1.1-r2'
}
seperate espresso
An example is shown by https://github.com/stephanenicolas/Quality-Tools-for-Android but it is much outdated and had also some drawbacks. It will recompile
and makes android studio behave strange. It flags application module sources as (root source) of the espresso test module. That works but not intuitive.
build.gradle snippet for espresso module
dependencies {
androidTestCompile 'com.jakewharton.espresso:espresso:1.1-r2'
}
android {
sourceSets {
main {
manifest.srcFile '../AndroidSample/AndroidManifest.xml'
java.srcDirs += ['../AndroidSample/src/main/java']
resources.srcDirs = ['../AndroidSample/res']
res.srcDirs = ['../AndroidSample/res']
}
}
defaultConfig {
testInstrumentationRunner "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"
}
}
spereate robolectric
There exist a plugin https://github.com/novoda/gradle-android-test-plugin which enable us to put robolectric tests in a sperate package. This project
setup works for me great:
- MyProject
|- app (with espresso tests)
|- - build.gradle (app)
|- robolectric (unit tests)
|- - build.gradle (robo)
build.gradle (app + espresso) snippet
dependencies {
androidTestCompile 'com.jakewharton.espresso:espresso:1.1-r2'
}
android {
defaultConfig {
testInstrumentationRunner "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"
}
}
build.gradle (robo) snippet
buildscript {
repositories {
mavenCentral()
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}
dependencies {
classpath 'com.android.tools.build:gradle:0.9.+'
classpath "com.novoda:gradle-android-test-plugin:0.9.8-SNAPSHOT"
}
}
android {
projectUnderTest ':AndroidSample'
}
apply plugin: 'java'
apply plugin: 'android-test'
dependencies {
testCompile 'junit:junit:4.11'
testCompile 'org.mockito:mockito-core:1.9.5'
testCompile 'com.squareup:fest-android:1.0.+')
testCompile ('org.robolectric:robolectric:2.3-SNAPSHOT')
}
There a some pitfall when you try setup this project setup, so just start with a working example: https://github.com/nenick/android-gradle-template
This is unlikely to work out of the box as src/test isn't used automatically.
You'd need to create a test task automatically that compiles this source sets, sets the right dependencies and run it.
We intend to support this in the future but right now you'd need to do this manually.
I tested all the solutions presented here and they all lack of something (version of gradle / gradle plugin not supported, library project not supported, no integration with Android studio, etc). It may not be true in the future but it is today.
The best way I found is to configure the unit tests by yourself. You will need to add a few lines of config to your build.gradle file. Explications are on the following article: http://tryge.com/2013/02/28/android-gradle-build/. Since I'm not the author, I don't think I can copy past the content here directly.
In addition to that article, if you want configure Android Studio to see the unit test folder as a source folder (autocompletion and stuff), you can apply the following little dirty hack and let the IDE think that the unit tests are located in the instrumentationTest folder. Of course, it will mess with your real instrumentation tests so it works only if you don't have any of those.
build.gradle
// the unit test source set as described in the article
sourceSets {
unitTest {
java.srcDir file('src/test/java')
resources.srcDir file('src/test/resources')
}
}
android {
// tell Android studio that the instrumentTest source set is located in the unit test source set
sourceSets {
instrumentTest.setRoot('src/test')
}
}
dependencies {
// your unit test dependencies as described in the article
unitTestCompile files("$project.buildDir/classes/release")
unitTestCompile 'junit:junit:4.11'
unitTestCompile 'com.google.android:android:4.1.1.4'
unitTestCompile 'org.robolectric:robolectric:2.1.1'
// duplicate these dependencies in the instrumentTestCompile scope
// in order to have the integration in Android Studio (autocompletion and stuff)
instrumentTestCompile 'junit:junit:4.11'
instrumentTestCompile 'org.robolectric:robolectric:2.1.1'
}
// the rest of the config as described in the article
Tested with Android Studio 0.2.6 and android gradle plugin 0.5.
Gradle Android Unit Testing Plugin is the best option for me.
Developed by Jake Wharton, I guess it is going to be the next standard (maybe until google releases an out of the box support for Robolectric in Android Studio).
You can import the library by adding in your build.gradle file:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.X.+'
classpath 'com.squareup.gradle:gradle-android-test-plugin:0.9.+'
}
}
...
apply plugin: 'android-test'
...
dependencies {
testCompile 'junit:junit:4.10'
testCompile 'org.robolectric:robolectric:2.1.+'
testCompile 'com.squareup:fest-android:1.0.+'
}
Update: This library has been deprecated since gradle plugin version 0.8
I've tested a lot of scenarios (like http://tryge.com/2013/02/28/android-gradle-build/ and http://www.peterfriese.de/android-testing-with-robolectric/) but only the solution provided by the Robolectric team worked for me. The setup uses instrumented and robolectric tests in one Android project with gradle as build system.
See http://robolectric.org/getting_started/
and the sources on
https://github.com/robolectric/deckard-gradle
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.9.2'
classpath 'org.robolectric.gradle:gradle-android-test-plugin:0.9.4'
}
}
allprojects {
repositories {
mavenCentral()
}
}
apply plugin: 'android'
apply plugin: 'android-test'
android {
packagingOptions {
exclude 'LICENSE.txt'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE'
}
compileSdkVersion 19
buildToolsVersion "19.0.3"
defaultConfig {
minSdkVersion 18
targetSdkVersion 18
versionCode 2
versionName "1.0.0-SNAPSHOT"
testInstrumentationRunner "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"
}
buildTypes {
release {
runProguard false
}
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
res.srcDirs = ['res']
}
androidTest {
setRoot('src/test')
}
}
}
androidTest {
include '**/*Test.class'
exclude '**/espresso/**/*.class'
}
dependencies {
repositories {
mavenCentral()
maven {
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
// Espresso
androidTestCompile files('lib/espresso-1.1.jar', 'lib/testrunner-1.1.jar', 'lib/testrunner-runtime-1.1.jar')
androidTestCompile 'com.google.guava:guava:14.0.1',
'com.squareup.dagger:dagger:1.1.0',
'org.hamcrest:hamcrest-integration:1.1',
'org.hamcrest:hamcrest-core:1.1',
'org.hamcrest:hamcrest-library:1.1'
androidTestCompile('junit:junit:4.11') {
exclude module: 'hamcrest-core'
}
androidTestCompile('org.robolectric:robolectric:2.3-SNAPSHOT') {
exclude module: 'classworlds'
exclude module: 'maven-artifact'
exclude module: 'maven-artifact-manager'
exclude module: 'maven-error-diagnostics'
exclude module: 'maven-model'
exclude module: 'maven-plugin-registry'
exclude module: 'maven-profile'
exclude module: 'maven-project'
exclude module: 'maven-settings'
exclude module: 'nekohtml'
exclude module: 'plexus-container-default'
exclude module: 'plexus-interpolation'
exclude module: 'plexus-utils'
exclude module: 'wagon-file'
exclude module: 'wagon-http-lightweight'
exclude module: 'wagon-http-shared'
exclude module: 'wagon-provider-api'
}
androidTestCompile 'com.squareup:fest-android:1.0.+'
}
apply plugin: 'idea'
idea {
module {
testOutputDir = file('build/test-classes/debug')
}
}