public class StringUtilsTests extends TestCase {
String message;
#Override
protected void setUp() throws Exception {
super.setUp();
message = "33,333";
}
/**
*
*/
public void testCommaToSpaces() {
String result = StringUtils.commasToSpaces(message);
assertEquals("33 333", result);
}
}
build.gradle :-
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.0.0'
compile 'com.google.android.gms:play-services-plus:7.5.0'
compile 'com.google.android.gms:play-services-ads:7.5.0'
compile 'com.google.android.gms:play-services-maps:7.5.0'
compile 'com.google.android.gms:play-services-gcm:7.5.0'
compile 'com.google.android.gms:play-services-location:7.5.0'
compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.google.code.gson:gson:2.3.1'
// Unit testing dependencies
testCompile 'junit:junit:4.12'
// Set this dependency if you want to use Mockito
testCompile 'org.mockito:mockito-core:1.10.19'
}
testOptions {
unitTests.all {
// All the usual Gradle options.
jvmArgs '-XX:MaxPermSize=256m'
}
}
sourceSets {
unitTest {
java.srcDir file('src/androidTest/java')
}
}
configurations {
unitTestCompile.extendsFrom runtime
unitTestRuntime.extendsFrom unitTestCompile
}
dependencies {
unitTestCompile files("$project.buildDir/results-tests")
}
task unitTest(type: Test, dependsOn: assemble) {
description = "run unit tests"
testClassesDir = project.sourceSets.unitTest.output.classesDir
classpath = project.sourceSets.unitTest.runtimeClasspath
}
check.dependsOn unitTest
I tried lot of things after googling more than a day, but test reports - xml/html are not getting generated. Please kindly guide if anyone has any idea on this.
If i add below line then gradle sync failed.
reports.html.enabled = true
Did you add the line below in your gradle script?
buildTypes {
debug {testCoverageEnabled = TEST_COVERAGE}}
There is an export results option in the test runner. Once the tests have been executed, you can export these results as .html or .xml
It's the right most option.
Click here to see where it is
Related
Hello
While developing an Android AAR module, I encounter the following problem
My AAR module has a few jar dependencies, some of them have resources folder with error localized error messages. For some reason when I create the module AAR I noticed that Android build process exclude the resources folder from the jar dependency. The dependencies folder is an essential part since otherwise the error details are not found.
If something could shed light on the issue, I tried to create additional resources folder under main/resources//messages.properties but it didn't help.
Any help will be appreciated
here is my gradle file
apply plugin: 'com.android.library'
apply plugin: 'jacoco'
allprojects {
repositories {
jcenter()
maven {
url "https://maven.google.com"
}
}
}
buildscript {
repositories {
jcenter()
google()
mavenCentral()
}
dependencies {
classpath 'com.dicedmelon.gradle:jacoco-android:0.1.2'
classpath 'com.android.tools.build:gradle:3.2.1'
}
}
android {
compileSdkVersion 27
buildToolsVersion '26.0.3'
configurations {
javadocDeps
}
defaultConfig {
minSdkVersion 21
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
testCoverageEnabled false
}
}
testOptions {
unitTests.all {
jacoco {
includeNoLocationClasses = true
}
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen {false}
showStandardStreams = true
}
}
unitTests.returnDefaultValues = true
}
lintOptions {
abortOnError false
}
sourceSets {
androidTest {
...
}
test {
}
}
}
//assembleDebug.dependsOn(copyResDirectoryToClasses)
dependencies {
releaseCompile fileTree(include: ['*.jar'], dir: 'libs')
provided 'com.android.support:appcompat-v7:27.1.1'
provided 'org.jetbrains:annotations:16.0.3'
provided 'com.google.code.findbugs:annotations:3.0.1'
provided 'org.codehaus.sonar-plugins:sonar-ant-task:2.2'
provided 'org.jetbrains:annotations-java5:15.0'
provided 'com.google.android:annotations:4.1.1.4'
provided 'com.squareup.okhttp3:okhttp:3.9.1'
provided 'com.squareup.okhttp3:okhttp-urlconnection:3.9.1'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'org.mockito:mockito-core:1.9.5'
androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
androidTestCompile files('../sdkSample/lib/qa_utils.jar')
androidTestCompile 'com.google.android:annotations:4.1.1.4'
javadocDeps 'com.android.support:appcompat-v7:27.1.1'
javadocDeps 'com.squareup.okhttp3:okhttp:3.9.1'
javadocDeps 'com.squareup.okhttp:okhttp-urlconnection:3.9.1'
javadocDeps 'com.google.code.findbugs:annotations:3.0.1'
javadocDeps group: 'org.mozilla', name: 'rhino', version: '1.7.7.1'
javadocDeps group: 'org.jetbrains', name: 'annotations', version: '16.0.3'
testCompile files('../sdkSample/lib/qa_utils.jar')
testCompile 'junit:junit:4.12'
testCompile 'org.json:json:20171018'
testCompile 'com.google.android:annotations:4.1.1.4'
testCompile 'org.testng:testng:6.13.1'
testCompile 'com.squareup.okhttp3:okhttp:3.9.1'
testCompile 'com.squareup.okhttp3:okhttp-urlconnection:3.9.1'
testCompile 'org.robolectric:robolectric:3.8'
androidTestCompile 'com.squareup.okhttp3:okhttp:3.9.1'
androidTestCompile 'com.squareup.okhttp3:okhttp-urlconnection:3.9.1'
testCompile 'org.khronos:opengl-api:gl1.1-android-2.1_r1'
}
gradle.taskGraph.whenReady {
gradle.taskGraph.allTasks.each {
if(it.project == 'sdkSample') {
it.onlyIf { false }
}
}
}
//ignore all test failures - is done temporary, the final solution is test categorization
project.gradle.taskGraph.whenReady {
-> project.tasks.findAll { it.name =~ /connected.+AndroidTest/ ||
it.name == "testDebugUnitTest" ||
it.name =="testReleaseUnitTest" }.each {
it.ignoreFailures = true
}
}
You need to use api instead of provided. You can find more info from here.
As i know aar cant have transitive dependencies. You may try export fat aar or you can give it a try to
implementation 'your.package:your_artifact:your_version' {transitive = true}
PS: Dont use type #aar
Also known as flatDir, because flatDir dependencies DOES NOT resolve transitives)
implementation 'your.package:your_artifact:your_version#aar' {transitive = true}
On the otherhand, you need to convert your project to maven standards. So that, you need a pom.xml file which points transitive dependencies under dependencies tag.
As you experienced jar files cant have resource files either. If you dont need to resource files, just export jar by executing createFullJarRelease task.
If you have to use .aar, you can add other dependencies that library uses in consumer.
I'm facing a weird issue with multidex. I've had my app multidexed for a long time, but lately I can't build it anymore. It started after configuring Kotlin in the project.
The 'run' option in Android Studio works: the app runs successfully in my device. However, if I try the "Build APK" option or run gradlew assembleDebug, the build fails with the usual exception:
Error:The number of method references in a .dex file cannot exceed 64K.
Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html
Error:com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
However, multidex worked correctly before adding Kotlin. I can checkout the commit just before adding Kotlin, build the apk and check there's 3 .dex files, with a method count over 100k total.
Some key details:
Gradle 4.1, with Gradle plugin 3.0.1
Build-tools version 26.0.2
Kotlin version 1.2.0
After proguarding, the app does not need multidex, but I don't really want to proguard for debug compilation, and besides, this should be working.
Here's the complete build.gradle script:
buildscript {
repositories {
mavenCentral()
}
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'idea'
repositories {
mavenCentral()
jcenter()
maven { url "https://maven.google.com" }
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
maven { url 'https://jitpack.io' }
}
idea {
module {
downloadJavadoc = true
downloadSources = true
}
}
// read keystore for app signing
def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = null
if (keystorePropertiesFile.exists()) {
keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
def getDate() {
def date = new Date()
def formattedDate = date.format('yyyy.MM.dd')
return formattedDate
}
def getCustomProguardFiles() {
return fileTree(dir: "proguard", include: ["*.pro"]).asList().toArray()
}
android {
compileSdkVersion 25
buildToolsVersion '26.0.2'
defaultConfig {
minSdkVersion 16
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
applicationId "my.app.id"
multiDexEnabled true
manifestPlaceholders = [
'appAuthRedirectScheme': 'my.app.id'
]
//TODO do not put this into release
resValue "string", "google_client_id", google_appId + ".apps.googleusercontent.com"
resValue "string", "google_auth_redirect_uri", "com.googleusercontent.apps." + google_appId + ":/oauth2redirect"
}
dexOptions {
}
dexOptions {
javaMaxHeapSize "2g"
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
}
signingConfigs {
release {
keyAlias keystoreProperties != null ? keystoreProperties['keyAlias'] : null
keyPassword keystoreProperties != null ? keystoreProperties['keyPassword'] : null
storeFile keystoreProperties != null ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties != null ? keystoreProperties['storePassword'] : null
}
}
lintOptions {
abortOnError false
checkReleaseBuilds false
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt')
proguardFiles getCustomProguardFiles()
testProguardFiles getDefaultProguardFile('proguard-android.txt')
testProguardFiles getCustomProguardFiles()
signingConfig signingConfigs.release
}
debug {
debuggable true
minifyEnabled false
}
}
flavorDimensions "buildType"
productFlavors {
develop {
applicationIdSuffix ""
dimension "buildType"
}
product {
dimension "buildType"
}
ci {
dimension "buildType"
}
}
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "${variant.name}-${variant.versionName}.apk"
}
}
compileOptions.incremental = false
}
dependencies {
/********** DEBUGGING **********/
// Chrome debug bridge
compile 'com.facebook.stetho:stetho:1.5.0'
compile 'com.facebook.stetho:stetho-okhttp3:1.5.0'
// Memory leak debugging
// 1.5.2 held back because of a bug with gradle 3.0
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
androidTestCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
/********** SUPPORT **********/
// Multidex support
compile 'com.android.support:multidex:1.0.2'
// Support libs
compile "com.android.support:appcompat-v7:$libVersions.android.support"
compile "com.android.support:cardview-v7:$libVersions.android.support"
compile "com.android.support:customtabs:$libVersions.android.support"
compile "com.android.support:design:$libVersions.android.support"
compile "com.android.support:gridlayout-v7:$libVersions.android.support"
compile "com.android.support:palette-v7:$libVersions.android.support"
compile "com.android.support:preference-v7:$libVersions.android.support"
compile "com.android.support:recyclerview-v7:$libVersions.android.support"
compile "com.android.support:support-annotations:$libVersions.android.support"
compile "com.android.support:support-v4:$libVersions.android.support"
compile "com.android.support:support-v13:$libVersions.android.support"
// Testing dependencies
// Made explicit to avoid conflicts with other testing libs
androidTestCompile "com.android.support:appcompat-v7:$libVersions.android.support"
androidTestCompile "com.android.support:design:$libVersions.android.support"
androidTestCompile "com.android.support:recyclerview-v7:$libVersions.android.support"
androidTestCompile "com.android.support:support-annotations:$libVersions.android.support"
androidTestCompile "com.android.support:support-v4:$libVersions.android.support"
/********** TESTING **********/
// JUnit
testCompile 'junit:junit:4.12'
// Mockito
testCompile "org.mockito:mockito-core:2.8.47"
// Support testing
androidTestCompile 'com.android.support.test.espresso:espresso-contrib:3.0.0'
androidTestCompile 'com.android.support.test.espresso:espresso-core:3.0.0'
androidTestCompile 'com.android.support.test:rules:1.0.0'
androidTestCompile 'com.android.support.test:runner:1.0.0'
/********** UTILITIES **********/
// HTML parsing
compile 'org.jsoup:jsoup:1.10.2'
// Event bus
compile 'org.greenrobot:eventbus:3.0.0'
// FHIR
compile 'ca.uhn.hapi.fhir:hapi-fhir-android:3.1.0'
compile 'ca.uhn.hapi.fhir:hapi-fhir-structures-dstu3:3.1.0'
// Jobs
compile 'com.evernote:android-job:1.1.11'
// JSON serializing-deserializing
compile 'com.google.code.gson:gson:2.8.1'
// JWT validation
compile 'com.nimbusds:nimbus-jose-jwt:4.41.1'
// Lang utilities
// Used for Levenshtein distance, etc
compile 'org.apache.commons:commons-lang3:3.6'
compile 'org.apache.commons:commons-text:1.1'
// OpenID authentication
compile 'net.openid:appauth:0.7.0'
// QR code scanning
compile 'com.google.zxing:core:3.3.0'
compile 'com.journeyapps:zxing-android-embedded:3.5.0#aar'
// Play Services (for Firebase InstanceID)
compile 'com.google.android.gms:play-services-auth:11.6.0'
// Recurrence processing
compile 'org.dmfs:lib-recur:0.10'
// REST services
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-scalars:2.1.0'
// SQLite ORM
compile 'com.j256.ormlite:ormlite-android:5.0'
// Time and date handling
compile 'com.fatboyindustrial.gson-jodatime-serialisers:gson-jodatime-serialisers:1.6.0'
compile 'joda-time:joda-time:2.9.7'
// View/resource binding
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
compile 'com.jakewharton:butterknife:8.8.1'
/********** VIEWS AND VIEW UTILITIES **********/
// About page with libraries
compile('com.mikepenz:aboutlibraries:5.2.5#aar') {
transitive = true
}
// Calendar views
compile 'com.roomorama:caldroid:3.0.1'
compile 'com.squareup:android-times-square:1.6.4#aar'
// Circular progress "pie" view
// Used for pill picker
compile 'com.github.filippudak.progresspieview:library:1.0.4'
// Dialogs with material style
compile 'com.github.javiersantos:MaterialStyledDialogs:2.0'
// Floating Action Button
compile 'com.getbase:floatingactionbutton:1.9.0'
// GIF ImageView
compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.3'
// Icons
compile 'com.mikepenz:community-material-typeface:1.9.32.2#aar'
compile 'com.mikepenz:google-material-typeface:2.1.2.1#aar'
compile 'com.mikepenz:iconics-core:2.7.1#aar'
// Image loading
compile 'com.squareup.picasso:picasso:2.5.2'
// Intro slides
compile 'com.heinrichreimersoftware:material-intro:1.5.8'
// Material style utilities
compile('com.mikepenz:materialize:0.2.7#aar') {
transitive = true
}
// Picker DialogFragments
compile 'com.code-troopers.betterpickers:library:3.1.0'
// Round image view
compile 'com.makeramen:roundedimageview:1.5.0'
// Tab strip
compile 'com.astuetz:pagerslidingtabstrip:1.0.1'
// Sliding left drawer
compile('com.mikepenz:materialdrawer:4.4.1#aar') {
transitive = true
}
// Recyclerview adapters
compile('com.mikepenz:fastadapter:2.1.5#aar') {
transitive = true
}
compile 'com.mikepenz:fastadapter-commons:2.1.0#aar'
compile 'com.mikepenz:fastadapter-extensions:2.1.0#aar'
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// Schedule step-by-step building
compile 'com.stepstone.stepper:material-stepper:3.3.0'
compile 'com.wdullaer:materialdatetimepicker:3.2.2'
compile 'com.shawnlin:number-picker:2.4.4'
}
apply plugin: 'com.google.gms.google-services'
And the build.gradle of the project:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.2.0'
repositories {
jcenter()
maven { url "https://maven.google.com" }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:3.0.0'
}
ext {
libVersions = [
android: [
support: '25.4.0'
]
]
}
}
It turned out to be a problem with the way I was including HAPI-FHIR. It's a really big library with tons of dependencies, and it probably was collapsing the main dexfile.
In the end, I solved it by replacing:
// FHIR
compile 'ca.uhn.hapi.fhir:hapi-fhir-android:3.1.0'
compile 'ca.uhn.hapi.fhir:hapi-fhir-structures-dstu3:3.1.0'
with:
// FHIR
compile 'ca.uhn.hapi.fhir:hapi-fhir-base:3.1.0#jar'
compile 'ca.uhn.hapi.fhir:hapi-fhir-utilities:3.1.0#jar'
compile 'ca.uhn.hapi.fhir:hapi-fhir-structures-dstu3:3.1.0#jar'
compile 'commons-io:commons-io:2.5'
compile 'org.slf4j:slf4j-api:1.7.25#jar'
commons-io and slf4j are runtime dependencies of HAPI, and when using #jar those dependencies aren't downloaded, so they need to be explicitly declared.
Note: this particular configuration is only valid for my use case, as HAPI has more runtime dependencies, which would need to be added manually as well in case they're needed.
whenever i run a unit test, i get this error when it tries to retrieve a string value from a custom config.xml file.
Background:
The project itself is a library apk project that uses and references another library APK project.
The error occurs when the project itself tries to initiate a new object that is a subclass of a super class contained on the referenced library apk project.
The Issue explained more below
The specific line of code that fails with the error is a static variable defined below:
protected static final String ANDROID_CONFIG_ID = LibraryApplication.getApplication().getString(R.string.api_checkout_config_id_override);
it fails with the following error:
java.lang.NoClassDefFoundError: com/jon/commonlib/R$string
commonLib is the referenced library apk if you are wondering.
Here is my unit test
#RunWith(RobolectricTestRunner.class)
#Config(constants = BuildConfig.class, manifest=Config.NONE)
public class TestSearchShows {
#Test
public void testSearchJsonFile(){
EventsTestHelper testHelper = new EventsTestHelper(RuntimeEnvironment.application);
try {
ShowsList showList = testHelper.getShowList(new SearchEvent());
if(showList.getShows().size() < 0){
Assert.fail("show list is empty");
}
} catch (IOException e) {
e.printStackTrace();
Assert.fail(e.toString());
}
}
}
The EventsTestHelper is the sub class for a super class called NetworkHelper which looks like this:
public abstract class NetworkHelper<T, P, S> implements NetworkConstants {
protected static final String ANDROID_CONFIG_ID = LibraryApplication.getApplication().getString(R.string.api_checkout_config_id_override);
//other stuff ....
}
I use robolectric version 3.0 the latest for runing ,my unit tests.
If i was to run the code live and call and initiate the sub class, it works perfectly fine, no crashes
edit: Here is snippets of my build gradle file below
apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.library'
apply plugin: 'crashlytics'
buildscript {
repositories {
jcenter()
mavenCentral()
maven { url 'http://download.crashlytics.com/maven' }
maven { url 'http://www.testfairy.com/maven' }
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.0'
classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.+'
classpath 'com.crashlytics.tools.gradle:crashlytics-gradle:1.+'
classpath 'com.testfairy.plugins.gradle:testfairy:1.+'
}
}
repositories {
mavenCentral()
maven { url 'http://download.crashlytics.com/maven' }
maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
flatDir {
dirs 'libs'
}
}
android {
compileSdkVersion 19
buildToolsVersion "22.0.1"
def package_namespace = "com.jonney.moduleApp"
defaultConfig {
minSdkVersion 14
testApplicationId "com.jonney.moduleApp"
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
productFlavors {
//testing {
//}
local {
}
mock {
}
qa {
}
//qa4 {
//}
production {
}
}
sourceSets {
local {
res.srcDir 'build-config/local/res'
}
testing {
res.srcDir 'build-config/testing/res'
}
mock {
res.srcDir 'build-config/mock/res'
}
qa {
res.srcDir 'build-config/qa/res'
}
qa4 {
res.srcDir 'build-config/qa4/res'
}
staging {
res.srcDir 'build-config/staging/res'
test.java.srcDirs += 'src/main/java'
}
production {
res.srcDir 'build-config/production/res'
test.java.srcDirs += 'src/main/java'
test.java.srcDirs += "build/generated/source/r/production"
test.java.srcDirs += "build/generated/source/buildConfig/production"
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:19.1.+'
compile 'com.google.code.gson:gson:2.3'
testCompile('org.robolectric:robolectric:3.0') {
exclude group: 'commons-logging', module: 'commons-logging'
exclude group: 'org.apache.httpcomponents', module: 'httpclient'
}
compile 'com.fasterxml.jackson:jackson-parent:2.5'
compile 'com.squareup:otto:1.3.6'
compile 'com.jakewharton:butterknife:6.1.0'
compile 'com.sothree.slidinguppanel:library:3.0.0'
compile 'com.crashlytics.android:crashlytics:1.+'
compile 'com.mcxiaoke.volley:library-aar:1.0.0'
compile "joda-time:joda-time:2.4"
testCompile('junit:junit:4.12') {
exclude module: 'hamcrest'
exclude module: 'hamcrest-core'
}
testCompile 'org.hamcrest:hamcrest-all:1.3'
compile 'com.sothree.slidinguppanel:library:3.0.0'
compile 'com.squareup:otto:1.3.6'
compile 'com.squareup.okhttp:okhttp:2.3.0'
testCompile 'org.apache.maven:maven-ant-tasks:2.1.3'
compile 'com.google.android.gms:play-services:7.0.0'
compile 'com.android.support:multidex:1.0.0'
compile(name: 'commonLib 1.0 1', ext: 'aar')
testCompile(name: 'commonLib-1.0 1', ext: 'aar')
}
edit: i have also tried to manually create a task that copies the r class for each dependency.
afterEvaluate { project ->
android.libraryVariants.each { variant ->
// workaround for missing R class for aar dependencies
def copyTaskName = "copy${variant.name.capitalize()}AppCompat"
def copyTaskNameTwo = "copy${variant.name.capitalize()}commonlib"
task(copyTaskName, type:Copy) {
dependsOn "process${variant.name.capitalize()}Resources"
from { "build/generated/source/r/${variant.dirName}/$package_namespace_path" }
into { "build/generated/source/r/${variant.dirName}/com/jon/commonlib" }
// into { "src/test/java/android/support/v7/appcompat" }
include 'R.java'
filter { line -> line.contains("package ${package_namespace};") ? 'package android.support.v7.appcompat;' : line }
outputs.upToDateWhen { false }
}
task(copyTaskNameTwo, type:Copy) {
dependsOn "process${variant.name.capitalize()}Resources"
from { "build/generated/source/r/${variant.dirName}/$package_namespace_path" }
into { "build/generated/source/r/${variant.dirName}/android/support/v7/appcompat" }
// into { "src/test/java/android/support/v7/appcompat" }
include 'R.java'
filter { line -> line.contains("package ${package_namespace};") ? 'package com.jon.commonlib;' : line }
outputs.upToDateWhen { false }
}
System.out.println("adding ${copyTaskName} build/generated/source/r/${variant.dirName}/$package_namespace_path ")
println("basename = ${variant.baseName}")
println("directory name = ${variant.dirName}")
tasks.getByName("compile${variant.name.capitalize()}UnitTestJava") dependsOn copyTaskName
}
}
Kind regards
jonnney
The project itself is a library apk project that uses and references another library APK project.
For this type of projects exist an already known issue https://github.com/robolectric/robolectric/issues/1796 but you can workaround it.
The base issue is the android/gradle behaviour for library projects which is different compared to application projects. It just ignores to generate R classes from aar dependencies.
To workaround you can provide your own R class which already contains all dependencies R values. Here an example for the appcompat dependency
afterEvaluate { project ->
android.libraryVariants.each { variant ->
// one line for each aar dependency
tasks.getByName("assemble${variant.name.capitalize()}").dependsOn copyAppcompat
}
}
// copy it for each aar dependency and adjust it to your needs
task copyAppcompat(type: Copy) {
// replace the base package with yours (all after /r/debug/) which contains your R.class
from 'build/generated/source/r/debug/com/example/core'.replace("/", File.separator)
// replace the library packages with yours (all after /test/java/) with your aar dependency base package
into 'src/test/java/android/support/v7/appcompat'.replace("/", File.separator)
// also replace the package declaration or you will get compile errors
filter { line -> line.contains('package com.example.core;') ? 'package android.support.v7.appcompat;' : line }
include 'R.java'
}
An example project with your setup can be found at https://github.com/nenick/AndroidStudioAndRobolectric/tree/library-with-aar
Are you including the library in your testing classpath?
dependencies {
androidTestCompile(<reference to commonLib>)
}
I wasn't able to reproduce this in any way, but here are two things that might help.
Try using RobolectricGradleTestRunner instead of RobolectricTestRunner
You shouldn't need to put your other library in testCompile. So I think you can safely remove testCompile(name: 'commonLib-1.0 1', ext: 'aar')
Let me know in the comments if you have any updates after you try the different runner.
When executing ./gradlew clean connectedAndroidTest with the following configuration... I'm getting No tests found
This is my build.gradle:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.14.1'
classpath 'com.github.jcandksolutions.gradle:android-unit-test:2.0.1'
}
}
allprojects {
repositories {
maven { url "http://dl.bintray.com/populov/maven" }
jcenter()
}
}
apply plugin: 'com.android.application'
android {
packagingOptions {
exclude 'LICENSE.txt'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LGP2.1'
exclude 'META-INF/LGPL2.1'
}
compileSdkVersion 21
buildToolsVersion "21.1.0"
lintOptions {
abortOnError false
}
defaultConfig {
applicationId "com.example"
minSdkVersion 9
targetSdkVersion 21
versionCode 2
versionName "0.1"
testInstrumentationRunner "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"
}
buildTypes {
release {
runProguard false
}
}
sourceSets {
androidTest {
setRoot('src/espressoTest')
}
}
}
apply plugin: 'android-unit-test'
dependencies {
// App
compile 'com.android.support:support-v4:21.0.0'
compile 'com.android.support:appcompat-v7:21.0.0'
compile 'com.android.support:gridlayout-v7:18.0.0'
compile 'joda-time:joda-time:2.3'
compile 'com.google.code.gson:gson:2.2.4'
compile 'de.greenrobot:eventbus:2.0.2'
compile 'com.squareup.dagger:dagger:1.1.0'
compile 'com.squareup.dagger:dagger-compiler:1.1.0'
compile 'com.google.android.gms:play-services:6.1.71'
compile 'com.squareup.okhttp:okhttp:2.0.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.0'
compile 'com.squareup.retrofit:retrofit:1.6.1'
compile 'com.squareup.picasso:picasso:2.3.4'
compile 'com.squareup:otto:1.3.5'
compile 'com.google.guava:guava:18.0'
compile 'com.astuetz:pagerslidingtabstrip:1.0.1'
compile 'com.viewpagerindicator:library:2.4.1#aar'
compile 'com.wrapp.floatlabelededittext:library:0.0.3'
compile 'com.daimajia.swipelayout:library:1.0.7#aar'
compile 'com.github.flavienlaurent.datetimepicker:library:0.0.2'
compile 'info.hoang8f:android-segmented:1.0.2'
compile 'com.nineoldandroids:library:2.4.0'
compile 'com.daimajia.easing:library:1.0.0#aar'
compile 'com.daimajia.androidanimations:library:1.1.2#aar'
compile 'com.balysv.materialmenu:material-menu-toolbar:1.4.0'
// 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'
androidTestCompile 'org.hamcrest:hamcrest-integration:1.1'
androidTestCompile 'org.hamcrest:hamcrest-core:1.1'
androidTestCompile 'org.hamcrest:hamcrest-library:1.1'
// Robolectric
testCompile('junit:junit:4.11') {
exclude module: 'hamcrest-core'
}
testCompile files('lib/robolectric-2.4-SNAPSHOT-jar-with-dependencies.jar')
testCompile 'org.mockito:mockito-all:1.9.5'
testCompile 'com.squareup:fest-android:1.0.+'
testCompile 'com.googlecode.catch-exception:catch-exception:1.2.0'
}
tasks.findByName("assembleDebug").dependsOn("testDebugClasses")
This is the class for the tests under src/espressoTest:
package com.example;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import com.betavalue.myvalue.MainActivity;
import com.betavalue.myvalue.R;
import static com.google.android.apps.common.testing.ui.espresso.Espresso.onView;
import static com.google.android.apps.common.testing.ui.espresso.assertion.ViewAssertions.matches;
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withId;
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withText;
#LargeTest
public class MainEspressoTest extends ActivityInstrumentationTestCase2<MainActivity> {
#SuppressWarnings("deprecation")
public MainEspressoTest() {
// This constructor was deprecated - but we want to support lower API levels.
super(MainActivity.class);
}
#Override
public void setUp() throws Exception {
super.setUp();
// Espresso will not launch our activity for us, we must launch it via getActivity().
getActivity();
}
public void testCheckText() {
onView(withId(R.id.text))
.check(matches(withText("Hello Espresso!")));
}
}
And MainActivityis an empty Activity just to try testing.
Any ideas? Is there something on the AndroidManifest.xml I could be missing?
If anyone is having this issue... It just solved automatically when pulling it from my repository again.
It had to do something with Android Studio cache.
With IntelliJ, I could create a directory "test", add some POJO test files and run them through the IDE.
With Android Studio, I can't find a way to do that. I tried to modify the build.gradle, but I always get the class not found exception.
The next step would be to set up a rule that loads some Guice bindings only during test.
My project looks like:
Project
Module
LibraryModule
src
main
java/com/temp/...
test
java/com/temp/TestClass.java
TestClass.java:
package com.temp;
import org.junit.Before;
import org.junit.Test;
public class TestClass {
#Before
public void setup() throws Exception {
}
#Test
public void testSomething() {
//do something
}
}
build.gradle:
sourceSets {
unitTest {
java.srcDir file('src/test/java')
resources.srcDir file('src/test/resources')
}
}
dependencies {
instrumentTestCompile fileTree(dir: 'libs/test', include: '*.jar')
compile fileTree(dir: 'libs', include: '*.jar')
compile 'com.android.support:support-v4:13.0.0'
}
Error I get:
Class not found: "com.temp.TestClass"
When I run the same project in IntelliJ, I don't get any error. Any tips would help, thanks!
Complete answer (based on what I found here: http://tryge.com/2013/02/28/android-gradle-build/)
build.gradle:
sourceSets {
unitTest {
java.srcDir file('src/test/java')
resources.srcDir file('src/test/resources')
}
}
configurations {
unitTestCompile.extendsFrom runtime
unitTestRuntime.extendsFrom unitTestCompile
}
dependencies {
unitTestCompile files("$project.buildDir/classes/release")
}
task unitTest(type: Test, dependsOn: assemble) {
description = "run unit tests"
testClassesDir = project.sourceSets.unitTest.output.classesDir
classpath = project.sourceSets.unitTest.runtimeClasspath
}
check.dependsOn unitTest
dependencies {
unitTestCompile fileTree(dir: 'libs/test', include: '*.jar')
unitTestCompile fileTree(dir: 'libs', include: '*.jar') // redundant, but don't know how to fix it
compile fileTree(dir: 'libs', include: '*.jar')
compile 'com.android.support:support-v4:13.0.0'
}
Then, to add the test bindings for Guice, make your test class extends that:
public class PojoTestCase {
public PojoTestCase() {
Guice.createInjector(new TestBindings()).injectMembers(this);
}
}
And the way to run:
./gradlew unitTest
Also, the test won't run from Android Studio, but I'm fine with that for now.