web-dev-qa-db-fra.com

Obtention du contexte dans AndroidTestCase ou InstrumentationTestCase dans Android Fonction de test d'unité de studio

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:

enter image description here

enter image description here

22
asco

Mise à jour - Veuillez utiliser Espresso pour écrire des tests d'instrumentation

Exemples plus récents:

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
}

Tests de base:

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

Googler les anciens exemples:

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.

Utilisation d'InstrumentationTestCase:

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

Utilisation d'ActivityTestCase:

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

Utilisation d'AndroidTestCase:

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

43
Jared Burrows

Avec la Android Testing Support Library , vous pouvez

  • obtenir le contexte apk de test avec InstrumentationRegistry.getContext()
  • obtenir le contexte apk de l'application avec InstrumentationRegistry.getTargetContext()
  • obtenir l'Instrumentation avec InstrumentationRegistry.getInstrumentation()

Voir le bas de la page liée pour savoir comment ajouter la bibliothèque de support de test à votre projet.

17
taynguyen

Voici une façon récente de configurer les tests d'instrumentation (unitaires)

Installer

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"

Exemple de classe

public class Example {

    public Object doSomething() {
        // Context is used here
    }

}

Exemple de test

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

}

Documentation

11
JJD

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.

4
Dev D

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

1
ilatyphi95

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.

1
TTransmit