Gordak
Gordak

Reputation: 2070

Instrumented Tests in Android Studio

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:

 @RunWith(AndroidJUnit4.class)
    public class ServerRequestInstrumentationTest {
        @Test
        public void test(){
           LogC.d("Here we go testing !");
        }
    }
@RunWith(Suite.class)
@Suite.SuiteClasses({ServerRequestInstrumentationTest.class})
public class TestSuit {

    public TestSuit(){}
}
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

Upvotes: 2

Views: 5818

Answers (4)

Code-Apprentice
Code-Apprentice

Reputation: 83527

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.

Upvotes: 0

Shyri
Shyri

Reputation: 410

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

Upvotes: 0

Gordak
Gordak

Reputation: 2070

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...

Upvotes: 1

Rich
Rich

Reputation: 1055

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 ;)

Upvotes: 1

Related Questions