Functional tests

Functional tests for a microservice project are all the tests that interact with the published API by sending HTTP requests and asserting the HTTP responses.

This definition is broad enough to include any test that can call the app, from fuzzing tests (you send gibberish to your app and see what happens) to penetration tests (you try to break the app security), and so on.

As developers, the two most important kinds of functional tests we should focus on are these:

  • Tests that verify that the application does what it was built for
  • Tests that ensure an abnormal behavior that was fixed is not happening anymore

The way those scenarios are organized in the tests class is up to the developers, but the general pattern is to create an instance of the application in the test class and then interact with it.

In that context, the network layer is not used, and the application is called directly by the tests, but the same request-response cycle happens, so it's realistic enough. However, we would still mock out any network calls happening within the application. ;

Flask includes a FlaskClient class to build requests, which can be instantiated directly from the app object via its test_client() method.

The following is an example of a test against the first app we showed in this chapter, which sends back a JSON body on /api/:

    import unittest 
import json
from flask_basic import app as tested_app

class TestApp(unittest.TestCase):
def test_help(self):
# creating a FlaskClient instance to interact with the app
app = tested_app.test_client()

# calling /api/ endpoint
hello = app.get('/api')

# asserting the body
body = json.loads(str(hello.data, 'utf8'))
self.assertEqual(body['Hello'], 'World!')

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

The FlaskClient class has one method per HTTP verb, and sends back Response objects that can be used to assert the results. In the preceding example, we used .get().

There's a testing flag in the Flask class, which you can use to propagate exceptions to the test, but some prefer not to use it by default to get back from the app what a real client would get--for instance, to make sure the body of 5xx or 4xx errors are converted to JSON for API consistency.

In the following example, the /api/ call produces an exception, and we're making sure the client gets a proper 500 with a structured JSON body in test_raise().

The test_proper_404() test method does the same tests on a non-existent path:

    import unittest 
import json
from flask_error import app as tested_app

_404 = ('The requested URL was not found on the server. '
'If you entered the URL manually please check your '
'spelling and try again.')

class TestApp(unittest.TestCase):
def setUp(self):
# creating a client to interact with the app
self.app = tested_app.test_client()

def test_raise(self):
# this won't raise a Python exception but return a 500
hello = self.app.get('/api')
body = json.loads(str(hello.data, 'utf8'))
self.assertEqual(body['code'], 500)

def test_proper_404(self):
# calling a non existing endpoint
hello = self.app.get('/dwdwqqwdwqd')

# yeah it's not there
self.assertEqual(hello.status_code, 404)

# but we still get a nice JSON body
body = json.loads(str(hello.data, 'utf8'))
self.assertEqual(body['code'], 404)
self.assertEqual(body['message'], '404: Not Found')
self.assertEqual(body['description'], _404)

if __name__ == '__main__':
unittest.main()
An alternative to the FlaskClient method is WebTest (http://webtest.pythonpaste.org), which offers a few more features out of the box. It's covered later in this chapter.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset