IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Comment import le projet depuis un dossier test unittest ?


Sujet :

Python

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2020
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2020
    Messages : 41
    Points : 75
    Points
    75
    Par défaut Comment import le projet depuis un dossier test unittest ?
    Salut tout le monde !

    J'ai un projet qui contient 2 dossiers :

    sources (qui contient mes fichiers sources)
    test (qui contient les tests unitaires du code source)

    J'aimerais que mon dossier test import des modules contenus dans sources pour les tester. Mon problème est que pour l'instant je n'ai réussi à faire marcher mes tests qu'en modifiant le sys.path dans tous les fichiers contenus dans le dossier test or je n'ai pas l'impression que ce soit une bonne méthode. Si je dois modifier l'arborescence, cette méthode entraîne beaucoup de duplication de code et n'est pas très adaptable.

    J'ai l'impression que la bonne technique (n'hésitez pas à me dire si je me trompe) serait de modifier le sys.path d'un seul fichier dans le répertoire test qui pourrait ensuite transmettre l'info à tous les autres fichiers. Le problème c'est que cette méthode ne fonctionne qu'avec les fichiers qui se trouvent au même endroit. Dans le répertoire test les fichiers sont réparties en plusieurs dossiers qui contiennent eux-mêmes plusieurs sous-dossiers donc je ne pourrais pas indiquer le même chemin pour tous les fichiers, il faudra que je m'adapte.

    J'ai essayé de faire un import relatif depuis les fichiers situés dans les sous-dossiers vers mon répertoire test mais je me retrouve avec cette erreur :

    ImportError: attempted relative import with no known parent package

    Quelqu'un aurait une idée pour avoir un répertoire test en dehors du répertoire du code source qui puisse importer le package sources depuis tous les fichiers de test ? J'imagine que je ne suis pas le seul à adopter une configuration avec un dossier test séparé des sources. Pourtant après plusieurs heures de recherche je n'ai pas trouvé la solution...

    Merci d'avance !

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour

    Je ne suis pas sûr d'avoir bien compris le problème, mais il me semble que la technique des "packages" seraient appropriées:
    https://docs.python.org/fr/3.10/tuto....html#packages

    Ainsi, on ajoute dans le fichier test la racine du répertoire source avec sys.path, et on importe les modules en citant le chemin des fichiers à importer avec les sous-répertoires dans les instructions d'importation. Cela nécessite simplement la présence de fichier "__init__.py", même vide, sous le répertoire racine et ses sous-répertoires concernés:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    import sousrep1.sousrep2.source
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  3. #3
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2020
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2020
    Messages : 41
    Points : 75
    Points
    75
    Par défaut
    Merci pour ta réponse !

    Je peux lancer les tests depuis un script dans mon dossier test mais mes fichiers de test qui sont dans l'arborescence en dessous n'arrive pas à importer le code à l'intérieur de mon dossier source. Pour cela j'ai dû faire des ajouts dans le sys.path :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    sys.path.append(home/user/monprojet/source)
    sys.path.append(home/user/monprojet/test/utils)
    puis utiliser un import absolu :

    from sources import module1.
    from sources import module2
    Si je retire le sys.path j'ai cette erreur :
    ModuleNotFoundError: No module named 'sources'
    Si j'essaie de mettre des relative imports j'ai cette erreur :
    ValueError: attempted relative import beyond top-level package

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Röyksopp Voir le message
    J'ai un projet qui contient 2 dossiers :

    sources (qui contient mes fichiers sources)
    test (qui contient les tests unitaires du code source)

    J'aimerais que mon dossier test import des modules contenus dans sources pour les tester.
    Un code Python part toujours du dossier qui le contient. Si tu lances un script "test/toto.py", ou si tu te places dans "test" et que tu appelles "./toto.py" c'est pareil, le code partira du dossier "test" pour ses imports.
    Rajoute donc sys.path.append("..") pour que le dossier "source" soit connu depuis le script situé dans "test" puis tu pourras taper from sources import ... dans les scripts dudit dossier "test". Attention toutefois, il existe aussi un dossier nommé "test" dans les lib Python. Cela peut causer de la confusion.

    Donc exemple
    A la racine j'ai un fichier "main.py"
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #!/usr/bin/env python3
    # coding: utf-8
     
    from tests import ttt
     
    ttt.fctT()

    J'ai un dossier "tests" (avec un "s" pour pas créer de conflit avec celui de la lib Python) contenant un fichier "ttt.py"
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #!/usr/bin/env python3
    # coding: utf-8
     
    from sources import sss
     
    def fctT():
    	print("fctT")
    	sss.fctS()

    Et un dossier "sources" contenant le code "sss.py"
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #!/usr/bin/env python3
    # coding: utf-8
     
    def fctS(): print("fctS")
    Le tout s'articule parfaitement

    Citation Envoyé par Röyksopp Voir le message
    Mon problème est que pour l'instant je n'ai réussi à faire marcher mes tests qu'en modifiant le sys.path dans tous les fichiers contenus dans le dossier test or je n'ai pas l'impression que ce soit une bonne méthode.
    Oui et non.
    A la base, quand on code un projet, on est présumé partir d'un programme situé à la racine du projet. Ce programme pourra importer "test/trucA" puis "sources/trucB". Et depuis un script situé dans "test" tu peux importer un truc situé dans "sources" sans souci puisque le code a démarré à la racine donc au niveau du dossier principal qui contient "test" et "sources" donc qui les connait tous les deux.
    Dans ce cas, pas besoin de modifier sys.path.
    Il peut toutefois arriver qu'on veuille faire des tests unitaires, et que ces tests aient besoin d'un import situé ailleurs. Dans ce cas, vu que le test unitaire se passe cette fois depuis le script testé, là oui il aura besoin de rajouter dans sys.path le chemin permettant de voir le dossier contenant l'import.
    Exemple: je veux pouvoir vérifier que "ttt.py" fonctionne. Je le réécris donc ainsi
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #!/usr/bin/env python3
    # coding: utf-8
     
    if __name__ == "__main__":
    	import sys
    	sys.path.append("..")
    # if
    from sources import sss
     
    def fctT():
    	print("fctT")
    	sss.fctS()
     
    if __name__ == "__main__":
    	fctT()
    De là je peux aller dans "tests" et appeler "ttt.py" et je vois qu'il fonctionne.

    Citation Envoyé par Röyksopp Voir le message
    J'ai l'impression que la bonne technique (n'hésitez pas à me dire si je me trompe) serait de modifier le sys.path d'un seul fichier dans le répertoire test qui pourrait ensuite transmettre l'info à tous les autres fichiers. Le problème c'est que cette méthode ne fonctionne qu'avec les fichiers qui se trouvent au même endroit. Dans le répertoire test les fichiers sont réparties en plusieurs dossiers qui contiennent eux-mêmes plusieurs sous-dossiers donc je ne pourrais pas indiquer le même chemin pour tous les fichiers, il faudra que je m'adapte.
    Effectivement si l'arborescence depuis "test" est plus complexe, ça devient fatalement plus complexe à gérer. La seule chose à faire alors est de toujours se souvenir qu'un script Python démarre son arborescence depuis l'endroit où il se trouve quand il est appelé.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2020
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2020
    Messages : 41
    Points : 75
    Points
    75
    Par défaut
    Merci pour ta réponse !

    Donc en gros, j'ai déjà implémenté la méthode qui correspond à mon problème. Je suis bel et bien obligé de renseigner le sys.path dans chaque fichier que je suis destiné à exécuter.

    Au moins, je peux arrêter de chercher une solution à présent parce que cette situation me prenait la tête depuis un moment !

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Röyksopp Voir le message
    Mon problème est que pour l'instant je n'ai réussi à faire marcher mes tests qu'en modifiant le sys.path dans tous les fichiers contenus dans le dossier test or je n'ai pas l'impression que ce soit une bonne méthode.
    Vu les répertoires, il faudra modifier sys.path directement où via la variable d'environnement PYTHONPATH (ce qui évite de modifier des lignes de code).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2020
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2020
    Messages : 41
    Points : 75
    Points
    75
    Par défaut
    Je ne suis pas sûr de pouvoir modifier le PYTHONPATH car mon projet est juste un utilitaire dans un projet plus volumineux. Après ça dépend de ce que cela implique.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Une variable d'environnement du shell se fait et se défait quand on veut...
    Après si vous préférez modifier sys.path dans vos scripts python, c'est vous qui voyez.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2020
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2020
    Messages : 41
    Points : 75
    Points
    75
    Par défaut
    En gros, il faudrait que je définisse le PYTHONPATH dans un fichier .sh puis que j'utilise ce fichier .sh comme runner pour lancer des commandes sur mon code ? Ça pourrait être une solution mais je préfère l'éviter pour l'instant car je pense que ça augmente un peu la complexité pour rien. Mais c'est un avis personnel.

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Cette affirmation:
    Citation Envoyé par Röyksopp
    Je suis bel et bien obligé de renseigner le sys.path dans chaque fichier que je suis destiné à exécuter.
    est fausse.
    Après si malgré tout vous préférez mettre à jour sys.path dans vos différents scripts... c'est vous qui bossez.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Röyksopp Voir le message
    Mais c'est un avis personnel.
    .. que je rejoins aussi. J'aime bien ton idée de "runner dédié" mais je préfère la solution du sys.path. Certes plus de travail mais chaque script décrit (déclare) explicitement les dossiers dont il a besoin.
    Et puis bon le travail n'est en réalité pas si grand car on rajoute au sys.path non pas les dossiers à importer mais juste l'unique dossier parent les contenant. Ca couplé à un modèle de base qu'on récupère quand on veut créer un nouveau script...
    Ici un tutoriel très bien détaillé sur le fonctionnement des import: https://datajourney.io/le-pythonpath.html.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Importer des Documents depuis un dossier
    Par fredlang dans le forum Développement Sharepoint
    Réponses: 3
    Dernier message: 20/10/2010, 09h36
  2. [RCP] Comment importer un projet à base de plug-in
    Par r2d2abc dans le forum Eclipse Platform
    Réponses: 4
    Dernier message: 03/05/2010, 13h59
  3. importer une classe depuis un dossier externe
    Par vulkanosaure dans le forum ActionScript 3
    Réponses: 3
    Dernier message: 19/08/2009, 14h12
  4. Import de .xls depuis un dossier local
    Par samson_02 dans le forum VBA Access
    Réponses: 5
    Dernier message: 14/01/2009, 11h56
  5. Réponses: 2
    Dernier message: 23/06/2008, 11h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo