Question

Is there a good practice to unit-test a flask blueprint?

http://flask.pocoo.org/docs/testing/

I didn't found something that helped me or that is simple enough.

// Edit
Here are my code:

# -*- coding: utf-8 -*-
import sys
import os
import unittest
import flask

sys.path = [os.path.abspath('')] + sys.path

from app import create_app
from views import bp


class SimplepagesTestCase(unittest.TestCase):
    def setUp(self):
        self.app = create_app('development.py')
        self.test_client = self.app.test_client()

    def tearDown(self):
        pass

    def test_show(self):
        page = self.test_client.get('/')
        assert '404 Not Found' not in page.data


if __name__ == '__main__':
    unittest.main()

In this case, i test the blueprint. Not the entire app. To test the blueprint i've added the root path of the app to sys.path. Now i can import the create_app function to ...create the app. I also init the test_client.

I think i've found a good solution. Or will is there a better way?

Was it helpful?

Solution 2

Blueprints are very similar to application. I guess that you want test test_client requests.

If you want test blueprint as part of your application then look like no differences there are with application.

If you want test blueprint as extension then you can create test application with own blueprint and test it.

OTHER TIPS

I did the following if this helps anyone. I basically made the test file my Flask application

from flask import Flask
import unittest

app = Flask(__name__)

from blueprint_file import blueprint
app.register_blueprint(blueprint, url_prefix='')

class BluePrintTestCase(unittest.TestCase):

    def setUp(self):
        self.app = app.test_client()

    def test_health(self):
        rv = self.app.get('/blueprint_path')
        print rv.data


if __name__ == '__main__':
    unittest.main()

I have multiple APIs in one app and therefore multiple blueprints with url_prefix. I did not like that I have to prefix all paths when testing on of the APIs. I used the following class to wrap the test_client for blueprints:

class BlueprintClient():
    def __init__(self, app_client, blueprint_url_prefix):
        self.app_client = app_client
        self.blueprint_url_prefix = blueprint_url_prefix.strip('/')

    def _delegate(self, method, path, *args, **kwargs):
        app_client_function = getattr(self.app_client, method)
        prefixed_path = '/%s/%s' % (self.blueprint_url_prefix, path.lstrip('/'))
        return app_client_function(prefixed_path, *args, **kwargs)

    def get(self, *args, **kwargs):
        return self._delegate('get', *args, **kwargs)

    def post(self, *args, **kwargs):
        return self._delegate('post', *args, **kwargs)

    def put(self, *args, **kwargs):
        return self._delegate('put', *args, **kwargs)

    def delete(self, *args, **kwargs):
        return self._delegate('delete', *args, **kwargs)

app_client = app.test_client()
api_client = BlueprintClient(app_client, '/api/v1')
api2_client = BlueprintClient(app_client, '/api/v2')
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top