You can create a MultiDict, then make it Immutable:
from werkzeug.datastructures
import MultiDict, ImmutableMultiDict
FAKE_EMAILS_AND_NAMES = [{
'email': 'a@a.com',
'name': 'a'
},
{
'email': 'b@b.com',
'name': 'b'
},
]
data = MultiDict()
for x in range(0, len(FAKE_EMAILS_AND_NAMES)):
mock_user = {}
mock_user['primaryEmail'] = FAKE_EMAILS_AND_NAMES[x]['email']
mock_user['name'] = {}
mock_user['name']['fullName'] = FAKE_EMAILS_AND_NAMES[x]['name']
data.add('select_user', mock_user)
data = ImmutableMultiDict(data)
print data
This prints:
ImmutableMultiDict([
('select_user', {
'primaryEmail': 'a@a.com',
'name': {
'fullName': 'a'
}
}),
('select_user', {
'primaryEmail': 'b@b.com',
'name': {
'fullName': 'b'
}
})
])
Python Flask is a framework that makes it easy to create web apps with Python. This guide will use a Flask app as an example and walk you through creating unit tests for it. Even if you don’t use Flask, the unit-testing concepts illustrated are generally applicable.,Unit Testing: Tests small components of the program (units) in isolation. For example, you might test each individual function.,All other pages may no longer function properly. For example, clicking on the About link on the home page will yield an error page. The other pages were removed to simplify this guide and so that we can concentrate on writing unit tests.,However, the c.get_user function is different because it is called more than once. This means we can’t specify a single return value when we mock it. Instead we will have to write the dummy function ourselves and return the user object whose ID matches the parameter. Here is an example:
$ git clone https: //github.com/Code-the-Change/flask_tests_workshop.git
$ pip3 install virtualenv
PATH="<Path from pip message>:$PATH"
export PATH
$ cd flask_tests_workshop $ virtualenv venv $ source venv / bin / activate $ pip install - r requirements.txt
chmod 700 run.sh
. / run.sh
Creates a test client for this application. For information about unit testing head over to Testing Flask Applications.,Register a function to run after each request to this object.,Registers a function to be run before the first request to this instance of the application.,Represents a blueprint, a collection of routes and other app-related functions that can be registered on a real application later.
from flask
import Flask
app = Flask(__name__)
app = Flask('yourapplication')
app = Flask(__name__.split('.')[0])
@app.route("/")
def index():
...
def index():
...
app.add_url_rule("/", view_func = index)
app.add_url_rule("/", endpoint = "index")
@app.endpoint("index")
def index():
...
with app.app_context():
init_db()
Flask provides a way to test your application by exposing the Werkzeug test Client and handling the context locals for you. You can then use that with your favourite testing solution. In this documentation we will use the unittest package that comes pre-installed with Python.,Notice that our test functions begin with the word test; this allows unittest to automatically identify the method as a test to run.,First, we need an application to test; we will use the application from the Flask Tutorial. If you don’t have that application yet, get the sources from the examples.,Even though it did not run any actual tests, we already know that our flaskr application is syntactically valid, otherwise the import would have died with an exception.
import os
import flaskr
import unittest
import tempfile
class FlaskrTestCase(unittest.TestCase):
def setUp(self):
self.db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()
flaskr.app.config['TESTING'] = True
self.app = flaskr.app.test_client()
with flaskr.app.app_context():
flaskr.init_db()
def tearDown(self):
os.close(self.db_fd)
os.unlink(flaskr.app.config['DATABASE'])
if __name__ == '__main__':
unittest.main()
$ python flaskr_tests.py -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Ran 0 tests in 0.000 s OK
class FlaskrTestCase(unittest.TestCase):
def setUp(self):
self.db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()
self.app = flaskr.app.test_client()
flaskr.init_db()
def tearDown(self):
os.close(self.db_fd)
os.unlink(flaskr.app.config['DATABASE'])
def test_empty_db(self):
rv = self.app.get('/')
assert b 'No entries here so far' in rv.data
$ python flaskr_tests.py . -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Ran 1 test in 0.034 s OK
def login(self, username, password):
return self.app.post('/login', data = dict(
username = username,
password = password
), follow_redirects = True)
def logout(self):
return self.app.get('/logout', follow_redirects = True)
def test_login_logout(self):
rv = self.login('admin', 'default')
assert b 'You were logged in' in rv.data
rv = self.logout()
assert b 'You were logged out' in rv.data
rv = self.login('adminx', 'default')
assert b 'Invalid username' in rv.data
rv = self.login('admin', 'defaultx')
assert b 'Invalid password' in rv.data
Pass the query_string argument to c.get, which can either be a dict, a MultiDict, or an already encoded string., Tags: python , testing , flask , unit-testing , flask-testing Answers: 1 | Viewed 10,836 times , 1 week ago 1 Answer. Pass the query_string argument to c.get, which can either be a dict, a MultiDict, or an already encoded string. with app.test_client () as c: r = c.get ('/', query_string= {'name': 'davidism'}) The test client request methods pass their arguments to Werkzeug's EnvironBuilder, which is where this is documented. , Similarly, Flask can be subclassed to override test_request_context: Do not push a test request context globally for all the tests. A new context should be created for each request, and will be handled automatically when making tests requests using client.
with self.app.test_request_context() as req: req.request.args = {
'code': 'mocked access token'
}
MyView()
with app.test_client() as c: r = c.get('/', query_string = {
'name': 'davidism'
})
with self.app.test_request_context() as req: req.request.args = {
'code': 'mocked access token'
}
MyView()
with self.app.test_client() as c: resp = c.get('/myview')
with self.app.test_client() as c: with self.app.test_request_context() as req: req.request.args = {
'code': 'mocked access token'
}
resp = c.get('/myview')
with app.test_client() as c: r = c.get('/', query_string = {
'name': 'davidism'
})
aiohttp provides plugin for pytest making writing web server tests extremely easy, it also provides test framework agnostic utilities for testing with other frameworks such as unittest.,Test server usually works in conjunction with aiohttp.test_utils.TestClient which provides handy client methods for accessing to the server.,aiohttp test utils provides a scaffolding for testing aiohttp-based web servers.,Before starting to write your tests, you may also be interested on reading how to write testable services that interact with the loop.
$ pip install pytest - aiohttp
from aiohttp
import web
async def hello(request):
return web.Response(text = 'Hello, world')
async def test_hello(aiohttp_client, loop):
app = web.Application()
app.router.add_get('/', hello)
client = await aiohttp_client(app)
resp = await client.get('/')
assert resp.status == 200
text = await resp.text()
assert 'Hello, world' in text
import pytest
from aiohttp
import web
async def previous(request):
if request.method == 'POST':
request.app['value'] = (await request.post())['value']
return web.Response(body = b 'thanks for the data')
return web.Response(
body = 'value: {}'.format(request.app['value']).encode('utf-8'))
@pytest.fixture
def cli(loop, aiohttp_client):
app = web.Application()
app.router.add_get('/', previous)
app.router.add_post('/', previous)
return loop.run_until_complete(aiohttp_client(app))
async def test_set_value(cli):
resp = await cli.post('/', data = {
'value': 'foo'
})
assert resp.status == 200
assert await resp.text() == 'thanks for the data'
assert cli.server.app['value'] == 'foo'
async def test_get_value(cli):
cli.server.app['value'] = 'bar'
resp = await cli.get('/')
assert resp.status == 200
assert await resp.text() == 'value: bar'
async def test_f(aiohttp_server):
app = web.Application()
# fill route table
server = await aiohttp_server(app)
async def test_f(aiohttp_client):
app = web.Application()
# fill route table
client = await aiohttp_client(app)
resp = await client.get('/')
async def test_f(aiohttp_raw_server, aiohttp_client):
async def handler(request):
return web.Response(text = "OK")
raw_server = await aiohttp_raw_server(handler)
client = await aiohttp_client(raw_server)
resp = await client.get('/')