Импорт Python для тестирования модулей с дополнительными зависимостями - PullRequest
0 голосов
/ 03 июля 2018

Я хочу, чтобы мои тесты находились в отдельной папке от кода моего пакета, чтобы из каталога верхнего уровня моего проекта я мог запустить python sample/run.py или python tests/test_run.py, и оба они правильно разрешали все операции импорта.

Моя структура каталогов выглядит так:

sample/
   __init__.py
   helper.py
   run.py
tests/
   context.py
   test_run.py

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

Однако, когда я пытаюсь запустить python tests/test_run.py, я получаю ModuleNotFoundError для 'helper', потому что 'sample / run.py' импортирует 'sample / helper.py'.

В частности, я пытаюсь следовать соглашению (предложенному в Справочнике автостопом по Python ) о явном изменении пути с помощью:

import os, sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

В результате у меня есть пустое sample/__init__.py вместе со следующими файлами кода.

образец / run.py:

from helper import helper_fn
def run():
    helper_fn(5)
    return 'foo'
if __name__ == '__main__':
    run()

образец / helper.py:

def helper_fn(N):
    print(list(range(N)))

Тесты / context.py:

import os, sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

import sample

Тесты / test_run.py:

from context import sample
from sample import run

assert run.run() == 'foo'

Итак, у меня два вопроса:

  1. Почему Python не может найти модуль 'helper'?
  2. Как исправить ситуацию, чтобы я мог запускать и sample/run.py и tests/test_run.py из каталога верхнего уровня?

1 Ответ

0 голосов
/ 03 июля 2018

Отредактировано:

Чтобы оба sample/run.py и tests/test_run.py работали, вы должны добавить путь к каталогу sample в путь к Python. Итак, ваш tests/context.py должен быть

import os, sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../sample')))


import sample

Это изменение позволит Python узнать путь к модулю helper.


sample/run.py должно быть:

  from .helper import helper_fn
  def run():
     helper_fn(5)
     return 'foo'
  if __name__ == '__main__':
     run()

Неявный относительный импорт внутри пакетов недоступен в Python 3. Пожалуйста, проверьте ниже:

Система импорта была обновлена ​​для полной реализации второго этапа PEP 302. Больше не существует неявного механизма импорта - полная система импорта предоставляется через sys.meta_path. Кроме того, была реализована поддержка пакета собственного пространства имен (см. PEP 420). ссылка

Эта документация может быть полезна для понимания ссылок внутри пакета.

...