[英]Flask testing with pytest, ENV is set to production?
I have built a flask app and i would like to create a test suite.我已经构建了一个烧瓶应用程序,我想创建一个测试套件。 Reading around it looks like pytest is the way to go;阅读它看起来像 pytest 是要走的路; however, I am finding it very difficult to understand how to get going, I have looked at https://flask.palletsprojects.com/en/2.0.x/testing/ but am struggling to relate it to my app.但是,我发现很难理解如何开始,我查看了https://flask.palletsprojects.com/en/2.0.x/testing/但我很难将它与我的应用程序联系起来。
my project has a run.py at its base:我的项目在其基础上有一个 run.py:
from wahoo_connect import init_app, db
from flask_migrate import Migrate
#run the app
app = init_app()
migrate = Migrate(app, db)
this is run using flask run and the .flaskenv sets the mode这是使用 flask run 运行的,.flaskenv 设置模式
FLASK_APP=run.py
#FLASK_ENV=production
FLASK_ENV=development
I have an application factory set up:我设置了一个应用程序工厂:
"""Main entry point into App"""
#import libraries
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
from flask_mail import Mail
#from flask_caching import Cache
from flask_session import Session
from os import path, mkdir
import logging
from logging.handlers import SMTPHandler, RotatingFileHandler
"""Flask Global Variables"""
#database connection
db = SQLAlchemy()
migrate = Migrate()
#login manager
login = LoginManager()
login.login_view = 'auth_bp.login'
login.login_message = 'Please log in to access this page.'
login.login_message_category = "info"
#email
mail = Mail()
#cache
#cache = Cache()
#session
sess = Session()
#initialise app
def init_app():
"""Initialize the core application."""
app = Flask(__name__)
print(app.config['ENV'])
if app.config['ENV'] == 'production':
app.config.from_object('wahoo_connect.config.ProductionConfig')
elif app.config['ENV'] == 'development':
app.config.from_object('wahoo_connect.config.DevelopmentConfig')
elif app.config['ENV'] == 'testing':
app.config.from_object('wahoo_connect.config.TestingConfig')
# Initialize Plugins
db.init_app(app)
migrate.init_app(app, db)
login.init_app(app)
mail.init_app(app)
# cache.init_app(app)
sess.init_app(app)
with app.app_context():
# Import and Register Blueprints
from wahoo_connect.errors.views import errors_bp
from wahoo_connect.auth.views import auth_bp
from wahoo_connect.profile.views import profile_bp
from wahoo_connect.wahoo.views import wahoo_bp
from wahoo_connect.home.views import home_bp
app.register_blueprint(errors_bp)
app.register_blueprint(auth_bp, url_prefix='/auth')
app.register_blueprint(profile_bp)
app.register_blueprint(wahoo_bp, url_prefix='/wahoo')
app.register_blueprint(home_bp)
if not app.debug:
#log to email
if app.config['MAIL_SERVER']:
auth = None
if app.config['MAIL_USERNAME'] or app.config['MAIL_PASSWORD']:
auth = (app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])
secure = None
if app.config['MAIL_USE_TLS']:
secure = ()
mail_handler = SMTPHandler(
mailhost=(app.config['MAIL_SERVER'], app.config['MAIL_PORT']),
fromaddr=app.config['MAIL_USERNAME'],
toaddrs=app.config['ADMINS'],
subject='Error in Wahoo-Connect',
credentials=auth, secure=secure)
mail_handler.setLevel(logging.ERROR)
app.logger.addHandler(mail_handler)
#log to file - heroku
if app.config['LOG_TO_STDOUT']:
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
app.logger.addHandler(stream_handler)
else:
logdir = path.dirname(app.instance_path) + '/logs'
if not path.exists(logdir):
mkdir(logdir)
file_handler = RotatingFileHandler(logdir + '/wahoo-connect.log',
maxBytes=10240, backupCount=10)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s '
'[in %(pathname)s:%(lineno)d]'))
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('Wahoo-Connect Startup')
return app
from wahoo_connect import models
Everything works and I can run the app on a production server.一切正常,我可以在生产服务器上运行该应用程序。 I am trying to get started with pytest and have set up conftest.py:我正在尝试开始使用 pytest 并设置了 conftest.py:
import pytest
from wahoo_connect import init_app
from wahoo_connect.models import User
@pytest.fixture(scope="session")
def app():
app = init_app()
return app
this always runs the app in production mode, how do I get it to run in testing mode so that it uses the correct config from config.py这总是在生产模式下运行应用程序,我如何让它在测试模式下运行,以便它使用 config.py 中的正确配置
"""Flask configuration."""
from os import environ, path
from dotenv import load_dotenv
from datetime import timedelta
#basedir = path.abspath(path.dirname(__file__))
basedir = path.dirname(path.dirname(path.abspath(__file__)))
load_dotenv(path.join(basedir, '.env'))
class Config(object):
"""Base config."""
DEBUG = False
TESTING = False
SECRET_KEY = environ.get('SECRET_KEY') or 'topsecretkey'
STATIC_FOLDER = 'static'
TEMPLATES_FOLDER = 'templates'
SESSION_COOKIE_SECURE = True
#Database
SQLALCHEMY_DATABASE_URI = environ.get('DATABASE_URL') or \
'sqlite:///' + path.join(basedir, 'app.db')
#fix for heroku postgres db
if SQLALCHEMY_DATABASE_URI.startswith("postgres://"):
SQLALCHEMY_DATABASE_URI = SQLALCHEMY_DATABASE_URI.replace("postgres://", "postgresql://", 1)
SQLALCHEMY_TRACK_MODIFICATIONS = False
#Wahoo
WAHOO_CLIENT_ID=environ.get('WAHOO_CLIENT_ID')
WAHOO_CLIENT_SECRET=environ.get('WAHOO_CLIENT_SECRET')
WAHOO_CLIENT_REDIRECT=environ.get('WAHOO_CLIENT_REDIRECT')
#Email
MAIL_SERVER = environ.get('MAIL_SMTP_SERVER')
MAIL_PORT = int(environ.get('MAIL_SMTP_PORT') or 25)
MAIL_USERNAME = environ.get('MAIL_SMTP_LOGIN')
MAIL_PASSWORD = environ.get('MAIL_SMTP_PASSWORD')
MAIL_USE_TLS = environ.get('MAIL_USE_TLS') is not None
ADMINS = ['martyndwheeler@gmail.com']
#Logging
LOG_TO_STDOUT = environ.get('LOG_TO_STDOUT') or None
# Flask-Caching related configs
CACHE_TYPE = 'FileSystemCache'
CACHE_DIR = environ.get('CACHE_DIR') or None
CACHE_DEFAULT_TIMEOUT = 300
CACHE_THRESHOLD = 100
# Flask-Session related configs
SESSION_PERMANENT = False
PERMANENT_SESSION_LIFETIME = timedelta(minutes=30)
SESSION_USE_SIGNER = True
SESSION_TYPE = "filesystem"
SESSION_FILE_DIR = environ.get('SESSION_FILE_DIR')
SESSION_FILE_THRESHOLD = 100
class ProductionConfig(Config):
pass
class DevelopmentConfig(Config):
DEBUG = True
SESSION_COOKIE_SECURE = False
class TestingConfig(Config):
TESTING = True
SESSION_COOKIE_SECURE = False
If there is a good tutorial that I have missed I'd be pleased to hear.如果有我错过的好教程,我会很高兴听到。
Thank you in advance.先感谢您。
Martyn马丁
#test.py
from os import environ
print(environ.get("ENV_VAR")) # Output : test
#.env
ENV_VAR=test
You can use this to store an Boolean in .env file and read it to define wich mode you are running.您可以使用它在 .env 文件中存储一个布尔值并读取它来定义您正在运行的模式。 be careful as env variables get read as string.当 env 变量被读取为字符串时要小心。 if you wanna use boolean you need to parse them from the string.如果你想使用布尔值,你需要从字符串中解析它们。
An other option is to store in env file which config you wanna use and make an if else tree in python script:另一种选择是将您要使用的配置存储在 env 文件中,并在 python 脚本中创建一个 if else 树:
if os.environ.get("CONFIG") == "1":
app.config.from_object("config.conf1")
elif os.environ.get("CONFIG") == "2":
app.config.from_object("config.conf2")
else:
app.config.from_object("config.default")
The advantage of using environment variables is that you can ignore them in git and every time the server is seetup in linux or docker all settings can be managed from one file.使用环境变量的好处是你可以在 git 中忽略它们,每次在 linux 或 docker 中设置服务器时,所有设置都可以从一个文件中管理。 also does the standart server admin know bash script and env files but not necesseraly python.标准服务器管理员也知道 bash 脚本和 env 文件,但不一定知道 python。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.