Testing authentication flows helps make sure users can log in and log out correctly. It checks that only the right people can access protected parts of your app.
Testing authentication flows in Flask
def test_login(client): response = client.post('/login', data={'username': 'user', 'password': 'pass'}) assert response.status_code == 200 assert b'Welcome' in response.data
Use Flask's test client to simulate requests to your app.
Check response status codes and content to confirm correct behavior.
def test_login_success(client): response = client.post('/login', data={'username': 'alice', 'password': 'secret'}) assert response.status_code == 200 assert b'Welcome, alice' in response.data
def test_login_failure(client): response = client.post('/login', data={'username': 'alice', 'password': 'wrong'}) assert response.status_code == 401 assert b'Invalid credentials' in response.data
def test_protected_page_requires_login(client): response = client.get('/dashboard') assert response.status_code == 302 assert '/login' in response.headers['Location']
This Flask app has simple login, dashboard, and logout routes. The test checks logging in with correct and wrong passwords, accessing a protected page, and logging out.
from flask import Flask, request, redirect, url_for, session import pytest app = Flask(__name__) app.secret_key = 'testkey' users = {'bob': 'password123'} @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] if users.get(username) == password: session['user'] = username return f'Welcome, {username}' else: return 'Invalid credentials', 401 return 'Login Page' @app.route('/dashboard') def dashboard(): if 'user' not in session: return redirect(url_for('login')) return f'Dashboard for {session["user"]}' @app.route('/logout') def logout(): session.pop('user', None) return 'Logged out' # Testing @pytest.fixture def client(): app.config['TESTING'] = True with app.test_client() as client: yield client def test_auth_flow(client): # Test login success response = client.post('/login', data={'username': 'bob', 'password': 'password123'}) assert response.status_code == 200 assert b'Welcome, bob' in response.data # Test access to dashboard after login response = client.get('/dashboard') assert response.status_code == 200 assert b'Dashboard for bob' in response.data # Test logout response = client.get('/logout') assert response.status_code == 200 assert b'Logged out' in response.data # Test dashboard redirects after logout response = client.get('/dashboard') assert response.status_code == 302 assert '/login' in response.headers['Location'] # Test login failure response = client.post('/login', data={'username': 'bob', 'password': 'wrongpass'}) assert response.status_code == 401 assert b'Invalid credentials' in response.data
Use Flask's test_client() to simulate browser requests without running the server.
Always check both the HTTP status code and the response content to confirm correct behavior.
Clear session data between tests to avoid false positives.
Testing authentication flows ensures your login system works as expected.
Use Flask's test client to simulate login, logout, and protected page access.
Check status codes and response messages to verify success or failure.
Practice
Solution
Step 1: Understand authentication flow purpose
Authentication flows control user access to secure parts of the app.Step 2: Identify the goal of testing these flows
Testing ensures only users with correct credentials can access protected routes.Final Answer:
To verify that only authorized users can access protected routes -> Option DQuick Check:
Authentication testing = Access control verification [OK]
- Confusing authentication with UI or server startup tests
- Thinking database connection tests are part of authentication
- Assuming authentication tests check layout or styling
Solution
Step 1: Identify HTTP method for login submission
Login forms usually send data via POST requests to submit credentials.Step 2: Match Flask test client method
client.post() simulates POST requests in Flask tests.Final Answer:
client.post() -> Option CQuick Check:
POST request for login = client.post() [OK]
- Using client.get() for login POST requests
- Confusing HTTP methods like PUT or DELETE for login
- Not passing data with the POST request
response.status_code be after a successful login?
response = client.post('/login', data={'username': 'user', 'password': 'pass'}, follow_redirects=True)Solution
Step 1: Understand follow_redirects=True effect
Setting follow_redirects=True makes the client follow redirects and return the final page response.Step 2: Determine status code after successful login with redirect
After login, the app redirects (302) but client follows it, so final response is the redirected page with status 200.Final Answer:
200 -> Option AQuick Check:
follow_redirects=True means final status = 200 [OK]
- Expecting 302 instead of 200 when following redirects
- Confusing 404 or 500 as login response codes
- Ignoring follow_redirects parameter effect
response = client.post('/login', data={'username': 'user'})
assert response.status_code == 200Solution
Step 1: Check login data completeness
Login usually requires both username and password; password is missing here.Step 2: Understand impact on response
Missing password likely causes login failure, so status code 200 may not be returned.Final Answer:
Missing password in data causes login failure -> Option AQuick Check:
Login needs username and password [OK]
- Assuming client.get() is needed for login POST
- Expecting 404 status code on login failure
- Ignoring missing password field
/dashboard redirects unauthorized users to /login. Which test code snippet correctly checks this behavior?Solution
Step 1: Understand protected route behavior
Unauthorized access to /dashboard should redirect (302) to /login.Step 2: Verify test code matches expected behavior
client.get('/dashboard') without login returns 302 redirect; Location header includes '/login'.Final Answer:
response = client.get('/dashboard')\nassert response.status_code == 302\nassert '/login' in response.headers['Location'] -> Option BQuick Check:
Unauthorized access redirects = status 302 + Location header [OK]
- Using POST instead of GET for protected route access
- Expecting 200 status without login
- Checking wrong status code or missing Location header
Ready to prove it?
Pass the test and this pattern moves unknown
