Как правильно структурировать код и импорт python3, который подходит как для тестов, так и для запуска кода? - PullRequest
2 голосов
/ 10 апреля 2019

Я относительно новичок в python, и я изо всех сил пытаюсь найти комбинацию файловой иерархии и операторов импорта, которые будут работать в pycharm, pytest в командной строке, запускать настоящую программу в командной строке и строить из бамбука.

Вот моя иерархия:

foo
| goo
| __init__.py
| run.py
  | koo
    | __init__.py
    | bar.py
  | loo
    | __init__.py
    | baz.py
| tests
| __init__.py
| test_bar.py
| test_baz.py
| test_file.py
| data
  | text.txt

Вот мой код:

Foo / липкая / Koo / bar.py:

greeting = "hello"


def hello():
    return greeting

Foo / липкая / Лоо / baz.py:

from koo import bar


def greet():
    return "the greeting is..." + bar.hello()

Foo / липкая / run.py:

import loo.baz as baz


print(baz.greet())

Foo / тесты / test_bar.py:

import goo.koo.bar as b


def test_hello():
    assert b.hello() == "hello"

Foo / тесты / test_baz.py:

import goo.loo.baz as b


def test_greet():
    assert b.greet() == "the greeting is...hello"

Foo / тесты / test_file.py:

import os.path
import sys


def test_file():
    f = open(os.path.join(sys.path[0], "tests", "data", "test.txt"), "rt")
    assert f.read() == "hello world"

Когда я иду в каталог foo и запускаю

python goo/run.py

это работает. Но когда я бегу

python -m pytest tests

Я получаю ошибку

Traceback:
tests/test_baz.py:1: in <module>
    import goo.loo.baz as b
goo/loo/baz.py:1: in <module>
    from koo import bar
E   ModuleNotFoundError: No module named 'koo'

Если я изменю baz.py на следующее:

from goo.koo import bar


def greet():
    return "the greeting is..." + bar.hello()

тогда все тесты проходят, но запуск программы выдает эту ошибку:

Traceback (most recent call last):
  File "goo/run.py", line 1, in <module>
    import loo.baz as baz
  File "/home/me/PycharmProjects/foo/goo/loo/baz.py", line 1, in <module>
    from goo.koo import bar
ModuleNotFoundError: No module named 'goo'

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

Если я хочу сохранить тесты на верхнем уровне, будет ли работать какая-то комбинация импорта?

1 Ответ

1 голос
/ 10 апреля 2019

Я бы использовал комбинацию абсолютного импорта, например from goo.koo import bar и добавление папки foo в PYTHONPATH с помощью

export PYTHONPATH=$PYTHONPATH:/path/to/foo

затем структурируйте все ваши импорты, как если бы они происходили из папки foo

...