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 Réponses :
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 .
.
Pouvez-vous montrer exactement ce que cela signifie? Je suis nouveau sur python.
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
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.
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
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 ;)
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
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.
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.')
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.
Votre répertoire
tests
se trouve dans le répertoireweb
, 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 ...