Android project with Robolectric and Gradle (Android studio) - android

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')
}
}

Related

Gradle duplicate entry error: META-INF/MANIFEST.MF (Or how to delete a file from jar)

I've cloned a github repository because I wanted to study the code, but when I tried to build it in Android Studio, I ran into some trouble.
After adding the google maven repository (as prompted by Android Studio) and updating both the Gradle Plugin Version and the Grade Version (to 3.5.2 and to 5.4.1, respectively), the build fails because of the following error:
Cause: duplicate entry: META-INF/MANIFEST.MF
And this, to be more specific:
Caused by: java.util.zip.ZipException: duplicate entry: META-INF/MANIFEST.MF
Here is my project level build.gradle file:
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
maven {
url 'https://maven.google.com'
}
}
}
Here's my module build.gradle file (before trying anything):
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion '28.0.3'
defaultConfig {
applicationId "com.thelittlenaruto.supportdesignexample"
minSdkVersion 11
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
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:22.2.1')
implementation ('com.android.support:design:22.2.1')
implementation 'com.github.frankiesardo:linearlistview:1.0.1#aar'
}
Here's what I've tried so far:
Adding the following to the android section of my module build.gradle file:
sourceSets {
main{
java{
exclude '**/META-INF/MANIFEST'
exclude '**/META-INF/MANIFEST.MF'
exclude 'META-INF/MANIFEST'
exclude 'META-INF/MANIFEST.MF'
exclude '!META-INF/MANIFEST.MF'
}
}
}
Adding this:
sourceSets.main.res.filter.exclude 'META-INF/MANIFEST'
sourceSets.main.res.filter.exclude 'META-INF/MANIFEST.MF'
Also this:
packagingOptions {
apply plugin: 'project-report'
exclude '**/META-INF/MANIFEST'
exclude '**/META-INF/MANIFEST.MF'
exclude 'META-INF/MANIFEST'
exclude 'META-INF/MANIFEST.MF'
exclude '!META-INF/MANIFEST.MF'
}
And this:
packagingOptions {
pickFirst '**/META-INF/MANIFEST'
pickFirst '**/META-INF/MANIFEST.MF'
pickFirst 'META-INF/MANIFEST'
pickFirst 'META-INF/MANIFEST.MF'
pickFirst '!META-INF/MANIFEST.MF'
}
This:
aaptOptions {
ignoreAssetsPattern "!META-INF/MANIFEST.MF"
ignoreAssetsPattern "META-INF/MANIFEST.MF"
}
I think I've tried mostly everything in this question:
How to exclude certain files from Android Studio gradle builds?
Nothing worked.
After searching for a solution, I think the problem is that I have duplicated dependencies. So I've tried the following:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation ('com.android.support:appcompat-v7:22.2.1'){
exclude module: 'support-v4'
}
implementation ('com.android.support:design:22.2.1')
implementation 'com.github.frankiesardo:linearlistview:1.0.1#aar'
}
And this:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation ('com.android.support:design:22.2.1'){
exclude module: 'support-v7'
}
implementation 'com.github.frankiesardo:linearlistview:1.0.1#aar'
}
I still get the same error.
What am I doing wrong?
As Rajen Raiyarela said, go to File->Project Structure->Project->Android Gradle Plugin Version and downgrade it from 3.5.2 to 3.5.1.
Set project dependencies to:
classpath 'com.android.tools.build:gradle:3.5.3'
or latest one.
Note: by doing this, my problem has been resolved.
This issue is happening because of duplicate dependencies.
Check for multiple dependencies in the Gradle app.
Either package it once or not at all:
android {
packagingOptions {
pickFirst "META-INF/MANIFEST.MF"
// exclude "META-INF/MANIFEST.MF"
}
}
as #rubo77 says and after my confirmation:
Latest solution
Upgrade gradle version
eg:
from 3.5.2 to 3.5.3
from 3.5.2 to 3.5.4
Obsolete solution:
downgrade from 3.5.2 to 3.5.1
my choice is : upgrade from 3.5.2 to 3.5.4
build.gradle:
dependencies {
// classpath 'com.android.tools.build:gradle:3.5.2'
// classpath 'com.android.tools.build:gradle:3.5.3'
classpath 'com.android.tools.build:gradle:3.5.4'
}

How can I generate a lint-results.xml file when building my project in Android studio?

