0

I am working on setting up unit tests in my flask project right now. My test file is below:

import flask_testing
import unittest
from flask import Flask
from flask_testing import TestCase

class MyTest(TestCase):

    def setUp(self):
        pass # Executed before each test

    def tearDown(self):
        pass # Executed after each test

    def create_app(self):
        app = Flask(__name__)
        # app.config['TESTING'] = True
        return app

    def test_greeting(self):
        response = self.client.get('/')
        print("should return 404 on landing page")
        self.assertTemplateUsed('index.html')
        self.assertEqual(response.status_code, 200)

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

When I run these tests the assertTemplateUsed does not return a template and the response.status_code is 404. I imagine this is because self is not actually my application for some reason? When I run the app the root address definitely returns index.html.

Am I setting up create_app wrong? Any help is appreciated.

Programmingjoe
  • 2,169
  • 2
  • 26
  • 46

2 Answers2

1

You need to create your Flask app instance in the setUp() function. At the moment the create_app() function doesn't get called at all.

Change your code like this:

import flask_testing
import unittest
from flask import Flask
from flask_testing import TestCase

class MyTest(TestCase):

    def setUp(self):
        self.app = Flask(__name__)
        self.app_context = self.app.app_context()
        self.app_context.push()
        self.client = self.app.test_client(use_cookie=True)

    def tearDown(self):
        self.app_context.pop()

    def test_greeting(self):
        response = self.client.get('/')
        print("should return 404 on landing page")
        self.assertTemplateUsed('index.html')
        self.assertEqual(response.status_code, 200)

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

The setUp() function gets called prior to each test function. At first you will create a new instance of your Flask app. If you want to access items in your application context it is good practice to push it in your setUp() function and pop it in your tearDown() function. You can leave this out if you don' t access app_context items (like Database session objects) from your test function. At last you need to creat the test client in your setUp() function. You missed that part in your post but I guess you did it somewhere else in your code.

MrLeeh
  • 5,321
  • 6
  • 33
  • 51
  • create_app() is definitely being called. It's required in Flask-Testing applications: https://pythonhosted.org/Flask-Testing/ Edit: I could however just try and drop flask-testing and just use unittest – Programmingjoe Mar 30 '17 at 04:50
1

In your setUp function, you need to provide a test client to make the requests. Try something like this.

def setUp(self):
    # this test client is what flask-testing will use to make your requests
    self.app = app.test_client()

Check this out for more information How to Test a Flask Application.