Как импортировать и пропатчить модуль Python, который находится в пакете, отличном от пакета тестов? - PullRequest
1 голос
/ 26 мая 2020

Мое исходное дерево выглядит так:

.
├── README.md
├── app
│   ├── __init__.py
│   ├── flask_main.py
│   └── lib.py
├── run_endpoint_check_tests.sh
├── run_flask.sh
├── run_unit_tests.sh
└── tests
    ├── endpoint_checks.py
    └── test_lib.py

flask_main.py (естественно) импортирует lib.py вот так: import roku_lib

Но чтобы получить test_lib.py для импорта lib.py, мне нужно сделать это:

sys.path.append("app")
from app import lib

И я запускаю модульные тесты, используя это (в run_unit_tests.sh):

#!/bin/sh
python -m pytest

(я не смог запустить pytest для работы, что, я думаю, имеет смысл после чтения https://docs.pytest.org/en/latest/goodpractices.html#tests -outside-application-code .)

Однако этот модульный тест не проходит:

def test_load_from_s3(mocker, monkeypatch):
    x_mock = mocker.Mock()
    return_mock = mocker.Mock()
    x_mock.Object = mocker.Mock(return_value=return_mock)
    monkeypatch.setattr(lib, 'get_x', lambda: x_mock)

    y = lib.get_x()

    x_mock.Object.assert_called_once()

    ...

Я думаю, что это не удается, потому что вызов lib.get_x () приводит к импорту его собственной (копии?) Библиотеки, не исправленной обезьяной.

Тот же тест работает, когда исходное дерево выглядит так:

    .
    ├── README.md
    ├── __init__.py
    ├── lib.py
    ├── uses_lib.py
    └── tests
        ├── __init__.py
        ├── test_uses_lib.py
        └── test_lib.py

И sys.path.append("app") и from app import lib не нужны.

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

Итак, наконец, мои вопросы ...

Как мне исправить импорт или код исправления обезьяны (или оба ) так что патч обезьяны работает?

Возможно ли (добавив лишние пустые __init__.py файлы, где они отсутствуют, возможно?) заставить импорт работать в test_lib.py без sys.path.append("app")?

1 Ответ

0 голосов
/ 27 мая 2020

Я переместил lib.py в каталог libs:

.
├── README.md
├── app
│   ├── __init__.py
│   └── flask_main.py
├── libs
│   ├── __init__.py
│   ├── lib_a.py
│   └── lib_b.py
├── run_endpoint_check_tests.sh
├── run_unit_tests.sh
└── tests
    ├── endpoint_checks.py
    ├── test_lib_a.py
    └── test_lib_b.py

(И я разделил lib.py на lib_a.py и lib_b.py. lib_b.py импортирует lib_a.)

И я импортирую lib_a.py и lib_b.py таким же образом в flask_main.py, lib_b.py и test_lib_a.py & test_lib_b.py:

sys.path.append("..")
from libs import lib_a
from libs import lib_b

Теперь flask_main.py выполняется правильно и , модульные тесты проходят (без сбоев утверждения патча обезьяны).

Примечание. Я удалил run_flask.sh, так как теперь мне нужно запустить flask_main.py с каталогом app как cwd.

Обратите внимание, что мне все еще нужно запустить python -m pytest - запуск pytest приводит к ModuleNotFoundErrors.

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