#python #flask #pytest
#python #flask #pytest
Вопрос:
Я пишу API в Flask и в какой-то момент отправляю электронное письмо пользователям, которые регистрируются. Я храню переменные, относящиеся к этой службе электронной почты, в файле .env. Теперь хочу протестировать фрагмент, в котором я использую эти переменные, но я понятия не имею, как загрузить их из файла .env.
Я перепробовал в основном все ответы здесьhttps://rb.gy/0nro1a , обезьяна исправляет setenv, как показано здесьhttps://rb.gy/kd07wa другие советы здесь и там. Каждый сбой в какой-то момент. Я также пробовал использовать pytest-dotenv. pytest-env, pytest.ini и т.д. Но на самом деле ничего не работало так, как ожидалось, и все это меня довольно смущает.
Мой прибор pytests выглядит следующим образом
@pytest.fixture(autouse=True)
def test_client_db():
# set up
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///"
app.config["JWT_SECRET_KEY"] = "testing"
with app.app_context():
db.init_app(app)
db.create_all()
testing_client = app.test_client()
ctx = app.app_context()
ctx.push()
# do testing
yield testing_client
# tear down
with app.app_context():
db.session.remove()
db.drop_all()
ctx.pop()
Мне интересно, почему я не могу просто загрузить файл .env с такой строкой load_dotenv(path/to/.env)
где-нибудь в настройке устройства и готово?
Может кто-нибудь объяснить мне как новичку, как читать переменные .env простым способом для работы с pytest?
Единственный способ, который действительно работает для меня, — это передавать переменные среды в командной строке при запуске тестов.
FROM_EMAIL="some@email.com" MAILGUN_DOMAIN="sandbox6420919ab29b4228sdfda9d43ff37f7689072.mailgun.org" MAILGUN_API_KEY="245d6d0asldlasdkjfc380fba7fbskfsj1ad3125649esadbf2-7cd1ac2b-47fb3ac2" pytest tests
Но это ужасный способ, и я не хочу записывать все эти переменные в командную строку каждый раз, когда я запускаю тесты.
Я просто хочу написать pytest test
, файл .env должен быть загружен где-то автоматически, я полагаю. Но где и как?
Любая помощь приветствуется.
Комментарии:
1. как насчет использования
def setup_class(cls):
и загрузки файла?2. где? разве настройка не выполняется в устройстве? все перед выходом — это «настройка» .. нет?
3. Вы можете использовать python-dotenv для чтения файла env и сделать это в привязке к сеансу (с
autouse=True
).4. Можете ли вы быть более конкретным? Потому что это то, что я пытался сделать в своем устройстве. Вот почему я также спросил: почему я не могу просто загрузить файл .env со строкой, подобной этой load_dotenv(путь / к /.env) где-нибудь в настройке устройства — это просто не сработало
5. Не уверен, что вы сделали по-другому, но я просто протестировал это, как показано в ответе, и у меня все работает нормально.
Ответ №1:
Если вы установите python-dotenv, вы можете использовать его для загрузки переменных из .env
файла. Вот минимальный пример:
.env
SQLALCHEMY_DATABASE_URI="sqlite:///"
JWT_SECRET_KEY="testing"
test.py
import os
import pytest
from dotenv import load_dotenv
@pytest.fixture(scope='session', autouse=True)
def load_env():
load_dotenv()
@pytest.fixture(autouse=True)
def test_client_db():
print(f"nSQLALCHEMY_DATABASE_URI"
f"={os.environ.get('SQLALCHEMY_DATABASE_URI')}")
print(f"JWT_SECRET_KEY={os.environ.get('JWT_SECRET_KEY')}")
def test():
pass
python -m pytest -s test.py
дает:
============================================ test session starts ============================================
...
collected 1 item
test.py
SQLALCHEMY_DATABASE_URI=sqlite:///
JWT_SECRET_KEY=testing
.
============================================= 1 passed in 0.27s =============================================
например, переменные среды устанавливаются на протяжении всего сеанса тестирования и могут использоваться для настройки вашего приложения. Обратите внимание, что я не указал путь в load_dotenv()
, потому что я поместил .env
файл в тот же каталог, что и тест — в вашем коде вам, вероятно, придется добавить путь ( load_dotenv(dotenv_path=your_path)
).
Комментарии:
1. ну, да, это работает так, как вы описали. На самом деле моя проблема была в другом месте. У меня есть несколько переменных env, инкапсулированных в класс, и мне нужно было поместить строку load_dotenv(dotenv_path=your_path) непосредственно в этот класс. Иметь его только в fixture было недостаточно.
2. Не уверен, что я это понимаю, но вы, кажется, нашли решение, так что это решено для вас, верно?
Ответ №2:
Вы можете использовать инструмент monkeypatch, предоставляемый pytest, для управления переменными env:
@pytest.fixture(scope="function")
def configured_env(monkeypatch):
monkeypatch.setenv("SQLALCHEMY_DATABASE_URI", "sqlite:///")
monkeypatch.setenv("JWT_SECRET_KEY", testing)
def test_client(configured_env):
#env variables are set here