2
votes

Comment utiliser "Discover" pour exécuter des tests dans mon répertoire "tests"?

Utilisation de DJango / Python 3.7. J'ai lu ici - Comment exécuter tout Tests unitaires Python dans un répertoire? que je pourrais utiliser une commande "découvrir" pour trouver des tests dans un répertoire spécifié. Je veux avoir un dossier "tests", alors j'en ai créé un puis j'ai lancé

from django.conf import settings
from django.test import TestCase
from django.core import management


def setup():
    print("setup")
    management.call_command('loaddata', 'test_data.yaml', verbosity=0)


def teardown():
    management.call_command('flush', verbosity=0, interactive=False)


class ModelTest(TestCase):

    # Verify we can correctly calculate the amount of taxes when we are working
    # with a state whose tax rates are defined in our test data
    def test_calculate_tax_rate_for_defined_state(self):
        state = "MN"
        income = 30000
        taxes = IndividualTaxBracket.objects.get_taxes_owed(state, income)
        print(taxes)
        self.assertTrue(taxes > 0, "Failed to calucate taxes owed properly.")

Cela m'est étrange car j'ai un fichier init (vide) ...

XXX

Que dois-je faire d'autre pour que mon répertoire de test soit reconnu?

Edit: Voici le contenu de model_tests.py .. .

(venv) localhost:myproject davea$ ls web/tests/
__init__.py  model_tests.py


4 commentaires

Votre répertoire tests se trouve dans le répertoire web , vous pourriez donc vouloir cd dedans avant d'exécuter votre commande.


Avez-vous oublié un fichier "tests.py" vide en tant que frère du dossier "tests"?


@MarioOrlandi, j'avais un fichier "tests.py" à côté de "tests", ce qui causait des erreurs, alors je suis allé de l'avant et je l'ai supprimé. Cependant, je ne parviens toujours pas à exécuter les tests ou à cibler uniquement ceux de model_tests.py.


Dave, quelques questions s'imposent ... J'ajouterai une réponse pour une meilleure mise en forme du texte ...


4 Réponses :


0
votes

Tout d'abord: avoir un __init__.py n'est pas inhabituel, car __init__.py indique à python que le répertoire est un module; Il est habituel d'avoir un fichier __init__.py vide. J'ai eu la même erreur et je l'ai corrigée en renommant mon répertoire . .


1 commentaires

Pouvez-vous montrer exactement ce que cela signifie? Je suis nouveau sur python.



2
votes

Je pense que vous avez une certaine confusion sur la commande Discover . Selon la documentation.

Unittest prend en charge la découverte de tests simples. Afin d'être compatible avec la découverte de test, tous les fichiers de test doivent être des modules ou des packages (y compris les packages d'espace de noms) importables à partir du répertoire de niveau supérieur du projet (cela signifie que leurs noms de fichiers doivent être valides identifiants).

Cela signifie que tous les fichiers de test doivent être importables à partir du répertoire à partir duquel vous exécutez la commande (répertoire qui contient votre répertoire web ). Assurez-vous que tous les fichiers de test doivent être dans des packages python valides (répertoires contenant __init__.py).

Deuxièmement, vous exécutez la commande python -m unittest discover tests qui est faux. Vous n'êtes pas obligé d'ajouter des tests à la fin. unittests avec la commande Discover prend en charge 4 options. Vous pouvez en savoir plus ici .

J'ai la structure de répertoires suivante.

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

Et j'exécute la commande suivante.

python3 -m unittest discover

Avec les résultats suivants.

 web
    ├── __init__.py
    └── tests
        ├── __init__.py
        └── test_models.py


8 commentaires

J'ai donc lancé "python -m unittest Discover" et j'ai reçu le message "Ran 0 tests in 0.000s". Que dois-je faire / ajouter pour que les tests de mon fichier model_tests.py s'exécutent réellement?


@Dave python découvre en fait les tests uniquement à partir de fichiers spécifiques. le modèle utilisé pour cette découverte est test * .py cela signifie que vos fichiers de test doivent commencer à partir du mot test . Comme test_models.py ou test_views.py . Vous pouvez remplacer ce modèle à l'aide de l'option -p. comme si vous préférez tester à la fin du nom de fichier comme model_tests.py vous pouvez le faire. python -m unittest découvrir -p "* _tests.py" .


J'ai modifié les noms de mes tests selon ce que vous avez recommandé, mais maintenant j'obtiens l'erreur "django.core.exceptions.ImproperlyConfigured: Paramètres demandés, mais les paramètres ne sont pas configurés". Je ne sais pas si cela est lié à ce que vous avez, alors j'ai ouvert une question distincte - stackoverflow.com/questions/55696337/... .


Ah! Alors vous essayez d'exécuter des tests django avec python? Vous ne pouvez pas faire cela très facilement. Je suis surpris de savoir pourquoi vous n'utilisez pas le workflow intégré de django pour exécuter des tests? Cependant, je vous suggère de le faire. depuis les paramètres d'importation de django.conf puis settings.configure () dans le fichier __init__.py de votre package de tests. Mais je soupçonne qu'une autre erreur apparaîtra. Je vous recommande vivement d'utiliser la configuration de test intégrée de django.


