Доступ к файлам ресурсов в модульных тестах Python и основном коде - PullRequest
6 голосов
/ 08 июля 2011

У меня есть проект Python со следующей структурой каталогов:

project/
project/src/
project/src/somecode.py
project/src/mypackage/mymodule.py
project/src/resources/
project/src/resources/datafile1.txt

В mymodule.py у меня есть класс (назовем его «MyClass»), который должен загрузить datafile1.txt.Когда я это делаю, это работает:

open ("../resources/datafile1.txt")

При условии, что код, который создает созданный экземпляр MyClass, запускается из somecode.py.

Однако, я понял, что у меня есть модульные тесты для mymodule.py, которые определены в этом файле, и если я оставлю относительный путь, как описано выше, код unittest будет взорван, так как теперь код запускается из проекта/ src / mypackage вместо project / src и относительный путь к файлу не разрешаются правильно.

Какие-либо предложения по подходу типа наилучшей практики для решения этой проблемы?Если я перенесу свои тестовые сценарии в project / src, который загромождает основную исходную папку тестовыми сценариями.

Ответы [ 3 ]

7 голосов
/ 08 июля 2011

Я обычно использую это, чтобы получить относительный путь от моего модуля. Никогда не пробовал в юнит тесте, хотя.

import os

print(os.path.join(os.path.dirname(__file__), 
                   '..',
                   'resources' 
                   'datafile1.txt'))

Примечание. Уловки .. работают довольно хорошо, но если вы измените структуру каталогов, вам потребуется обновить эту часть.

2 голосов
/ 08 июля 2011

в каждом каталоге, содержащем скрипты Python, поместите модуль Python, который знает путь к корню иерархии. Он может определить одну глобальную переменную с относительным путем. Импортируйте этот модуль в каждый скрипт. Python сначала ищет текущий каталог, поэтому он всегда будет использовать версию модуля в текущем каталоге, которая будет иметь относительный путь к корню текущего каталога. Затем используйте это, чтобы найти другие ваши файлы. Например:

# rootpath.py
rootpath = "../../../"

# in your scripts
from rootpath import rootpath
datapath = os.path.join(rootpath, "src/resources/datafile1.txt")

Если вы не хотите помещать дополнительные модули в каждый каталог, вы можете использовать этот подход:

Поместите дозорный файл в верхний уровень структуры каталогов, например, thisisthetop.txt. Пусть ваш скрипт Python перемещается вверх по иерархии каталогов, пока не найдет этот файл. Напишите все ваши пути относительно этого каталога.

Возможно, какой-то файл, который у вас уже есть в каталоге проекта, может быть использован для этой цели (например, продолжайте двигаться вверх, пока вы не найдете каталог src), или вы можете назвать каталог проекта таким образом, чтобы это стало очевидным.

0 голосов
/ 08 июля 2011

Путь к файлу будет относиться к сценарию, который вы изначально вызывали.Я бы посоветовал вам передать относительный путь в качестве аргумента MyClass.Таким образом, вы можете иметь разные пути в зависимости от того, какой скрипт вызывает MyClass.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...