web-dev-qa-db-fra.com

Tests unitaires Android nécessitant un contexte

J'écris mon premier backend de base de données Android et j'ai du mal à tester un peu la création de ma base de données.

Actuellement, le problème que je rencontre est l'obtention d'un objet Context valide à transmettre à mon implémentation de SQLiteOpenHelper. Existe-t-il un moyen d'obtenir un objet Context dans une classe qui étend TestCase? La solution à laquelle j'ai pensé consiste à instancier une activité dans la méthode d'installation de mon TestCase, puis à affecter le contexte de cette activité à une variable de champ à laquelle mes méthodes de test peuvent accéder ...

Merci pour votre contribution!

Macy

54
Macy Abbey

Vous pouvez essayer de basculer vers AndroidTestCase . En regardant la documentation, il semble qu'il devrait pouvoir vous fournir un contexte valide à transmettre à SQLiteOpenHelper.

Edit: N'oubliez pas que vous devez probablement configurer vos tests dans un "Projet de test Android" dans Eclipse, car les tests essaieront de s'exécuter sur l'émulateur (ou le périphérique réel).

39
Erich Douglass

Si vous exécutez vos tests avec AndroidJUnit4 , vous pouvez utiliser InstrumentationRegistry method pour obtenir un contexte:

InstrumentationRegistry.getTargetContext() - fournit l'application Context de l'application cible.

InstrumentationRegistry.getContext() - fournit la Context du package de cette instrumentation.


Pour AndroidX, utilisez InstrumentationRegistry.getInstrumentation().getTargetContext() ou InstrumentationRegistry.getInstrumentation().getContext().

21
birdy

L'utilisation de la méthode AndroidTestCase:getContext() ne donne qu'un contexte de talon dans mon expérience. Pour mes tests, j'utilise une activité vide dans mon application principale et récupère la Context via celle-ci. J'étends également la classe de suite de tests avec la classe ActivityInstrumentationTestCase2. Semble travailler pour moi.

public class DatabaseTest extends ActivityInstrumentationTestCase2<EmptyActivity>
    EmptyActivity activity;
    Context mContext = null;
    ...
    @Before
    public void setUp() {
        activity = getActivity();
        mContext = activity;
    }
    ... //tests to follow
}

Que font les autres?

4
Tim Kist

Vous pouvez dériver de MockContext et renvoyer par exemple un MockResources sur getResources(), un ContentResolver valide sur getContentResolver(), etc. , quelques tests unitaires.

L'alternative consiste à exécuter par exemple Robolectric qui simule un système d'exploitation Android complet. Celles-ci seraient pour tests du système: son exécution est beaucoup plus lente.

2
Wernight

Vous devez utiliser ApplicationTestCase ou ServiceTestCase.

2
Neil

Étendre AndroidTestCase et appeler AndroidTestCase: getContext () a très bien fonctionné pour que je puisse obtenir Context et l’utiliser avec une base de données SQLite.

Le seul inconvénient est que la base de données créée et/ou utilisée sera la même que celle utilisée par l’application de production, vous voudrez donc probablement utiliser un nom de fichier différent pour les deux applications.

par exemple. 

  public static final String    NOTES_DB      = "notestore.db";
  public  static final String   DEBUG_NOTES_DB = "DEBUG_notestore.db";
1
Ian

Votre test n'est pas un test unitaire !!!

Quand tu as besoin

  • Le contexte
  • Lire ou écrire sur le stockage
  • Réseau d'accès
  • Ou changez la configuration pour tester votre fonction

Vous n'écrivez pas un test unitaire.

Vous devez écrire votre test dans le package androidTest

0
Ehsan

Créez d'abord une classe de test sous (androidTest).

Maintenant, utilisez le code suivant:

public class YourDBTest extends InstrumentationTestCase {

private DBContracts.DatabaseHelper db;
private RenamingDelegatingContext context;

@Override
public void setUp() throws Exception {
    super.setUp();
    context = new RenamingDelegatingContext(getInstrumentation().getTargetContext(), "test_");
    db = new DBContracts.DatabaseHelper(context);
}

@Override
public void tearDown() throws Exception {
    db.close();
    super.tearDown();
}

@Test
public void test1() throws Exception {
    // here is your context
    context = context;
}}
0
lidox