Oh, la façon dont Django exécute les tests n'implique pas le fichier "manage.py"? Je suis confus avec tous ces tutoriels.


@Dave Oui, cela implique un fichier manage.py mais il existe des solutions. Je ne sais pas sur quel type de projet vous travaillez exactement. Mais la documentation la plus précise sur les tests dans django est la documentation officielle. Vous pouvez le lire ici .


@Dave Vous devriez utiliser ./manage.py test pour exécuter les tests de votre Django. Cette commande utilise discover () dans le back-end pour les tests de collecte.


Ok, maintenant que j'ai relu votre description de "Discover" et la façon dont Django exécute les tests, j'étais clairement confus quant au moment où la commande unittest-discover devrait être utilisée. Exécuter des tests de manière normale résout les choses.



0
votes

Si un fichier nommé tests.py existe en tant que frère du module tests , cela provoquerait probablement l'erreur ImportError mentionnée, et la suppression de test.py devrait le corriger.

p> Si les tests unitaires ne sont toujours pas découverts, quelques questions s'imposent:

1) le module de test contient-il au moins une classe dérivée de django.test.TestCase?

2) et dans ce cas, cette classe contient-elle au moins une méthode dont le nom commence par "test_"

Veuillez noter que le nom de tout fichier contenant un test unitaire doit commencer par "test ".

Donc model_test.py ne fonctionnera pas; est généralement utilisé pour configurer certains faux modèles, mais les tests unitaires doivent résider ailleurs.

Vous pouvez découvrir et exécuter des tests avec cette commande de gestion:

python manage.py test appname

ou

python manage.py test

Y a-t-il une raison particulière d'utiliser à la place python -m unittest discover ? Je pense que cela pourrait fonctionner non plus, mais vous devrez ensuite démarrer manuellement l'environnement django


2 commentaires

J'ai modifié ma question pour inclure mon fichier model_tests.py. La ligne de classe ressemble à "class ModelTest (TestCase)", donc je "pense" qu'elle hérite de ce que vous avez spécifié mais peut-être qu'il se passe autre chose que je ne sais pas.


@Dave je pense que vous devez renommer model_tests.py pour avoir la moindre chance de découvrir des tests unitaires à l'intérieur. De plus, déplacez setup () dans une méthode de classe nommée setUp (self) et teardown () dans une méthode appelée tearDown (self). J'ai élaboré ma réponse avec quelques indices supplémentaires. Bonne chance ;)



0
votes

Pour compléter ...

Vous connaissez déjà ce formulaire ici :

Les noms de vos tests et fichiers doivent correspondre à un modèle spécifique pour être détectables par discover () .

Mais alors vous avez cette erreur:

"django.core.exceptions.ImproperlyConfigured: Paramètres demandés, mais les paramètres ne sont pas configurés"

Cela signifie que Django n'a pas pu trouver ses paramètres lors de l'exécution de vos tests. Vous pouvez dire où trouver les paramètres à l'aide d'une variable d'environnement:

settings.configure()

Référence: https://docs.djangoproject.com/en/2.2/topics/settings/#designating-the-settings

D'un autre côté ...

Vous devriez exécuter vos tests Django avec

from django.conf import settings

cela recherche automatiquement des tests en utilisant le même mécanisme que discover () , et comme vous exécuteriez une commande Django, vous aurez certains avantages par rapport à l'exécution directe des tests Django.


@Nafees Anwar a demandé: Comment définir la variable d'environnement configure-t-il les paramètres?

Au tout début du fichier model_tests.py , il y a la ligne des paramètres d'importation de django.conf , lors de la création des paramètres LazyObject c ode> instance, Django recherchera cette variable d'environnement. Lisez le code pour plus de détails.

Je publierai ici un extrait de ce code à titre d'illustration.

# django.conf module.
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"


class LazySettings(LazyObject):
    """
    A lazy proxy for either global Django settings or a custom settings object.
    The user can manually configure settings prior to using them. Otherwise,
    Django uses the settings module pointed to by DJANGO_SETTINGS_MODULE.
    """
    def _setup(self, name=None):
        """
        Load the settings module pointed to by the environment variable. This
        is used the first time we need any settings at all, if the user has not
        previously configured the settings manually.
        """
        settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
        if not settings_module:
            desc = ("setting %s" % name) if name else "settings"
            raise ImproperlyConfigured(
                "Requested %s, but settings are not configured. "
                "You must either define the environment variable %s "
                "or call settings.configure() before accessing settings."
                % (desc, ENVIRONMENT_VARIABLE))

        self._wrapped = Settings(settings_module)

Donc, si vous le faites: p >

./manage.py tests

une fois cette variable d'environnement réglée, l'instruction

DJANGO_SETTINGS_MODULE='myproyect.settings' python3 -m unittest discover

échouera avec RuntimeError ('Paramètres déjà configurés.')


2 commentaires

Comment définir la variable d'environnement configurer les paramètres ?


Au tout début du fichier model_tests.py , il y a la ligne des paramètres d'importation de django.conf , lors de la création de l'instance settings LazyObject, django recherchera cette variable d'environnement. Lisez le code pour plus de détails.