I am having a really weird issue implementing tests for my Flask app. I am using a session scoped test_client
to run all my tests. I am implementing tests for user registration and logging in. If I comment out my registration test and execute the login test, the test completes successfully. However, if I run a test_register followed by a test_login, the test fails. Below is my code for the tests
def test_valid_register(client, db):
response = register(client, db, 'testuser123', 'password', 'password')
assert response.status_code == 200
assert db.session.query(User).filter(User.username == 'testuser123').first()
assert b'Dashboard' in response.data
logout(client)
def test_valid_login(client, db):
USERNAME = 'user1'
PASSWORD = 'pa$$w0rd'
response = login(client, db, USERNAME, PASSWORD)
assert response.status_code == 200
with client.session_transaction(subdomain='test_domain') as session:
assert session['username'] == USERNAME
assert session['user_id'] == db.session.query(User).filter( \
User.username == USERNAME).first().get_id()
assert b'Dashboard' in response.data
And my utility functions for login and register
def register(client, db, username, password, confirm_password):
with client.session_transaction(subdomain='test_domain') as session:
user_entity = db.session.query(User).filter( \
User.username == username).first()
if not user_entity and password == confirm_password:
session['username'] = username
else:
session['username'] = None
session['user_id'] = None
return client.post(
'/register', data={
'username' : username,
'password' : password,
'confirm_password' : confirm_password
},
follow_redirects=True
)
def login(client, db, username, password):
# Simulates a session and sets the session KV pairs accordingly
with client.session_transaction(subdomain='test_domain') as session:
user_entity = db.session.query(User).filter( \
User.username == username).first()
session['username'] = username if user_entity and user_entity.check_password(password) else None
session['user_id'] = user_entity.get_id() if user_entity and user_entity.check_password(password) else None
return client.post(
'/login', data={
'username' : username,
'password' : password
},
follow_redirects=True
)
The program flow is as such - When a user registers a valid account, he will be redirected to a user dashboard page (follow_redirects) with an automatic login and session simulated as shown. In this case, If I exclude the register
test and execute the login
test only, the test passes. Individually the tests are working fine but when put together it fails.
I have implemented a logging system in my main Flask app that have logged the following messages
DEBUG app:routes.py:81 Entering login function
DEBUG app:routes.py:93 Successfully logged in user User ID: 8 -- Username: user1
INFO app:routes.py:120 Entering dashboard home..
WARNING app:routes.py:122 Anonymous user in dashboard home, going to index..
It would seem like the register test have passed successfully and entered the test_valid_login
test, in which the user have actually successfully authenticated in line 2 of the log and entered in to the home. However, I do have a check to redirect anonymous users attempting to access my dashboard
route back to index which is exactly what is happening right now.
If I execute the valid_login
test alone this behavior does not happen. I am not very sure what has gone wrong - previously before I implemented the session
simulation the tests were all working fine but I am not very sure if this is causing the tests to fail and why.
Below is my PyTest conftest
file -
@pytest.fixture(scope='session')
def app():
yield flask_app
@pytest.fixture(scope='session')
def client(app):
# WTF_CSRF_ENABLED = False to allow form submission in tests
app.config['WTF_CSRF_ENABLED'] = False
app.config['TESTING'] = True
return app.test_client()
@pytest.fixture(scope='session')
def db():
yield ps_db
And this is the dashboard
route failing the test -
@app.route('/dashboard', methods=['GET'])
def dashboard():
logger.info("Entering dashboard home..")
if current_user.is_anonymous:
logger.warning("Anonymous user in dashboard home, going to index..")
return redirect(url_for('index'))
Even though I am not using current_user
from flask_login
, the login test have passed without much issues until the register test comes in before it.
Any help will be greatly appreciated. Just to clarify, I have a teardown script to remove the newly registered user after each test so the entry into the database will always be valid for registrations.
Aucun commentaire:
Enregistrer un commentaire