Created
April 21, 2013 23:54
-
-
Save nimbus154/5431618 to your computer and use it in GitHub Desktop.
An example of how to write functional tests for a RESTful API using the Bottle microframework.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from bottle import get, run, request, post, Bottle, abort, error, response, debug, redirect | |
# This is a dictionary endpoint. It retrieves definitions for words. | |
# You can also add words to the dictionary. | |
# this allows our bottle application to be accessible outside this file | |
app = Bottle() | |
dictionary = { | |
"lugubrious": "extremely sad", | |
"kinetic": "relating to motion", | |
"august": "awesome; also a month" | |
} | |
# Retrieve the definition of a word | |
@app.get('/dictionary/:word') | |
def define(word=""): | |
global dictionary # needed to make the dictionary accessible | |
if word in dictionary: | |
return {word: dictionary[word]} | |
else: | |
abort(404, "Word not in dictionary. Maybe you should add it?") | |
# Add a word to the dictionary | |
# If word is in dictionary, redirect | |
@app.post('/dictionary') | |
def add(): | |
global dictionary # needed to make the dictionary accessible | |
word = request.json['word'] | |
if word in dictionary: | |
# word already exists, redirect | |
redirect('/dictionary/%s' % word) | |
else: | |
dictionary[word] = request.json['definition'] | |
response.status = '201 Created' | |
return response | |
debug(True) | |
if __name__ == '__main__': | |
run(reloader=True, debug=True) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# import the unit testing module | |
import unittest | |
# for HTTP tests | |
# you must pip install webtest | |
from webtest import TestApp | |
# import our bottle app | |
import dictionary | |
test_app = TestApp(dictionary.app) | |
# extend the class unittest.TestCase | |
class TestGetJSON(unittest.TestCase): | |
# name any method you want to run as a test "test_" | |
def test_word_found(self): | |
# look up a word that should be in the dictionary | |
response = test_app.get('/dictionary/lugubrious') | |
# Response status should be HTTP 200 OK | |
self.assertEqual(response.status_int, 200) | |
self.assertEqual(response.status, '200 OK') | |
# Response body should be JSON {"number": 0} | |
self.assertEqual(response.json['lugubrious'], 'extremely sad') | |
def test_not_found(self): | |
# look up a word not in the dictionary | |
# should return 404 | |
# need to tell WebTest to expect a status of 404 | |
# otherwise it will throw an exception | |
response = test_app.get('/dictionary/ghostbuster', status=404) | |
self.assertEqual(response.status_int, 404) | |
class TestPostJSON(unittest.TestCase): | |
def test_add(self): | |
response = test_app.post_json('/dictionary', { | |
'word': 'hacker', | |
'definition': 'a computer genius' | |
}) | |
# Expect a new resource to be created | |
self.assertEqual(response.status, '201 Created') | |
# to be really thorough, let's get the resource to ensure it was created | |
response = test_app.get('/dictionary/hacker') | |
self.assertEqual(response.status_int, 200) | |
self.assertEqual(response.json['hacker'], 'a computer genius') | |
def test_already_in_dictionary(self): | |
# try to add a word that's already in the dictionary | |
# server respond with a redirect | |
response = test_app.post_json('/dictionary', { | |
'word': 'lugubrious', | |
'definition': 'extremely sad' | |
}) | |
# 302 is "Found" redirect, indicating resource was found | |
self.assertEqual(response.status_int, 302) | |
# the 'Location' header should end with the path /dictionary/lugubrious | |
self.assertRegexpMatches(response.location, '/dictionary/lugubrious$') | |
# If running this file, run the tests | |
# invoke with `python -m unittest discover` | |
if __name__ == '__main__': | |
unittest.main() |
many thanks!
nice, thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
nice example to create unit testing with WebTest for Bottle! Well done.