Как загрузить переменные из файла .env для pytests

#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