Цели
Я пытаюсь настроить проект так, чтобы он работал во время разработки и после упаковки. Мне нужно достичь нескольких целей, и мне кажется, что я не могуразберитесь с ними по отдельности, делая правильное, потому что один не сможет выполнить некоторые другие.
- возможность запуска тестов из командной строки, возможно, после установки переменной окружения PYTHONPATH
- возможность запуска/ отладка тестов из IDE, возможно определение переменной среды PYTHONPATH
- запуск теста во время CI (Трэвис)
- не предоставляет ничего, кроме требуемой функции
- предоставляет функцию
- вызывается как интерфейс командной строки
Context
Вот структура моего проекта.Мне это нравится, но я с удовольствием поменяю его, чтобы удовлетворить вышеупомянутые требования.Но я бы действительно предпочел не смешивать тесты и исходники, а также ресурсы и код.
.
├── LICENSE
├── README.md
├── mysql_tracer
│ ├── __init__.py
│ ├── __main__.py
│ ├── chest.py
│ ├── cursor_provider.py
│ ├── query.py
│ └── writer.py
├── requirements.txt
├── setup.py
└── tests
├── assets
│ ├── sample-query-executed.csv
│ ├── sample-query-executed.sql
│ ├── sample-query.sql
│ └── sample-template-query.sql
└── python
├── __init__.py
├── conftest.py
├── test_query.py
└── test_writer.py
4 directories, 18 files
Разработка
Во время разработки я настраивал 1, 2 и 3. Мне было трудноЭто происходит потому, что импорт между модулями, импорт из тестов и модули-модули все работают по-разному.Я управлял рабочим решением со следующим:
- module query.py импортирует модуль writer.py, используя
import writer
- module query.py импортирует класс CursorProvider из модуля cursor_provider.py, используя
from cursor_provider import CursorProvider
- модуль test_query.py импортирует запрос, используя
import query
- , функция test_result из модуля test_query.py проверяет модуль CursorProvider, импортированный из модуля query.py, используя
@mock.patch('query.CursorProvider')
- .travis.yml определяет тест как:
script:
- export PYTHONPATH=mysql_tracer
- pytest
Эта последняя часть была особенно нелогичной, так как предыдущие настройки, которые я пробовал, позволяли запускать тесты локали из терминала без установки переменной среды, и Idea всегда управлялаработать как-то.Рабочие настройки требовали его настройки для Travis и локального терминала.
Можно было просмотреть мою историю git и увидеть, что мне пришлось попробовать много вещей, прежде чем она заработала:
$ git log 1e5338dfab429d894a109a287f2a087c5d945a90..39c6e093e3bdb4470f374c4eb50d02ec52cb878a --pretty=format:"%h%x09%ad%x09%s"
39c6e09 Mon Feb 11 01:15:04 2019 +0100 travis, just do it please
544e540 Mon Feb 11 01:00:17 2019 +0100 mark it work locally... we'll see for CI later
a38caaa Mon Feb 11 00:10:50 2019 +0100 combine regexes with or
7a1eb88 Sun Feb 10 23:43:35 2019 +0100 travis, you're the last one, just f* works please
042f7c3 Sun Feb 10 23:08:14 2019 +0100 travis, mock, pytest, I changed everything, are you happy now ?
79e45c9 Sun Feb 10 22:54:35 2019 +0100 travis, get your shit together please
17eafaa Sun Feb 10 22:48:39 2019 +0100 another way to expose and import module to please both travis and mock
ea93558 Sun Feb 10 22:39:05 2019 +0100 test
4956d5a Sun Feb 10 21:34:31 2019 +0100 another way to expose Query...
98ff216 Sun Feb 10 21:22:33 2019 +0100 import differently
2426a6d Sun Feb 10 21:20:30 2019 +0100 expose Query
851ea43 Sun Feb 10 21:17:09 2019 +0100 setup.py
Упаковка
Но теперь, когда разработка подходит к концу, я настроил конфигурацию пакета для поддержки 5 и 6. К сожалению, мне не удалось настроить 4 правильно, и я сломал 1, 2 и3.
Мне пришлось изменить импорт между модулями, потому что в противном случае использование моего пакета после его установки локально или из pypi не сработало бы.
- Вместо того, чтобы делать
import writer
Iбудет делать from . import writer
- Вместо того, чтобы делать
from cursor_provider import CursorProvider
Я бы сделал from .cursor_provider import CursorProvider
(обратите внимание на точку перед именем модуля)
Это заставило мой интерфейс Cli работать.После этого я мог бы использовать
$ mysql_tracer -h
... skipped output ...
$ mysql_tracer --host 127.0.0.1 --user aho --database company --destination /home/aho/Downloads /home/aho/sources/sql-test-tools/people.sql
. На этом этапе импорт модуля mysql_tracer будет работать, но он ничего не показывает.Однако при добавлении следующей строки в файл mysql_tracer/__init__.py
будет открыт класс Query:
from .query import Query
Но так же все модули определены в пакете mysql_tracer (конец списка):
>>> import mysql_tracer
>>> dir(mysql_tracer)
['Query', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'chest', 'cursor_provider', 'query', 'writer']
Хотя это не слишком беспокоит, это нежелательно.Я имел в виду только атрибут Query, который будет доступен. сундук, cursor_provider, запрос и писатель должны быть скрыты .Обратите внимание, что они были недоступны до того, как я попытался предоставить класс Query.
Но теперь операторы импорта, которые сделали функционал пакета, делают тесты неудачными:
from . import writer
E ImportError: attempted relative import with no known parent package
ИтакКак сохранить работоспособность функций (5 и 6) при восстановлении требований к разработке (1,2 и 3)?И, возможно, также функция 4?
Я надеюсь, что предоставил необходимую и достаточную информацию, но если вам нужно больше, пожалуйста, посетите мой проект , пакет или CI page или прокомментируйте и попросите разъяснений.