I got some of my old tests running with Android Studio 1.1.0's new unit test support feature.
When running gradlew testDebug the tests are run, but all of the tests that require a Context fail because getContext
(AndroidTestCase) / getInstrumentation.getContext()
(InstrumentationTestCase) both return null.
How can I solve this?
Here's two variants I've tried:
import android.content.Context;
import android.test.InstrumentationTestCase;
public class TestTest extends InstrumentationTestCase {
Context context;
public void setUp() throws Exception {
super.setUp();
context = getInstrumentation().getContext();
assertNotNull(context);
}
public void testSomething() {
assertEquals(false, true);
}
}
and
import android.content.Context;
import android.test.AndroidTestCase;
public class TestTest extends AndroidTestCase {
Context context;
public void setUp() throws Exception {
super.setUp();
context = getContext();
assertNotNull(context);
}
public void testSomething() {
assertEquals(false, true);
}
}
This is my module's build.gradle
:
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.0"
testOptions {
unitTests.returnDefaultValues = true
}
defaultConfig {
applicationId "com.example.test.penistest"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
testCompile 'junit:junit:4.12'
}
and here the build.gradle
for the project:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
EDIT: My tests all worked before upgrading to AS 1.1.0 and ran on a device / emulator.
EDIT:
Heres 2 screenshots of failing InstrumentationTestCase and AndroidTestCase:
I got these working without deploying to a device. Put the tests in the /src/main/test/
folder.
Here are newer examples, I took your examples and tested them in my own temporary test project. I ran the tests via command line: ./gradlew clean test
. Please read more here: https://sites.google.com/a/android.com/tools/tech-docs/unit-testing-support.
Top build.gradle
:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
App build.gradle
:
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.0"
defaultConfig {
applicationId "com.test"
minSdkVersion 9
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
testOptions { // <-- You need this
unitTests {
returnDefaultValues = true
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
testCompile 'junit:junit:4.12' // <-- You need this
}
InstrumentationTestCaseTest
to test Context
and Assertions
.
import android.content.Context;
import android.test.InstrumentationTestCase;
import android.test.mock.MockContext;
public class InstrumentationTestCaseTest extends InstrumentationTestCase {
Context context;
public void setUp() throws Exception {
super.setUp();
context = new MockContext();
assertNotNull(context);
}
public void testSomething() {
assertEquals(false, true);
}
}
ActivityTestCase
to test your Resources
.
import android.content.Context;
import android.content.res.Resources;
import android.test.ActivityTestCase;
public class ActivityTestCaseTest extends ActivityTestCase {
public void testFoo() {
Context testContext = getInstrumentation().getContext();
Resources testRes = testContext.getResources();
assertNotNull(testRes);
assertNotNull(testRes.getString(R.string.app_name));
}
}
AndroidTestCase
to test Context
and Assertions
.
import android.content.Context;
import android.test.AndroidTestCase;
import android.test.mock.MockContext;
public class AndroidTestCaseTest extends AndroidTestCase {
Context context;
public void setUp() throws Exception {
super.setUp();
context = new MockContext();
setContext(context);
assertNotNull(context);
}
// Fake failed test
public void testSomething() {
assertEquals(false, true);
}
}
After Googling a lot bout this error, I believe your bet is to use getInstrumentation().getContext().getResources().openRawResource(R.raw.your_res).
or something similar in order to test your resources.
Test Resources:
public class PrintoutPullParserTest extends InstrumentationTestCase {
public void testParsing() throws Exception {
PrintoutPullParser parser = new PrintoutPullParser();
parser.parse(getInstrumentation().getContext().getResources().getXml(R.xml.printer_configuration));
}
}
Source: https://stackoverflow.com/a/8870318/950427 and https://stackoverflow.com/a/16763196/950427
Test Resources:
public class Test extends ActivityTestCase {
public void testFoo() {
// .. test project environment
Context testContext = getInstrumentation().getContext();
Resources testRes = testContext.getResources();
InputStream ts = testRes.openRawResource(R.raw.your_res);
assertNotNull(testRes);
}
}
Source: https://stackoverflow.com/a/9820390/950427
Getting the Context
(a simple hack):
private Context getTestContext() {
try {
Method getTestContext = ServiceTestCase.class.getMethod("getTestContext");
return (Context) getTestContext.invoke(this);
} catch (final Exception exception) {
exception.printStackTrace();
return null;
}
}
Source: https://stackoverflow.com/a/14232913/950427
But, if you look a the source code of AndroidTestCase
, it looks like you need to set a Context
yourself:
Source: http://alvinalexander.com/java/jwarehouse/android/core/java/android/test/AndroidTestCase.java.shtml
With the Android Testing Support Library, you can
InstrumentationRegistry.getContext()
InstrumentationRegistry.getTargetContext()
InstrumentationRegistry.getInstrumentation()
See the bottom of the linked page for how to add Testing Support library to your project.
Here is a recent way to setup (unit) instrumentation tests
In your build.gradle add:
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
and the following dependencies:
// Instrumentation tests
androidTestImplementation "com.android.support.test:runner:$supportTestRunnerVersion"
// To use assertThat syntax
androidTestImplementation "org.assertj:assertj-core:$assertJVersion"
public class Example {
public Object doSomething() {
// Context is used here
}
}
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(AndroidJUnit4.class)
public class ExampleTest {
private Context context;
@Before
public void setUp() {
// In case you need the context in your test
context = InstrumentationRegistry.getTargetContext();
}
@Test
public void doSomething() {
Example example = new Example();
assertThat(example.doSomething()).isNotNull();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With