简体   繁体   English

Flask单元测试如何加载环境变量

[英]How to load environment variables in Flask unit test

I'm trying to test an app which relies on several environment variables (API keys, mostly).我正在尝试测试依赖于多个环境变量(主要是 API 密钥)的应用程序。 I'd like to keep those as variables instead of putting them directly into a config file, but my unit tests (using unittest ) won't run because the environment variables aren't loaded when the test mounts.我想将它们保留为变量而不是将它们直接放入配置文件中,但我的单元测试(使用unittest )不会运行,因为在测试安装时未加载环境变量。

I've tried calling load_dotenv in setUp (see below) but that doesn't make a difference.我试过在setUp中调用load_dotenv (见下文),但这没有什么区别。 How can I ensure that the test suite reads the environment variables correctly?如何确保测试套件正确读取环境变量?

.flaskenv .flaskenv

FLASK_APP=myapp.py
BASE_URI='https://example.com'
OTHER_API_KEY='abc123itsasecret'

config.py配置.py

import os
basedir = os.path.abspath(os.path.dirname(__file__))

class Config(object):
    SQLALCHEMY_DATABASE_URI = "sqlite:///"
    API_URL = os.environ.get('BASE_URI') + "/api/v1"
    SECRET_KEY = os.environ.get('OTHER_API_KEY')

test_file.py测试文件.py

import os
from dotenv import load_dotenv
import config

basedir = os.path.abspath(os.path.dirname(__file__))

class TestTheThing(unittest.TestCase):
    def setUp(self):
        load_dotenv(os.path.join(basedir, '.flaskenv'))
        app.config.from_object(config.Config)
        app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite://"
        db.create_all()
        self.client = app.test_client()

In the console after running python -m unittest myapp.test_file在运行后的控制台中python -m unittest myapp.test_file

File "/../../package/config.py", line 29, in Config
    'API_URL': os.environ.get('BASE_URI') + 'api/v1/',
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

After reading more, I realized that I needed to load the variables in my config file, not in the test runner.阅读更多之后,我意识到我需要在我的配置文件中加载变量,而不是在测试运行器中。 Adding load_dotenv to the top of the config file allowed tests to run.load_dotenv添加到配置文件的顶部允许测试运行。

config.py配置.py

import os
from dotenv import load_dotenv

basedir = os.path.abspath(os.path.dirname(__file__))

load_dotenv(os.path.join(basedir, '.flaskenv'))
# rest of file

I spent time trying to figure out where the crash was happening.我花了很多时间试图找出崩溃发生的地方。 I added a breakpoint inside setUp that never got hit, so it had to be earlier in the execution.我在setUp中添加了一个从未被击中的断点,因此它必须在执行的早期。

Reading the stack trace more carefully, it was caused by importing app at the top of the test file.仔细阅读堆栈跟踪,这是由在测试文件顶部导入app引起的。 When the app is imported, it tries to pull all the variables in before it could call load_dotenv inside setUp .导入应用程序时,它会尝试在调用setUp中的load_dotenv之前拉入所有变量。 Loading environment variables before the config object was loaded into the Flask object cleared it up.在将配置 object 加载到 Flask object 之前加载环境变量将其清除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM