简体   繁体   中英

Why use Flask's app.test_client() over requests.Session() for testing

If requests.Session() can handle cookies and does almost everything that app.test_client() does. Then why use the app.test_client() ?

After a bit of digging around, I think I found a good reason to use app.test_client() as well as some other context managers that are provided by Flask.

Test Client

app.test_client()

Enables you to access local contexts via its context manager This is extremely helpful when trying to access variables on the _request_ctx_stack ( request context stack). eg the request and session context locals.

Some extensions also store variables on the _request_ctx_stack . eg flask_login stores the current_user and flask_stateless_auth stores the current_stateless_user on the request context stack.

from flask import request
from flask_stateless_auth import current_stateless_user

with app.test_client() as c:
  test_path = '/resource_for_authenticated_users'
  c.get(test_path)
  assert request.path == test_url
  assert flask.session is not None # You can also access the session context local from here
  assert current_stateless_user is not None

If this was called without the test_client() context manager, it would throw a runtime error for trying to access the request local context after the _request_ctx_stack has been popped. Also, current_stateless_user would return None

App Context

app.app_context()

Similarly, you can access variables that are stored on the app context via the app.app_context() context manager, as such:

from my_app.db import db # db connections are commonly stored on the `_app_ctx_stack`

with app.app_context():
  db.create_tables()
  assert db.session
  assert db.query.MyTable.all()

You can also access app context global variable (typically used to store app related global variables that are not be used across multiple requests like the session global)

with app.app_context():
  assert g.my_global_app_var

Test Request Context

test_request_context()

Then you have the app.test_request_context() context manager which is used to activate a request context temporarily. This is best explained by the official docs .

Session Transaction Context

app.test_client().session_transaction()

Finally, there's the session_transaction() context manager. This is typically used to modify a session object. This should be nested in an app.test_client() .

When the __exit__() method is called, the session is safely stored.

example from docs :

with app.test_client() as c:
     with c.session_transaction() as sess:
         sess['a_key'] = 'a value'

    # once this is reached the session was stored

test_client is already prebuilt into flask, this makes it easier for people to quickly test their programs. Both the requests utility and test_client server the same functionality, so the usage is just based on personal preference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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