L'exécution de unittest avec test type de structure de répertoire
La très commune de la structure de répertoire, même pour un simple module Python semble être de séparer les tests unitaires dans leur propre test
répertoire:
new_project/
antigravity/
antigravity.py
test/
test_antigravity.py
setup.py
etc.
voir, par exemple, ce Projet de Python howto.
Ma question est simple Quelle est la manière habituelle de réellement exécuter les tests? Je suppose que c'est évident pour tout le monde sauf moi, mais vous ne pouvez pas exécuter python test_antigravity.py
à partir du répertoire test comme sa import antigravity
échouera car le module n'est pas sur le chemin.
Je sais que je pourrais modifier PYTHONPATH et d'autres le chemin de recherche liés trucs, mais je ne peux pas croire que c'est la façon la plus simple - c'est très bien si vous êtes le développeur, mais pas réaliste de s'attendre à ce que vos utilisateurs à utiliser si ils veulent juste pour vérifier les tests sont de passage.
L'autre alternative, c'est juste pour copier le fichier de test dans l'autre répertoire, mais il semble un peu stupide et rate le point de les avoir dans un répertoire distinct pour commencer.
Donc, si vous aviez téléchargé la source de mon nouveau projet, comment voulez-vous exécuter les tests unitaires? Je préfère une réponse qui s'permettez-moi de dire à mes utilisateurs: "Pour exécuter les tests unitaires ne X."
- La bonne solution lorsque vous avez besoin de définir le chemin de recherche est de... définir le chemin de recherche. Quel type de solution que vous l'espériez?
- une autre meilleure solution est d'utiliser le
unittest
interface de ligne de commande comme décrit dans mon réponse ci-dessous de sorte que vous n'avez pas à ajouter le répertoire du chemin. - Même ici. J'ai juste lancé sur l'écriture de mes premiers tests unitaires pour un petit projet de Python et a pris plusieurs jours à essayer de raisonner avec le fait que je ne peux pas facilement exécuter un test tout en gardant mes sources dans un répertoire src et de tests dans un répertoire de test, apparemment avec un test de cadres. Je vais finalement accepter les choses, de trouver un moyen; mais cela a été très frustrant introduction. (Et je suis un test d'unité de vétéran à l'extérieur de Python.)
Vous devez vous connecter pour publier un commentaire.
La meilleure solution à mon avis est d'utiliser le
unittest
interface de ligne de commande qui va ajouter le répertoire à lasys.path
de sorte que vous n'avez pas à (fait dans leTestLoader
classe).Par exemple pour une structure de répertoire comme ceci:
Il vous suffit d'exécuter:
Pour une structure de répertoire comme la vôtre:
Et dans les modules de test à l'intérieur de la
test
package, vous pouvez importer lesantigravity
et de ses modules, comme d'habitude:De l'exécution d'un seul module de test:
Pour exécuter un seul module de test, dans ce cas
test_antigravity.py
:Juste référence le module de test de la même manière que vous l'importer.
De l'exécution d'un seul cas de test ou de la méthode de test:
Aussi, vous pouvez exécuter une seule
TestCase
ou une seule méthode de test:L'exécution de tous les tests:
Vous pouvez également utiliser test de la découverte qui permettra de découvrir et d'exécuter tous les tests pour vous, ils doivent être des modules ou des paquets nommé
test*.py
(peut être changé avec la-p, --pattern
drapeau):Cela permettra d'exécuter tous les
test*.py
modules à l'intérieur de latest
paquet.python -m unittest discover
permettra de trouver et d'exécuter les tests dans letest
répertoire s'ils sont nomméstest*.py
. Si vous avez nommé le sous-répertoiretests
, utilisezpython -m unittest discover -s tests
, et si vous avez nommé les fichiers de testantigravity_test.py
, utilisezpython -m unittest discover -s tests -p '*test.py'
les noms de Fichiers peuvent utiliser des traits de soulignement, mais pas des tirets.antigravity.py
contiendrait, compte tenu de la structure de répertoire qui ressemble le deuxième exemple. Je peux imaginer ma question est est-ce vraiment que la différence entre le forfait et le module, mais souhaitez un aperçu de leur distinction dans le contexte de ce scénario. Merci!!!!test_antigravity.py
par exempleimport .antigravity
ne fonctionne, il doit êtreimport antigravity
common
à l'aide de deux façons,from .common import whatever
oufrom test.common import whatever
.ImportError: No module named 'test.test_antigravity'
en raison d'un conflit avec le test de sous-module unittest de la bibliothèque. Peut-être qu'un expert puisse vérifier et changer la réponse nom de sous-répertoire, par exemple, "tests" (au pluriel).test_antigravity.py
jette toujours un message d'erreur d'importation pour les deuximport antigravity
etfrom antigravity import antigravity
, ainsi. J'ai à la fois__init_.py
fichiers et je fais appelpython3 -m unittest discover
de lanew project
répertoire. Quoi d'autre pourrait être mal?test/test_antigravity.py
ajouterimport os,sys; sys.path.insert(0, os.path.abspath('..'))
python -m unittest
semble fonctionner comme découvrirtest/__init__.py
est ici crucial, même si c'est videtest
est spécial...mais juste pour le record, il n'est pas. 😛python -m unittest discover
fonctionne avec les fichiers de test danstests/
aussi bien quetest/
.python -m unittest discover
trouverez les fichiers de test automatiquement. Mais si vous avez nommé 'mygrav_test.py" ou "mygravtest.py', alors vous devez utiliserpython -m unittest discover -p '*test.py'
.La solution la plus simple pour vos utilisateurs est de fournir un script exécutable (
runtests.py
ou quelque chose du genre) qui amorce le nécessaire, environnement de test, y compris, si nécessaire, ajouter la racine de votre répertoire de projet àsys.path
temporairement. Cela ne nécessite pas les utilisateurs à définir des variables d'environnement, quelque chose comme cela fonctionne bien dans un script bootstrap:Ensuite vos instructions à vos utilisateurs peut être aussi simple que "
python runtests.py
".Bien sûr, si le chemin que vous avez vraiment besoin est
os.path.dirname(__file__)
, alors vous n'avez pas besoin de l'ajouter àsys.path
à tous; Python met toujours le répertoire du script en cours d'exécution au début desys.path
, donc, en fonction de votre structure de répertoire, juste à l'emplacement de votreruntests.py
au bon endroit, peut-être tout ce qui est nécessaire.Aussi, le unittest module en Python 2.7+ (qui est pris comme unittest2 pour Python 2.6 et antérieures) a maintenant test de la découverte intégré, de sorte que le nez n'est plus nécessaire si vous voulez test automatisé découverte: votre manuel d'utilisateur peut être aussi simple que
python -m unittest discover
.python -m pdb tests\test_antigravity.py
. À l'intérieur de l'apb, j'ai exécutésys.path.insert(0, "antigravity")
qui a permis à l'instruction import pour résoudre, comme si j'étais de l'exécution du module.J'en général de créer une "exécution de tests de script" dans le répertoire du projet (celui qui est commun à la fois le répertoire source et
test
) qui charge mon "Tous les Tests" de la suite. C'est généralement le code réutilisable, donc, je peux la réutiliser dans d'autres projets.run_tests.py:
test/all_tests.py (à partir de Comment puis-je exécuter toutes Python tests unitaires dans un répertoire?)
Avec cette configuration, vous pouvez en effet juste
include antigravity
dans vos modules de test. L'inconvénient est que vous auriez besoin de plus de soutien de code à exécuter un test particulier... je viens de courir à chaque fois.run tests
script dans le répertoire du projet et trouvé beaucoup le moyen le plus propre pour le faire. Fortement recommandé.De l'article que vous avez lié à:
Peut-être que vous devriez regarder nez comme il le suggère?
si vous exécutez "python setup.py développer", puis le paquet sera dans le chemin. Mais vous ne voulez pas le faire parce que vous pourriez infecter votre système d'installation de python, c'est pourquoi des outils comme virtualenv et buildout existent.
J'ai eu le même problème, avec une unité distincte dossier de tests. De la mentionnée suggestions, j'ai ajouter le absolu chemin de la source à
sys.path
.L'avantage de la solution suivante est, que l'on peut exécuter le fichier
test/test_yourmodule.py
sans changer à la première dans le test-répertoire:Utilisation
setup.py develop
pour faire de votre répertoire de travail de faire partie de l'installation de Python, de l'environnement, puis exécuter les tests.invalid command 'develop'
et cette option n'est pas mentionné si je demandesetup.py --help-commands
. Il faut quelque chose dans lesetup.py
lui-même pour que cela fonctionne?import setuptools
de monsetup.py
fichier. Mais je suppose que cela ne va montrer que cela ne fonctionne pas tout le temps pour les autres modules.pip install -e .
Cette même ajoute le colis à l'environnement Python sans copier la source, vous permettant de continuer à éditer à l'endroit où il se trouve.pip install -e .
est exactement la même chose quepython setup.py develop
, c'est juste monkeypatches votresetup.py
à utiliser setuptools même si il ne fait pas, de sorte qu'il fonctionne de toute façon.Si vous utilisez VS Code et vos tests sont situés sur le même niveau que votre projet puis exécuter et déboguer votre code ne fonctionne pas hors de la boîte. Ce que vous pouvez faire est de changer votre lancement.fichier json:
La clé ici est envFile
À la racine de votre projet, ajouter .fichier env
À l'intérieur de votre .env fichier ajouter le chemin vers la racine de votre projet. Cela permettra d'ajouter temporairement
chemin d'accès à votre projet et vous serez en mesure d'utiliser debug tests unitaires à partir de VS Code
Solution/Exemple pour Python module unittest
Compte tenu de la structure de projet suivante:
Vous pouvez exécuter votre projet à partir du répertoire racine avec
python project_name
, qui appelleProjectName/project_name/__main__.py
.À l'exécution de vos tests avec
python test
, de manière efficace l'exécution deProjectName/test/__main__.py
, vous devez effectuer les opérations suivantes:1) Transformer votre
test/models
répertoire dans un paquet en ajoutant un__init__.py
fichier. Cela rend le cas de test dans le sous-répertoire accessible à partir du parenttest
répertoire.2) Modifier le chemin d'accès système dans
test/__main__.py
pour inclure leproject_name
répertoire.Maintenant, vous pouvez importer correctement les choses de
project_name
dans vos tests.J'ai remarqué que si vous exécutez l'unittest interface de ligne de commande à partir de votre répertoire "src", puis importations travail correctement sans modification.
Si vous voulez mettre que dans un lot de fichier dans votre répertoire de projet, vous pouvez le faire:
J'utilise Python 3.6.2
Pour installer pytest:
sudo pip install pytest
Je n'ai pas mis toute variable de chemin d'accès et mon importations ne manquent pas avec le même "test" de la structure de projet.
J'ai commenté ce truc:
if __name__ == '__main__'
comme ceci:test_antigravity.py
Il est possible d'utiliser un wrapper qui s'exécute sélectionné ou de tous les tests.
Par exemple:
ou pour exécuter tous les tests de manière récursive utilisation d'expansion (
tests/**/*.py
) (activer parshopt -s globstar
).Le gestionnaire peut utiliser
argparse
à analyser les arguments comme:Puis de charger tous les tests:
puis les ajouter dans votre suite de tests (à l'aide de
inspect
):et de les exécuter:
Vérifier cette exemple pour plus de détails.
Voir aussi: Comment faire pour exécuter toutes Python tests unitaires dans un répertoire?
Voici mon projet structure:
Je l'ai trouvé de mieux pour l'importation dans la méthode setUp ():
Python 3+
Ajoutant à @Pierre
À l'aide de
unittest
structure de répertoire comme ceci:Pour exécuter le module de test
test_antigravity.py
:Ou un seul
TestCase
Obligatoire n'oubliez pas le
__init__.py
même si vide dans le cas contraire ne fonctionnera pas.Vous ne pouvez pas importer à partir du répertoire parent sans le vaudou. Voici encore une autre manière qui fonctionne avec au moins Python 3.6.
Tout d'abord, avoir un fichier test/context.py avec le contenu suivant:
Alors d'importation suivantes dans le fichier test/test_antigravity.py:
Noter que la raison de cet essai, sauf clause est que
Avec cette supercherie ils travaillent tous les deux.
Maintenant, vous pouvez exécuter tous les fichiers de test dans le test de répertoire avec:
ou d'exécuter un test de fichier avec:
Ok, ce n'est pas beaucoup plus joli que d'avoir le contenu de context.py au sein de test_antigravity.py mais peut-être un peu. Les Suggestions sont les bienvenues.
Ce script BASH va exécuter le script python unittest répertoire de test à partir de n'importe où dans le système de fichiers, n'importe quel répertoire de travail, vous êtes dans.
Ceci est utile lors de votre séjour dans la
./src
ou./example
répertoire de travail et vous avez besoin d'un rapide test de l'unité:Pas besoin d'un
test/__init__.py
fichier à la charge de votre colis/mémoire de frais généraux au cours de la production.Si vous avez plusieurs répertoires dans votre répertoire de test, puis vous devez ajouter à chaque répertoire un
__init__.py
fichier.Puis pour exécuter tous les tests à la fois, exécutez:
Source:
python -m unittest -h
Si vous êtes à la recherche d'une ligne de commande seule solution:
Basé sur la structure de répertoire suivante (généralisée avec un répertoire source):
Windows: (en
new_project
)Voir cette question si vous voulez l'utiliser dans un lot de boucle.
Linux: (en
new_project
)Avec cette approche, il est également possible d'ajouter des répertoires à la PYTHONPATH si nécessaire.
De cette façon vous permettra d'exécuter les scripts de test à partir d'où vous voulez, sans déconner avec les variables du système à partir de la ligne de commande.
Ceci s'ajoute le dossier de projet principal pour le python path, avec l'emplacement par rapport au script lui-même, pas par rapport au répertoire de travail courant.
Ajouter que vers le haut de tous vos scripts de test. Qui va ajouter le dossier de projet principal pour le système de chemin, de sorte que n'importe quel module importations qui fonctionnent à partir de maintenant, il y aura du travail. Et il n'importe pas où vous exécutez les tests de.
Vous pouvez bien évidemment changer le project_path_hack fichier pour correspondre à votre projet principal emplacement de dossier.
Vous devriez vraiment utiliser le pip de l'outil.
Utilisation
pip install -e .
pour installer votre colis, le mode de développement. C'est une très bonne pratique, recommandé par pytest (voir leur les bonnes pratiques de documentation, où vous pouvez également trouver deux projets de mises en page à suivre).pytest
est meilleur pour l'exécution des tests, en raison de la sortie de la console, vous obtenez, en couleur, avec trace de la pile d'info et détaillée de l'erreur d'assertion de l'information.