Android Studio project setup for Espresso tests

2019-08-04 02:35发布

问题:

About a week ago I asked this question

Why is library module android.support.test not visible in add dependency

After much head scratching and project setup morphing I discovered that this app/build.gradle dependency configuration gets me so much further than ever before in that at least the project compiles but does not build when attempting to run:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion '22.0.1'

    defaultConfig {
        applicationId "com.my.package.name"
        minSdkVersion 8
        targetSdkVersion 22
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
    sourceSets { main { java.srcDirs = ['src/main/java', 'src/androidTest/java'] } }

    packagingOptions {
        exclude 'LICENSE.txt'
    }

}

dependencies {
    compile 'com.android.support:appcompat-v7:22.1.0'
    compile 'com.android.support:support-v4:22.1.0'
    compile 'com.android.support.test.espresso:espresso-core:2.1'
    compile 'com.android.support.test:testing-support-lib:0.1'
}

Notice compile instead of androidTestCompile on the testing support dependencies. Using androidTestCompile results in the problems noted in my previous question identified above.

Also notice the two srcDirs in the sourceSets declaration. That declaration was automatically set when I manually created the androidTest/java directory. Should this be declared differently?

Also too, getDefaultProguardFile is underlined in the ide with the tool tip "cannot resolve symbol 'getDefaultProguardFile'". In case that is crucial.

This new revelation, switching androidTestCompile to compile, leads me to believe there is something wrong with the way I set up the project structure for the unit test. Here is a picture of my project structure:

I should mention that this project/module structure was automatically created when migrating from Eclipse. By the icon decorations it looks like it at least recognizes my test class as a test class.

But now I am stuck at this error:

Error:Execution failed for task ':mymodule:dexDebug'. com.android.ide.common.internal.LoggedErrorException: Failed to run command: C:\Users\myuser\AppData\Local\Android\sdk\build-tools\22.0.1\dx.bat --dex --no-optimize --output C:\Users\myuser\AndroidstudioProjects\myproject\mymodule\build\intermediates\dex\debug --input-list=C:\Users\myuser\AndroidstudioProjects\myproject\mymodule\build\intermediates\tmp\dex\debug\inputList.txt Error Code: 2 Output: UNEXPECTED TOP-LEVEL EXCEPTION: com.android.dex.DexException: Multiple dex files define Landroid/support/test/BuildConfig; at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:596) at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:554) at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:535) at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:171) at com.android.dx.merge.DexMerger.merge(DexMerger.java:189) at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:454) at com.android.dx.command.dexer.Main.runMonoDex(Main.java:303) at com.android.dx.command.dexer.Main.run(Main.java:246) at com.android.dx.command.dexer.Main.main(Main.java:215) at com.android.dx.command.Main.main(Main.java:106)

Not sure if this is coming from my project setup or if it is coming from the libraries due to using compile on the support.test libraries.

Any advice on why androidTestCompile doesn't work is appreciated.

Also I just 2 days ago took all the latest updates from SDK Manager to 22.0.1 to no avail.

Another thing I noticed is the only jar I seem to find containing package com.google.common.* is in the espresso library. (com.google.common.* is a dependency of the testing libraries.) But when I inspect the espresso library jar with winzip all of the com.google.common.* package folder structure is there but there are no .class files in the package folders nor subfolders. Just mentioning that in case it lends a clue. Perhaps it is somewhere else also that I had missed.

Thanks!

Edit:

my source sets now look like this

sourceSets {
    main {
        java.srcDirs = ['src/main/java']
     }
}

and dependencies

dependencies {
    compile 'com.android.support:appcompat-v7:22.1.0'
    compile 'com.android.support:support-v4:22.1.0'
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.1'
    androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
    androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.0'
}

I still get can't resolve android.support.test in my test class (test is colored red on these lines):

import android.support.test.InstrumentationRegistry;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard;
import static android.support.test.espresso.action.ViewActions.typeText;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;

shouldn't I see a testing-support, espresso-core and espresso-contrib in my External libraries?

回答1:

Below is my working Espresso gradle setup based on Android Studio 1.1.0 + Espresso 2.0 + Support Library v11 + gradle environment. It looks likely that you missed androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.0' library.

dependencies {
    // ...
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
    androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
    androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.0'
}

android {
    defaultConfig {
        minSdkVersion 10
        targetSdkVersion 21
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    sourceSets {
        packagingOptions {
            //...
            exclude 'META-INF/LICENSE.txt'
            exclude 'LICENSE.txt'
        }
    }
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src/main/java']
            res.srcDirs = ['res']
        }
    }
}

About the directory, yes. just maintain androidTest and main under src folder. But, your setting does not make IDE to recognize androidTest folder as a test project folder. For that, two projects with same package name causes multi dex error I think. Use androidTestCompile to espresso-related lines in gradle dependencies and clean/rebuild project.

Note that you have to set all referenced projects gradle to same testInstrumentationRunner.

I also spent times to make it work. I wrote Korean tutorial to setup and run Espresso. Sorry about the language but screenshots might be helpful or you can try Google translate to read it.

EDIT. APPENDED BELOW

I thought why your IDE did not show green color in androidTest folder (means Test Project), and found your gradle setup seems to be wrong.

The line { main { java.srcDirs = ['src/main/java', 'src/androidTest/java'] } } make IDE to recognize androidTest is a Project folder not Test Project folder. remove second one. androidTest will be automatically recognized as a Test Project.