I am trying to add an instrumentation test to our project, but it seems that Gradle doesn't properly add the Android JUnit Test Runner to the project's classpath. The test depenencies of my gradle build file looks like this:
testCompile 'junit:junit:4.12'
androidTestCompile 'junit:junit:4.12'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
We are using the latest version of the support library (24.0.0), but the current version of the test runner (JUnit runner) and Espresso use version 23.1.0. To resolve the version conflict, I force the runner (and Espresso) to use the newer version (I understand the implications, but we can't use the older version):
androidTestCompile 'com.android.support:support-v4:24.0.0'
androidTestCompile 'com.android.support:appcompat-v7:24.0.0'
androidTestCompile 'com.android.support:support-v13:24.0.0'
androidTestCompile 'com.android.support:recyclerview-v7:24.0.0'
androidTestCompile 'com.android.support:design:24.0.0'
androidTestCompile 'com.android.support:support-annotations:24.0.0'
and:
configurations.all {
resolutionStrategy {
force 'com.android.support:support-annotations:24.0.0'
}
}
However, for some reason, Gradle doesn't add the runner package (under android.support.test). So
import android.support.test.runner.AndroidJUnit4;
throws an error: cannot resolve symbol 'runner'. Have cleared Android Studio's cache, restarted the IDE, cleared Gradle's cache (both project and global), all with no luck. Does anyone know what's going on?
try adding:
androidTestCompile 'com.android.support.test:rules:0.5'
This is my old question but thought it might help to explain the issue and the solution. The issue was with the name of the debug build variant: if you name your debug build variant anything but debug, make sure to notify Android's Gradle plugin by adding testBuildType "yourDebugBuildVariantName" to your build.gradle script (your app module's build.gradle not the project global) in the android{} section, or rename your debug build variant to just debug. If you have multiple debug build variants, you need to specify one of them on which you'd like to run your tests, like: testBuildType armDebug:
apply plugin: 'com.android.application'
...
android {
testBuildType "myDebug" <-
compileOptions { ... }
sourceSets { ... }
signingConfigs { ... }
}
Even with this explicit config, Gradle occasionally seems to have issues with running instrumentation tests. The best way to workaround this is to rename your debug build variant (the one you run your tests on) to debug if this is a feasible option for you.
Related
Android Studio 2.2.3
Install Android Support Repository - ver. 44.0.0
I setup all as in official site for Espresso:
https://google.github.io/android-testing-support-library/docs/espresso/setup/index.html
I try to write instrumentation test (Espresso) in package androidTest. So I create StringUtilAndroidTest in folder src/androidTest/java/com/mycompany/
My StringUtilAndroidTest code:
#RunWith(AndroidJUnit4.class)
#LargeTest
public class StringUtilAndroidTest {
#Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule(MainActivity.class);
#Test
public void myTest() {
assert(true);
}
}
In my build.gradle:
android.defaultconfig {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
my dependencies:
testCompile 'junit:junit:4.12'
testCompile 'org.hamcrest:hamcrest-library:1.3'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestCompile 'com.android.support.test:testing-support-lib:0.1
But in StringUtilAndroidTest I get compile error:
#RunWith(AndroidJUnit4.class)
Cannot resolve symbol RunWith
Why?
Short answer: add this to your dependencies and you're golden.
androidTestCompile 'junit:junit:4.12'
androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
Long answer:
In the default configuration, an Android Studio project has two different testing "variants": test & androidTest. The former uses the 'src/test/java', and the latter 'src/androidTest/java' (which is your scenario).
There's a big difference between the two: androidTest needs an emulator or a device to run, and test doesn't. This means that test is much faster to run (usually a couple seconds on the IDE), but it doesn't have access to the Android Framework (like Activities, Contexts & etc). On the other hand, androidTest takes much longer to run (not to mention the waiting time for the emulator itself), but it does have the Android framework (since it's running in one).
Since they're two separate variants, you need to declare their dependencies separately as well. testCompile and androidTestCompile each adds that dependency only to their own variant. To have JUnit on both, you have to declare to dependency on both - essentially "repeating" the line.
P.S.: Note that when you use compile, that adds it to all variants, so you don't have to repeat non-test dependencies.
You probably have missed some dependency.
//App's dependencies, including test
compile 'com.android.support:support-annotations:22.2.0'
// Testing-only dependencies
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestCompile 'junit:junit:4.12'
testCompile 'junit:junit:4.12'
Hope this will fix your code.
I am converting all of my tests over to the Testing Support Library. However, when I try to import the LargeTest annotation like this
import android.support.test.filters.LargeTest;
I get Cannot resolve symbol 'LargeTest'. What dependency do I need to add to my gradle file to resolve this error?
Have you gone through this documentation?
You need to add some of these dependencies based on your need.
dependencies {
androidTestCompile 'com.android.support.test:runner:0.4'
// Set this dependency to use JUnit 4 rules
androidTestCompile 'com.android.support.test:rules:0.4'
// Set this dependency to build and run Espresso tests
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
// Set this dependency to build and run UI Automator tests
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
}
And add :
android {
defaultConfig {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
}
The filter annotation lives under the following dependency
androidTestCompile 'com.android.support.test:runner:0.5'
If it's still not working please file a bug.
Edit: The issue is that it was introduced in version 0.5 so you have to update your dependency.
For AndroidX:
import androidx.test.filters.LargeTest
https://developer.android.com/reference/androidx/test/filters/LargeTest
Running tests via Android Studio, Gradle
Espresso:
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
Library:
androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
Runner:
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
Error:A problem occurred configuring project ':application'.
> Conflict with dependency 'com.android.support:support-annotations'. Resolved versions for app and test app differ.
Just remove the androidTestCompile 'com.android.support.test:testing-support-lib:0.1' from your build.gradle. Take a look on example here.
Get comfortable with command-line Gradle. This tool help you find any conflicting dependencies when you run from console that command gradle -q app:dependencies.
Instead of deleting androidTestCompile 'com.android.support.test:testing-support-lib:0.1' from your app's build.gradle file, you can add exclude part like here.
androidTestCompile ('com.android.support.test.espresso:espresso-contrib:2.0') {
exclude module: 'support-annotations'
}
Hope it help.
I have been trying to run simple instrumented tests in Android Studio, without any success.
I followed the guide for Unit Tests and it works fine. Now, I would like to tests components which are difficult to mock.
When I follow the guide on instrumented tests, I end up with dependency errors.
What I did:
Install the Android Testing Support Library (Android Support Repository, rev 17).
Create a directory androidTest in src. Add Java folder + package ending with "test".
Add a simple Test class
#RunWith(AndroidJUnit4.class)
public class ServerRequestInstrumentationTest {
#Test
public void test(){
LogC.d("Here we go testing !");
}
}
Add a simple TestSuit.
#RunWith(Suite.class)
#Suite.SuiteClasses({ServerRequestInstrumentationTest.class})
public class TestSuit {
public TestSuit(){}
}
Modify my gradle file to add dependencies.
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.mydomain.app"
minSdkVersion 9
targetSdkVersion 22
versionCode 28
versionName "2.0.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
lintOptions {
disable 'MissingTranslation'
}
}
}
sourceSets { main { java.srcDirs = ['src/main/java'] } }
}
dependencies {
compile 'com.android.support:support-v4:22.2.0'
compile 'com.android.support:appcompat-v7:22.2.0'
wearApp project(':wear')
compile project(':moreapps')
compile project(':lib_repair')
compile project(':bugreport')
//testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
androidTestCompile 'junit:junit:4.12'
androidTestCompile 'org.hamcrest:hamcrest-library:1.1'
androidTestCompile 'com.android.support.test:runner:0.3'
androidTestCompile 'com.android.support.test:rules:0.3'
}
I just added the line androidTestCompile 'junit:junit:4.12', otherwise the annotation #RunWith(AndroidJUnit4.class) wasn't recognized.
Now when I launch the test, I get one Gradle build error.
Error:Execution failed for task ':app:dexDebugAndroidTest'.
com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command
'/usr/lib/jvm/jdkoracle/bin/java'' finished with non-zero exit value 2
Any suggestion ? Did I miss something about the testing library ?
Thank you
Okay, finally got it working.
After a little search, I found out that the Gradle console output an error :
AGPBI: {"kind":"simple","text":"UNEXPECTED TOP-LEVEL EXCEPTION:","sources":[{}]}
AGPBI: {"kind":"simple","text":"com.android.dex.DexException: Multiple dex files define Lorg/hamcrest/TypeSafeMatcher;","sources":[{}]}
After I changed one line in my gradle build, Gradle built the project successfuly and I was able to run the simple instrumented test.
Line to change:
androidTestCompile 'org.hamcrest:hamcrest-library:1.1'
to
testCompile 'org.hamcrest:hamcrest-library:1.1'
I don't know why Gradle complains in one case and not the other though...
Instrumentation tests are different to Unit Tests. You have to extend your test classes by specific classes. For more information about that take a look at Android Testing Fundamentals. Also you do not need JUnit for Instrumentaion tests.
Furthermore you have to switch your build variants from Unit Tests to Android Instrumentation Tests, as described here Unit testing in android studio
EXAMPLE:
Here an example for an instrumentaion test in android:
public class ExampleITest extends AndroidTestCase {
#Override
public void setUp() throws Exception {
super.setUp();
InputStream is = getContext().getAssets().open("test.xml");
XmlParser parser = new XmlParser(getContext());
parser.parse(is);
...
}
#MediumTest
public void testSomething() throws Exception {
// test some data your parser extracted from the xml file
...
}
}
As you can see, you can access context, etc.
For this test no specific dependencies are necessary in the gradle file.
I haven't heard about Instrumantation tests just with annotions. maybe i should look it up on the web ;)
Althought #Gordark's answer will not throw any error It's not a proper solution if you want to use Hamcrest in your instrumentation tests, it will work just for your local JVM tests.
I found that using 1.3 version of hamcrest-library actually worked, just replace
androidTestCompile 'org.hamcrest:hamcrest-library:1.1'
with
androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
And it should work. I think it's something about conflicting versions of junit and hamcrest. I guess hamcrest 1.1 depends on a version of junit bellow 4.12, and hamcrest 1.3 depends on junit v4.12
Your answer contains a hint to the problem. You state there that Gradle gives an error. This is because one of the other dependencies for androidTestCompile depends on hamcrest. This is called a transitive dependency. It also means that you can completely remove your explicit requirement for hamcrest. Your change adds hamcrest as a dependency for testCompile which is used for unit tests run locally on your development machine rather than on an Android device or emulator. If you aren't making unit tests you don't need this. Even when you do start writing unit tests, you probably don't need an explicit dependency on hamcrest.
While setting up Espresso 2.1 and the latest version of the Android Testing Support Library, I encountered the next Warning upon building:
Confilct with dependency 'com.android.support:support-annotations'.
Resolved versions for app and test app differ
My build.gradle file is:
apply plugin: 'com.android.application'
android {
...
defaultConfig {
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
}
...
}
dependencies {
androidTestCompile 'com.android.support.test:runner:0.2'
androidTestCompile 'com.android.support.test:rules:0.2'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.1'
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.1.0'
}
Actually I found an existing issue:
we built against the old 22.0.0 and didn't upgrade to 22.1.0.
The runner depends on com.android.support:support-annotations:22.0.0 which conflicts with the latest support library release (22.1.0)
I told gradle which version of support-annotations it needs to resolve to by adding the following line to my dependencies list:
androidTestCompile 'com.android.support:support-annotations:22.1.0'
and the warning is gone.
#appoll Here Stephan Linzner added workaround for that.
Above I've added his comment to this issue, which explains solution:
we are aware of the issue. The gist is that the runner depends on com.android.support:support-annotations:22.0.0 which conflicts with the latest support library release (22.1.0). The correct way to solve this right now, is to tell Gradle which version of support-annotations it needs to resolve to.