Testing

####Different kinds of testing If you check the article on software testing on Wikipedia, you will see there are many kinds of testing.

But in this post we are going to look specifically at testing webapp2 handlers on App Engine.

Setting up a test environment for App Engine applications is a little bit fiddly, but is not hard to do. We are going to use the NoseGAE plugin for nose, a widely-used extension to the unittest unit testing framework.

Testing is a big topic and we are just touching the surface here, but following the instructions below will get you to the point where you can build some simple functional tests for your application and begin to explore further.

####Getting set up

First, install the the WebTest framework for testing WSGI applications:

pip install --user webtest

(you can also use sudo pip install webtest)

Then, install the nose testing framework:

pip install --user nose

And, finally, install NoseGAE:

pip install --user nosegae

####Create a very simple App Engine application

Use the Hello World example on GitHub:

git clone https://github.com/GoogleCloudPlatform/appengine-helloworld-python.git

Amend the main.py file like this:

import webapp2

class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('Hello world!')

#app = webapp2.WSGIApplication([
#    ('/', MainHandler)
#], debug=True)

def application():
    return webapp2.WSGIApplication([
            ('/', MainHandler)
            ], debug=True)

if __name__ == '__main__':
    wsgiref.handlers.CGIHandler().run(application())
else:
    app = application()

We can now create a WSGIApplication object in two different ways; either the usual way via the app.yaml file or via wsgiref as a script, for testing purposes.

Create a test file (you can call it test.py):

from webtest import TestApp
from main import application

app = TestApp(application())

def test_index():
    response = app.get('/')
    assert 'Hello world!' in str(response)

Now run:

nosetests -v --with-gae 

If you get the error:

ImportError: No module named dev_appserver

Then, check where dev_appserver is being served from:

which dev_appserver.py
>>>/home/action/.google_appengine/dev_appserver.py

And run:

nosetests -v --with-gae --gae-lib-root="/home/action/.google_appengine/"

(or whichever path dev_appserver.py is on)

You should get something like:

test.test_index ... ok

------------------------------------------------
Ran 1 test in 0.123s

OK         

You now have a single passing test. Congratulations!

####Apply testing to your blog application

Make the same changes as above to your main blog application file, using the application() function. And add a test file to your application.

Now add some new tests. They might look something like this:

def test_index():
    response = app.get('/')
    assert 'Hello, Udacity!' in str(response)

def test_index():
    response = app.get('/blog')
    assert 'CS 253 Blog' in str(response)

These kinds of tests, where the output of the handler functions is tested against expectations, are known, appropriately enough, as functional tests.

Functional tests are based around the functions that a piece of software are expected to perform. In the case of the webapp2 framework, this means faking HTTP requests and checking that the handler functions return the expected responses.

####Unit tests

Unit testing is beyond the scope of this post, but is generally applied to a single class or module within an application.

Within the context of a web app, you would expect unit tests to be applied to models.

Nosegae has a nice approach to unit testing, which involves using doctest.

We haven’t covered doctest yet, but Wikipedia has a good introduction.