Certains de mes anciens tests ont été exécutés avec Android Studio 1.1.0. Lors de l'exécution de gradlew testDebug, les tests sont exécutés, mais tous les tests qui nécessitent un contexte échouent parce que getContext
(AndroidTestCase)/getInstrumentation.getContext()
(InstrumentationTestCase) renvoient tous deux null.
Comment puis-je résoudre ça?
Voici deux variantes que j'ai essayées:
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);
}
}
et
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);
}
}
Voici le build.gradle
De mon module:
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'
}
et voici le build.gradle
du projet:
// 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: Mes tests ont tous fonctionné avant la mise à niveau vers AS 1.1.0 et ont fonctionné sur un périphérique/émulateur.
MODIFIER:
Voici 2 captures d'écran d'échec d'InstrumentationTestCase et d'AndroidTestCase:
J'ai fait fonctionner ces sans déployer sur un appareil. Mettez les tests dans le dossier /src/main/test/
.
Voici des exemples plus récents, j'ai pris vos exemples et les ai testés dans mon propre projet de test temporaire. J'ai exécuté les tests via la ligne de commande: ./gradlew clean test
. Veuillez en savoir plus ici: https://sites.google.com/a/Android.com/tools/tech-docs/unit-testing-support .
Haut 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()
}
}
Application 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
pour tester Context
et 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
pour tester votre 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
pour tester Context
et 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);
}
}
Après avoir beaucoup recherché cette erreur sur Google, je pense que votre pari est d'utiliser getInstrumentation().getContext().getResources().openRawResource(R.raw.your_res).
ou quelque chose de similaire afin de tester vos ressources.
Ressources de test:
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 et https://stackoverflow.com/a/16763196/950427
Ressources de test:
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
Obtenir le Context
(un 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
Mais, si vous regardez le code source de AndroidTestCase
, il semble que vous devez définir vous-même un Context
:
Source: http://alvinalexander.com/Java/jwarehouse/Android/core/Java/Android/test/AndroidTestCase.Java.shtml
Avec la Android Testing Support Library , vous pouvez
InstrumentationRegistry.getContext()
InstrumentationRegistry.getTargetContext()
InstrumentationRegistry.getInstrumentation()
Voir le bas de la page liée pour savoir comment ajouter la bibliothèque de support de test à votre projet.
Voici une façon récente de configurer les tests d'instrumentation (unitaires)
Dans votre build.gradle ajoutez:
testInstrumentationRunner "Android.support.test.runner.AndroidJUnitRunner"
et les dépendances suivantes:
// 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();
}
}
Je recevais une erreur lorsque j'essayais d'appeler SQLite en utilisant la réponse @taynguyen, donc au lieu de:
InstrumentationRegistry.getContext()
J'ai utilisé:
InstrumentationRegistry.getTargetContext()
Afin d'obtenir mon contexte d'application cible au lieu du contexte d'instrumentation.
getInstrumentation().getContext()
est maintenant obsolète, vous devez utiliser cette InstrumentationRegistry.getInstrumentation().getTargetContext()
vous pouvez trouver plus de détails ici androidx.test.InstrumentationRegistry est obsolète
Context
doit faire référence à quelque chose qui étend Context
comme une classe Activity
ou Application
.
Context context = new Activity();
Une autre alternative consiste à utiliser Robolectric.Application
.