所以我尝试为我的Flask应用程序编写一些测试几天,但我无法让它运行。测试通过,但它被困在PASSED。
我克隆了cookiecutter-flask(cookiecutter-flask)并且它与pytest一起运行webtest(我认为)。我的 conftest.py 与回购中的内容相同(conftest.py)
这些是我目前的测试:
def test_app(testapp):
app = create_app(TestConfig)
res = testapp.get('/')
res.status_code == 200
这个过程继续。
def test_create_admin_user(db, testapp):
password = bcrypt.generate_password_hash('test')
User.create(
uid='00000000000000000000',
email='john@doe.com',
password=password,
active=1
)
user = User.query.filter_by(email='j@d.com').first()
assert user.email == 'j@d.com'
这是我丢失的地方,测试卡在PASSED上并且没有做任何事情。当我强制中断这个过程时,我得到了这个:
Traceback (most recent call last):
File "manage.py", line 68, in <module>
manager.run()
File "/home/johan/Development/venv_python/local/lib/python2.7/site-packages/flask_script/__init__.py", line 412, in run
result = self.handle(sys.argv[0], sys.argv[1:])
File "/home/johan/Development/venv_python/local/lib/python2.7/site-packages/flask_script/__init__.py", line 383, in handle
res = handle(*args, **config)
File "/home/johan/Development/venv_python/local/lib/python2.7/site-packages/flask_script/commands.py", line 216, in __call__
return self.run(*args, **kwargs)
File "/home/johan/Development/venv_python/local/lib/python2.7/site-packages/flask/ctx.py", line 386, in __exit__
self.auto_pop(exc_value)
File "/home/johan/Development/venv_python/local/lib/python2.7/site-packages/flask/ctx.py", line 374, in auto_pop
self.pop(exc)
File "/home/johan/Development/venv_python/local/lib/python2.7/site-packages/flask/ctx.py", line 357, in pop
% (rv, self)
AssertionError: Popped wrong request context. (<RequestContext 'http://localhost/' [GET] of backend.app> instead of <RequestContext 'http://localhost/' [GET] of backend.app>)
我在烧瓶中找到了关于测试的以下主题(授予,这是Flask-Testing,但我认为它有一些相关性,也许它没有:issue)并改变了我的test-config所以它包含 PRESERVE_CONTEXT_ON_EXCEPTION = False 但它仍然只是挂起。
有人有任何我可以尝试的想法吗? 我对测试本身并不是很熟悉所以它可能是我做错了。
答案 0 :(得分:1)
db
提供的flask-cookiecutter
夹具很容易锁定,这可能是我的测试挂起的问题(当我第一次开始编写测试时就是这种情况基于flask-cookiecutter
的应用)。
这里有一个更好的db
灯具(替换tests/conftest.py
文件中的灯具):
@pytest.yield_fixture(scope='function')
def db(app):
_db.app = app
with app.app_context():
_db.session.remove()
_db.drop_all()
_db.create_all()
yield _db
_db.session.remove()
_db.drop_all()
## This dispose() call is needed to avoid the DB locking
## between tests.
## Thanks to:
## http://stackoverflow.com/a/18293157/2066849
_db.get_engine(_db.app).dispose()
也可能是应用程序上下文的问题,但这并不像DB会话那样完全挂起测试。
您还应该考虑将此灯具(以及大多数其他灯具)更改为scope='session'
,因此不必为每个单独的测试重新创建数据库(因此应用不会&# 39;必须重新实例化,尽管与DB相比,这是一个微不足道的开销。但是,在修改数据库记录的单个测试之后,您必须手动进行一些清理。
答案 1 :(得分:0)
您需要使用正确的应用上下文
def test_create_admin_user(db, testapp):
with app.app_context():
password = bcrypt.generate_password_hash('test')
User.create(
uid='00000000000000000000',
email='john@doe.com',
password=password,
active=1
)
user = User.query.filter_by(email='j@d.com').first()
assert user.email == 'j@d.com'
有关完整示例,请参阅https://github.com/Leo-G/Flask-Scaffold/blob/master/scaffold/app/tests.py