测试时访问 Flask 配置时出错
Error while accessing Flask config while testing
在为我的 Flask 应用程序编写测试时,我在尝试设置 Flask 配置设置时遇到了一个问题。
通常,我是这样做的:
import unittest
from factory import create_app
class ConfigTests(unittest.TestCase):
def setUp(self):
app = create_app('flask_test.cfg')
app.testing = True
self.app = app.test_client()
def test_app_is_development(self):
self.assertTrue(self.app.config['SECRET_KEY'] is 'secret_key')
self.assertTrue(self.app.config['DEBUG'] is True)
这导致了错误
AttributeError: 'FlaskClient' object has no attribute 'config'
仅通过调试,我发现没有 "config" 属性,而我必须去 self.app.application.config
才能让它工作。
import unittest
from factory import create_app
class ConfigTests(unittest.TestCase):
def setUp(self):
app = create_app('flask_test.cfg')
app.testing = True
self.app = app.test_client()
def test_app_is_development(self):
self.assertTrue(self.app.application.config['SECRET_KEY'] is 'secret_key')
self.assertTrue(self.app.application.config['DEBUG'] is True)
我在做什么,Flask 是否在更新中更改了它,或者是否有更好的方法来做到这一点?
编辑:错误地在顶部块中发布代码,现在是正确的
生产中的 app
是 flask.app.Flask
类型,而您在测试中使用的是 flask.testing.FlaskClient
类型,这是两个不同的对象。使用 self.app.application.config
访问配置的方式是正确且唯一的方式,因为我相信当你设置 self.app = app.test_client()
这个 returns 一个 FlaskClient 实例时。
看看流水:FlaskClient and test_client
这里有一个提示,您可以在测试客户端本身时执行此操作:
import unittest
from app import app
class Tests(unittest.TestCase):
# setup client
def setUp(self):
self.client = app.test_client()
# generating proposital error to see methods available by self.client
def test_app_configs(self):
print(dir(self.client))
self.assertEqual(False, True)
所以在终端中执行 py.test
,结果是:
self = <test_app.Tests testMethod=test_if_inside_aws>
def test_app_configs(self):
print(dir(self.client))
> self.assertEqual(False, True)
E AssertionError: False != True
src/test_app.py:29: AssertionError
--------------------------------------------------- Captured stdout call ---------------------------------------------------
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'allow_subdomain_redirects', 'application', 'cookie_jar', 'delete', 'delete_cookie', 'environ_base', 'get', 'head', 'open', 'options', 'patch', 'post', 'preserve_context', 'put', 'resolve_redirect', 'response_wrapper', 'run_wsgi_app', 'session_transaction', 'set_cookie', 'trace']
================================================= short test summary info ==================================================
FAILED src/test_app.py::Tests::test_app_configs - AssertionError: False != True
正如上面提到的@gyx-hh,self.client
有一个application
方法可用。现在,执行相同的过程,但现在用于检查 self.client.application
:
的方法
['__call__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_before_request_lock', '_blueprint_order', '_find_error_handler', '_get_exc_class_and_code', '_got_first_request', '_register_error_handler', '_static_folder', '_static_url_path', 'add_template_filter', 'add_template_global', 'add_template_test', 'add_url_rule', 'after_request', 'after_request_funcs', 'app_context', 'app_ctx_globals_class', 'auto_find_instance_path', 'before_first_request', 'before_first_request_funcs', 'before_request', 'before_request_funcs', 'blueprints', 'cli', 'config', 'config_class', 'context_processor', 'create_global_jinja_loader', 'create_jinja_environment', 'create_url_adapter', 'debug', 'default_config', 'dispatch_request', 'do_teardown_appcontext', 'do_teardown_request', 'endpoint', 'env', 'error_handler_spec', 'errorhandler', 'extensions', 'finalize_request', 'full_dispatch_request', 'get_send_file_max_age', 'got_first_request', 'handle_exception', 'handle_http_exception', 'handle_url_build_error', 'handle_user_exception', 'has_static_folder', 'import_name', 'inject_url_defaults', 'instance_path', 'iter_blueprints', 'jinja_env', 'jinja_environment', 'jinja_loader', 'jinja_options', 'json_decoder', 'json_encoder', 'log_exception', 'logger', 'make_config', 'make_default_options_response', 'make_null_session', 'make_response', 'make_shell_context', 'name', 'open_instance_resource', 'open_resource', 'open_session', 'permanent_session_lifetime', 'preprocess_request', 'preserve_context_on_exception', 'process_response', 'propagate_exceptions', 'raise_routing_exception', 'register_blueprint', 'register_error_handler', 'request_class', 'request_context', 'response_class', 'root_path', 'route', 'run', 'save_session', 'secret_key', 'select_jinja_autoescape', 'send_file_max_age_default', 'send_static_file', 'session_cookie_name', 'session_interface', 'shell_context_processor', 'shell_context_processors', 'should_ignore_error', 'static_folder', 'static_url_path', 'subdomain_matching', 'teardown_appcontext', 'teardown_appcontext_funcs', 'teardown_request', 'teardown_request_funcs', 'template_context_processors', 'template_filter', 'template_folder', 'template_global', 'template_test', 'templates_auto_reload', 'test_cli_runner', 'test_cli_runner_class', 'test_client', 'test_client_class', 'test_request_context', 'testing', 'trap_http_exception', 'try_trigger_before_first_request_functions', 'update_template_context', 'url_build_error_handlers', 'url_default_functions', 'url_defaults', 'url_map', 'url_map_class', 'url_rule_class', 'url_value_preprocessor', 'url_value_preprocessors', 'use_x_sendfile', 'view_functions', 'wsgi_app']
然后现在有很多你通常需要的东西,还有config
属性。
在为我的 Flask 应用程序编写测试时,我在尝试设置 Flask 配置设置时遇到了一个问题。
通常,我是这样做的:
import unittest
from factory import create_app
class ConfigTests(unittest.TestCase):
def setUp(self):
app = create_app('flask_test.cfg')
app.testing = True
self.app = app.test_client()
def test_app_is_development(self):
self.assertTrue(self.app.config['SECRET_KEY'] is 'secret_key')
self.assertTrue(self.app.config['DEBUG'] is True)
这导致了错误
AttributeError: 'FlaskClient' object has no attribute 'config'
仅通过调试,我发现没有 "config" 属性,而我必须去 self.app.application.config
才能让它工作。
import unittest
from factory import create_app
class ConfigTests(unittest.TestCase):
def setUp(self):
app = create_app('flask_test.cfg')
app.testing = True
self.app = app.test_client()
def test_app_is_development(self):
self.assertTrue(self.app.application.config['SECRET_KEY'] is 'secret_key')
self.assertTrue(self.app.application.config['DEBUG'] is True)
我在做什么,Flask 是否在更新中更改了它,或者是否有更好的方法来做到这一点?
编辑:错误地在顶部块中发布代码,现在是正确的
生产中的 app
是 flask.app.Flask
类型,而您在测试中使用的是 flask.testing.FlaskClient
类型,这是两个不同的对象。使用 self.app.application.config
访问配置的方式是正确且唯一的方式,因为我相信当你设置 self.app = app.test_client()
这个 returns 一个 FlaskClient 实例时。
看看流水:FlaskClient and test_client
这里有一个提示,您可以在测试客户端本身时执行此操作:
import unittest
from app import app
class Tests(unittest.TestCase):
# setup client
def setUp(self):
self.client = app.test_client()
# generating proposital error to see methods available by self.client
def test_app_configs(self):
print(dir(self.client))
self.assertEqual(False, True)
所以在终端中执行 py.test
,结果是:
self = <test_app.Tests testMethod=test_if_inside_aws>
def test_app_configs(self):
print(dir(self.client))
> self.assertEqual(False, True)
E AssertionError: False != True
src/test_app.py:29: AssertionError
--------------------------------------------------- Captured stdout call ---------------------------------------------------
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'allow_subdomain_redirects', 'application', 'cookie_jar', 'delete', 'delete_cookie', 'environ_base', 'get', 'head', 'open', 'options', 'patch', 'post', 'preserve_context', 'put', 'resolve_redirect', 'response_wrapper', 'run_wsgi_app', 'session_transaction', 'set_cookie', 'trace']
================================================= short test summary info ==================================================
FAILED src/test_app.py::Tests::test_app_configs - AssertionError: False != True
正如上面提到的@gyx-hh,self.client
有一个application
方法可用。现在,执行相同的过程,但现在用于检查 self.client.application
:
['__call__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_before_request_lock', '_blueprint_order', '_find_error_handler', '_get_exc_class_and_code', '_got_first_request', '_register_error_handler', '_static_folder', '_static_url_path', 'add_template_filter', 'add_template_global', 'add_template_test', 'add_url_rule', 'after_request', 'after_request_funcs', 'app_context', 'app_ctx_globals_class', 'auto_find_instance_path', 'before_first_request', 'before_first_request_funcs', 'before_request', 'before_request_funcs', 'blueprints', 'cli', 'config', 'config_class', 'context_processor', 'create_global_jinja_loader', 'create_jinja_environment', 'create_url_adapter', 'debug', 'default_config', 'dispatch_request', 'do_teardown_appcontext', 'do_teardown_request', 'endpoint', 'env', 'error_handler_spec', 'errorhandler', 'extensions', 'finalize_request', 'full_dispatch_request', 'get_send_file_max_age', 'got_first_request', 'handle_exception', 'handle_http_exception', 'handle_url_build_error', 'handle_user_exception', 'has_static_folder', 'import_name', 'inject_url_defaults', 'instance_path', 'iter_blueprints', 'jinja_env', 'jinja_environment', 'jinja_loader', 'jinja_options', 'json_decoder', 'json_encoder', 'log_exception', 'logger', 'make_config', 'make_default_options_response', 'make_null_session', 'make_response', 'make_shell_context', 'name', 'open_instance_resource', 'open_resource', 'open_session', 'permanent_session_lifetime', 'preprocess_request', 'preserve_context_on_exception', 'process_response', 'propagate_exceptions', 'raise_routing_exception', 'register_blueprint', 'register_error_handler', 'request_class', 'request_context', 'response_class', 'root_path', 'route', 'run', 'save_session', 'secret_key', 'select_jinja_autoescape', 'send_file_max_age_default', 'send_static_file', 'session_cookie_name', 'session_interface', 'shell_context_processor', 'shell_context_processors', 'should_ignore_error', 'static_folder', 'static_url_path', 'subdomain_matching', 'teardown_appcontext', 'teardown_appcontext_funcs', 'teardown_request', 'teardown_request_funcs', 'template_context_processors', 'template_filter', 'template_folder', 'template_global', 'template_test', 'templates_auto_reload', 'test_cli_runner', 'test_cli_runner_class', 'test_client', 'test_client_class', 'test_request_context', 'testing', 'trap_http_exception', 'try_trigger_before_first_request_functions', 'update_template_context', 'url_build_error_handlers', 'url_default_functions', 'url_defaults', 'url_map', 'url_map_class', 'url_rule_class', 'url_value_preprocessor', 'url_value_preprocessors', 'use_x_sendfile', 'view_functions', 'wsgi_app']
然后现在有很多你通常需要的东西,还有config
属性。