Flask test_client removes query string parameters
I've just found out a workaround.
Make
data = { 'param1': 'somevalue1', 'param2': 'somevalue2'}response = self.client.get(url_for("api.my-service", **data))
into this:
data = { 'param1': 'somevalue1', 'param2': 'somevalue2'}response = self.client.get(url_for("api.my-service"), query_string = data)
This works but seems a bit unintuitive, and debugging there is a place where the provided query string in the URI is thrown away ....
But anyway this works for the moment.
I know this is an old post, but I ran into this too. There's an open issue about this in the flask github repository. It appears this is intended behavior. From a response in the issue thread:
mitsuhiko commented on Jul 24, 2013
That's currently intended behavior. The first parameter to the test client should be a relative url. If it's not, then the parameters are removed as it's treated as if it was url joined with the second. This works:
>>> from flask import Flask, request>>> app = Flask(__name__)>>> app.testing = True>>> @app.route('/')... def index():... return request.url... >>> c = app.test_client()>>> c.get('/?foo=bar').data'http://localhost/?foo=bar'
One way to convert your absolute url into a relative url and keep the query string is to use urlparse:
from urlparse import urlparseabsolute_url = "http://someurl.com/path/to/endpoint?q=test"parsed = urlparse(absolute_url)path = parsed[2] or "/"query = parsed[4]relative_url = "{}?{}".format(path, query)print relative_url
For me the solution was to use the client within with
statements:
with app.app_context(): with app.test_request_context(): with app.test_client() as client: client.get(...)
instead of
client = app.test_client()client.get(...)
I put the creation of the test client in a fixture, so that it is "automatically" created for each test method:
from my_back_end import MyBackEndsut = Noneapp = Noneclient = None@pytest.fixture(autouse=True)def before_each(): global sut, app, client sut = MyBackEnd() app = sut.create_application('frontEndPathMock') with app.app_context(): with app.test_request_context(): with app.test_client() as client: yield