我使用Android Studio 1.1.0的新单元测试支持功能运行了一些旧的测试。
运行gradlew testDebug时,运行测试,但所有需要Context失败的测试都会失败,因为getContext
(AndroidTestCase)/ getInstrumentation.getContext()
(InstrumentationTestCase)都返回null。
我该如何解决这个问题?
以下是我尝试的两种变体:
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);
}
}
和
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);
}
}
这是我的模块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'
}
这里是项目的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()
}
}
编辑:在升级到AS 1.1.0并在设备/模拟器上运行之前,我的测试都有效。
编辑:
Heres 2个失败的InstrumentationTestCase和AndroidTestCase的截图:
答案 0 :(得分:43)
我将这些工作,但没有部署到设备。将测试放在/src/main/test/
文件夹中。
这是更新的例子,我拿了你的例子并在我自己的临时测试项目中测试它们。我通过命令行运行测试:./gradlew clean test
。请在此处阅读更多信息:https://sites.google.com/a/android.com/tools/tech-docs/unit-testing-support。
热门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
来测试Context
和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
来测试您的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
来测试Context
和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);
}
}
经过Google搜索后发现此错误,我相信您的赌注是使用getInstrumentation().getContext().getResources().openRawResource(R.raw.your_res).
或类似内容来测试您的资源。
测试资源:
public class PrintoutPullParserTest extends InstrumentationTestCase {
public void testParsing() throws Exception {
PrintoutPullParser parser = new PrintoutPullParser();
parser.parse(getInstrumentation().getContext().getResources().getXml(R.xml.printer_configuration));
}
}
来源:https://stackoverflow.com/a/8870318/950427和https://stackoverflow.com/a/16763196/950427
测试资源:
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);
}
}
来源:https://stackoverflow.com/a/9820390/950427
获取Context
(一个简单的黑客):
private Context getTestContext() {
try {
Method getTestContext = ServiceTestCase.class.getMethod("getTestContext");
return (Context) getTestContext.invoke(this);
} catch (final Exception exception) {
exception.printStackTrace();
return null;
}
}
来源:https://stackoverflow.com/a/14232913/950427
但是,如果您查看AndroidTestCase
的源代码,看起来您需要自己设置Context
:
来源:http://alvinalexander.com/java/jwarehouse/android/core/java/android/test/AndroidTestCase.java.shtml
答案 1 :(得分:15)
使用Android Testing Support Library,您可以
<Grid>
<local:MusicList x:Name="musicList" />
</Grid>
InstrumentationRegistry.getContext()
InstrumentationRegistry.getTargetContext()
请参阅链接页面的底部,了解如何将Testing Support库添加到项目中。
答案 2 :(得分:10)
以下是设置(单位)仪器测试的最新方法
在 build.gradle 中添加:
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
以及以下依赖项:
// 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();
}
}
答案 3 :(得分:4)
我在尝试使用@taynguyen答案调用SQLite时收到错误,因此代替:
InstrumentationRegistry.getContext()
我用过:
InstrumentationRegistry.getTargetContext()
为了获取我的目标应用程序上下文而不是Instrumentation上下文。
答案 4 :(得分:2)
Context
需要引用扩展Context
的内容,例如Activity
或Application
类。
Context context = new Activity();
另一种方法是使用Robolectric.Application
。
答案 5 :(得分:1)
getInstrumentation().getContext()
现在已被弃用,您应该使用它
InstrumentationRegistry.getInstrumentation().getTargetContext()
您可以在这里找到更多详细信息
androidx.test.InstrumentationRegistry is deprecated