the_prole
the_prole

Reputation: 8945

How to add instrumented test and unit test source sets to existing Android Studio project

When I create a new Gradle project, I get two additional directories in addition to the main app directory, one for unit testing, and one for instrumented testing e.g.

java
  com.example.myapplication
  com.example.myapplication (androidTest) <--- instrumented testing
  com.example.myapplication (test) <---- unit testing

I guess these two directories basically contain the source sets which Android Studio will use Gradle to build and launch the tests with to a device.

However, I am working with a project which is lacking these two directories. I only have the app source directory.

All tutorials only show how to create tests assuming the two testing directories have been auto generated by Android Studio.

I need to know how to create these source set directories, but its all just magic to me, and I have no idea how to do it.

I guess in the worst case scenario, I can just create a new project, and port my code to it, but I hate doing that, because it's not really a solution, just a lame work-around.

I'm using the Android Gradle plugin, so I think I'm close, but no tomato. Any advice?

Thanks.

Upvotes: 1

Views: 3727

Answers (2)

CoolMind
CoolMind

Reputation: 28793

Add a new Android test. Select Tests view.

enter image description here

You will see all, one or no test packages.

enter image description here

Add one:

enter image description here

enter image description here

Go to your class and press Ctrl + Shift + T. Select Create New Test..., select "JUnit4", press "OK". You will see all available test packages, that you created before.

enter image description here

Make sure you have needed dependencies in build.gradle:

android {
    defaultConfig {
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

dependencies {
    androidTestImplementation 'androidx.test:runner:1.3.0'
    androidTestImplementation 'androidx.test:rules:1.3.0'

Upvotes: 2

the_prole
the_prole

Reputation: 8945

CommonsWare is correct. You just have to create the directory androidTest and change the configuration in the build.gradle (roughly speaking).

  1. Go to to Project view
  2. Right click on on src
  3. Select View in Terminal context option
  4. Do ls in src directory
  5. Do mkdir androidTest and mkdir main and move com to main

the go to build.gradle and replace src

sourceSets {
    main {
        manifest.srcFile 'AndroidManifest.xml'
        java.srcDirs = ['src']
        resources.srcDirs = ['src']
        aidl.srcDirs = ['src']
        res.srcDirs = ['res']
        assets.srcDirs = ['assets']
    }

    // ...
 }

with src/main (and possibly set the root on androidTest as well I guess)

sourceSets {
    main {
        manifest.srcFile 'AndroidManifest.xml'
        java.srcDirs = ['src/main']
        resources.srcDirs = ['src/main']
        aidl.srcDirs = ['src/main']
        res.srcDirs = ['res']
        assets.srcDirs = ['assets']
    }

    androidTest {
        java.srcDirs = ['src/androidTest/java']
    }
    androidTest.setRoot('src/androidTest')

    // ...
}

then entire source set block will look like this for me at least

sourceSets {
    main {
        manifest.srcFile 'AndroidManifest.xml'
        java.srcDirs = ['src/main']
        resources.srcDirs = ['src/main']
        aidl.srcDirs = ['src/main']
        res.srcDirs = ['res']
        assets.srcDirs = ['assets']
    }

    androidTest {
        java.srcDirs = ['src/androidTest/java']
    }
    androidTest.setRoot('src/androidTest')

    debug.setRoot('build-types/debug')
    release.setRoot('build-types/release')
}

the finally remember to add default runner if not included already so this

defaultConfig {
    applicationId "com.slacorp.myApp"
    minSdkVersion 19
    targetSdkVersion 26
    versionCode 190
    versionName "23.5"
}

becomes this

defaultConfig {
    applicationId "com.slacorp.myApp"
    minSdkVersion 19
    targetSdkVersion 26
    versionCode 190
    versionName "23.5"

    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

then add dependencies so this

dependencies {
    implementation project(':lib-android-common-ui')
    implementation project(':android-lite')
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation project(':lib-j-rci')
}

becomes this

dependencies {
    implementation project(':lib-android-common-ui')
    implementation project(':android-lite')
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation project(':lib-j-rci')

    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

}

and then sync Gradle, then add a test class with imports

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.assertEquals;

@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {

    @Test
    public  void useAppContext() throws Exception {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();
        assertEquals("foo", appContext.getPackageName());
    }
}

if that does not work do file > sync with file system and file > invalidate and restart

Upvotes: 2

Related Questions