[TestClient][HowTo] Design pytest for a feature that handshakes with an external service then receives a callback. #2626
-
Hello, I'm building a little project which leverages Starlette for ASGI, for my organization. It includes a login feature which is essentially doing open-id token retrieval querying a keycloak instance that manages our keys.
I'm designing a test that covers the case: import json
import requests
from bs4 import BeautifulSoup
@pytest.fixture(scope="session", autouse=True)
def client():
# Some shenanigans to import 'src/example' codebase from 'src/tests'.
cwd = Path(__file__).parent
example = cwd.parent.parent / 'example'
sys.path.append(example)
from example.app import main
with TestClient(app=main(), backend_options={
"use_uvloop": True
}) as c:
yield c
def json_bytes(d: Dict[Any, Any]) -> bytes:
"""Encodes python Dict as utf-8 bytes."""
return json.dumps(d).encode('utf-8')
def test_login_user_on_keycloak_and_get_token(client):
# Create User
user = {"username": "u_test", "password": "1234"}
_ = client.post('/users', content=json_bytes(user))
# Get login page
login_response = client.get('login')
login_url = login_response.text
with requests.Session() as session:
# Get and Parse form with bs
# Courtesy of: https://www.pythonrequests.com/python-requests-keycloak-login/
form_response = session.get(login_url)
soup = BeautifulSoup(form_response.content, 'html.parser')
form = soup.find('form')
action = form['action']
other_fields = {i['name']: i.get('value', '') for i in form.findAll('input', {'type': 'hidden'})}
response = session.post(action, data={
'username': user['username'],
'password': user['password'],
**other_fields,
}, allow_redirects=True)
assert response.status_code == 201 However, the What would be the way to go in order to test such a feature ? Best, |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
You'll need to either run your app as a webserver e.g. via docker compose or, if the keycloak client accept it, pass in your own |
Beta Was this translation helpful? Give feedback.
Well you can't get something that only talks HTTP over a network to talk to TestClient in process. You either make your server talk over the network or you make the thing talk in-process, both of which I suggested above.