I would like to generate a lint-results.xml file when building my project in Android studio. I need to be able to do this in order to use the following: https://github.com/KeepSafe/android-resource-remover
I have also tried building the project from the command line but I get the following error:
FAILURE: Build failed with an exception.
What went wrong:
Task 'lint' not found in root project 'client-android'. Some candidates are: 'init'.
Try:
Run gradlew tasks to get a list of available tasks. Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
Here are my gradle files:
apply plugin: 'com.android.application'
apply plugin: 'robolectric'
apply plugin: 'idea'
apply plugin: 'bugsnag'
android {
packagingOptions {
exclude 'LICENSE.txt'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE'
}
lintOptions {
// set to true to turn off analysis progress reporting by lint
quiet true
// if true, stop the gradle build if errors are found
abortOnError false
// if true, only report errors
ignoreWarnings true
}
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.mango.android"
minSdkVersion 14
targetSdkVersion 21
testInstrumentationRunner "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"
}
buildTypes {
release {
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
androidTest {
setRoot('src/test')
}
}
}
robolectric {
include '**/*Test.class'
}
dependencies {
repositories {
mavenCentral()
}
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.bugsnag:bugsnag-android:+'
compile 'com.android.support:appcompat-v7:21.0.3'
compile 'com.android.support:recyclerview-v7:+'
compile files('libs/android-sqlite-asset-helper.jar')
compile('com.google.inject:guice:4.0-beta:no_aop') { exclude module: 'asm' }
compile('org.roboguice:roboguice:2.0') { exclude module: 'asm' }
compile 'com.github.nirhart:parallaxscroll:1.0' // For parallax views
androidTestCompile 'junit:junit:4.11'
androidTestCompile files('libs/android-sqlite-asset-helper.jar')
androidTestCompile('org.robolectric:robolectric:2.4') {
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.google.android:android:4.1.1.4'
androidTestCompile 'org.mockito:mockito-core:1.9.5'
compile 'com.google.android.gms:play-services:6.5.87'
}
idea {
module {
testOutputDir = file('build/test-classes')
}
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.bugsnag:bugsnag-android-gradle-plugin:+'
}
}
// 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:1.0.0'
classpath 'org.robolectric:robolectric-gradle-plugin:0.14.0'
}
}
allprojects {
repositories {
jcenter()
mavenCentral()
}
}
This is how you can export Lint XML in Android Studio 1.3:
At top, click "Analyze"
Select "Inspect Code"
Click OK.
An Inspection panel should open at the bottom (if not, you should be able to click on "Inspection" at the bottom left to open this).
Select "Android Lint" from the list so that it is highlighted.
Click the icon with the green up arrow (second from bottom left) to Export.
Select XML format, and choose the folder you want to save the results to.
I'm not sure if Android Studio has always included Lint, or if Android Studio began including Lint at some later date. You may wish to go to Help -> About to check which version you are running. If you are running an older version, go to Help -> "Check for Updates" to update Android Studio.
Simply try this (on Windows 10) in your project folder cmd line:
./gradlew lintRelease

Roboelectric issues with new gradle and android sdk versions

I used to be able to use roboelectric with gradle just fine until recently. I keep getting an error Error:(6, 17) error: package org.junit does not exist. I'm not quite sure and have dug into this quite a bit.
Below is my project build.gradle:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
}
}
allprojects {
repositories {
mavenCentral()
jcenter()
}
}
Below is my app build.gradle:
repositories {
mavenCentral()
jcenter()
}
apply plugin: 'com.android.application'
android {
...
sourceSets {
androidTest.setRoot('src/test')
}
}
dependencies {
...
// Testing
compile project(':core')
testCompile 'org.robolectric:robolectric:2.4'
testCompile 'junit:junit:4.+'
testCompile 'org.easytesting:fest:1.0.16'
testCompile 'com.squareup:fest-android:1.0.8'
}
my core project build.gradle:
apply plugin: 'java'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:2.4'
}
I have read the below regarding this and nothing here has worked for me:
https://www.bignerdranch.com/blog/all-in-together-android-studio-gradle-and-robolectric/ - the android studio plugin that is to be used crashes on newer android studio versions.
https://www.bignerdranch.com/blog/triumph-android-studio-1-2-sneaks-in-full-testing-support/ - this simply doesn't solve the problem. It cannot find org.junit.
https://discuss.gradle.org/t/why-cant-my-simplest-one-line-build-gradle-compile-tests-with-junit-jar/1868
Can anybody point me in the right direction for this? Why is it not able to detect org.junit from the build.gradle?
You have to set the build variant test artifact to Unit Tests.
I no longer needed the "core" project, so I deleted it. My build.gradle for my app looks like this:
repositories {
jcenter()
}
apply plugin: 'com.android.application'
android {
...
sourceSets {
androidTest.setRoot('src/test')
}
}
dependencies {
...
// Testing
testCompile 'junit:junit:4.12'
testCompile 'org.easytesting:fest:1.0.16'
testCompile 'com.squareup:fest-android:1.0.8'
testCompile('org.robolectric:robolectric:3.0-rc2') {
exclude group: 'commons-logging', module: 'commons-logging'
exclude group: 'org.apache.httpcomponents', module: 'httpclient'
}
}
last day i am also facing the problem.Atlast i got the solution.
The error is due to you created the java folder for your test class as java folder which appear blue color in android studio.Actually you need it in green color
For testing you just need to create folder with java name,everything else will do by android studio itself.
for removing java folder dependency you can remove
sourceSets {
androidTest.setRoot('src/test')
}
code from the build.gradle
then everything will work fine

Roboelectric and Android Studio

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/

Android Gradle DexException: Multiple dex files define Lorg/hamcrest/Description

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

Categories

Resources