- The ability to do outside-in development properly - as is possible with ruby's Cucumber project (although, this could be used, but it'd be adding yet-another-technology to the stack - I haven't tried pyCucumber, but it doesn't look too active), and
- Something similar to rspactor - allowing tests to be run automatically as I edit files, and reporting them via the OS's notification system.
Wednesday, May 20, 2009
Outside-in development on Ubuntu
For over 6 months now I've been working on launchpad.net - collaborative development for open source software - using Python (Zope). It's been an unreal experience seeing various testing strategies on such a large code-base, but the two things I miss the most while developing on launchpad are:
Tuesday, October 14, 2008
Mocking in Python just got easier
Voidspace just released Mock 0.4.0 - an update to the excellent Mock library which brings a few conveniences and easier patching of module and class-level attributes.
This makes tests using mocks easier to read, for example inside a test case:
Can now be written as:
Check it out!
This makes tests using mocks easier to read, for example inside a test case:
self.assertEquals(my_mock.my_method.call_args,
(('goodbye',),{'hello': False}))
Can now be written as:
my_mock.my_method.assert_called_with('goodbye', hello=False)
Check it out!
Saturday, September 27, 2008
Mocking with Django and Google AppEngine
Since working with RSpec over the past 6 months - a Behaviour-Driven Development framework for ruby - I've been wondering if there's anything comparable in Python (my preferred tool for development!). One of the things I love about RSpec is the ease with which Mock objects can be used to keep tests focused.
While there are a number of mock libraries around for Python most don't result in particularly readable test code. But I was pleasantly suprised to discover Michael Foord's Mocking and Testing utilities.
A simple example: I've got a Django application hosted on Google AppEngine and say I want to write a simple test to verify that my view does require the user to be logged in with their Google account and if not, redirects appropriately - but I don't want to have to manually log a user in, or even use the Google api as part of my test. Here's a snippet showing how easy this is with Mock:
Easy! Thanks Michael. The Mock object has lots of other goodies of course (such as auto-setting all the mock-methods from the real object, testing for call parameters etc.).
While there are a number of mock libraries around for Python most don't result in particularly readable test code. But I was pleasantly suprised to discover Michael Foord's Mocking and Testing utilities.
A simple example: I've got a Django application hosted on Google AppEngine and say I want to write a simple test to verify that my view does require the user to be logged in with their Google account and if not, redirects appropriately - but I don't want to have to manually log a user in, or even use the Google api as part of my test. Here's a snippet showing how easy this is with Mock:
from mock import Mock
from google.appengine.api import users
class MySpecialView(TestCase):
def setUp():
""" Create the required mocks for the view tests """
# Mock the get_current_user method of the google users api
users.get_current_user = Mock()
# Create a mock user that we'll pretend is logged in
mock_user = Mock()
# Just for readability, save the special app-engine login url as
# an instance variable
self.url = reverse('my-special-view-name')
self.login_url = "http://testserver/_ah/login?continue=http%%3A//testserver%s" % self.url
def test_logged_in_user_can_access_page(self):
"""A logged in user should not be redirected to the login page"""
# Set the return value for the mocked
# get_current_user method:
users.get_current_user.return_value = mock_user
response = do_request()
# Make sure the mock method was called
self.assertTrue(users.get_current_user.called)
# And the redirect did not take place, but the
# normal template was rendered...
self.assertTemplateUsed(response, 'myapp/overview.html')
def test_anonymous_user_is_redirected_to_login(self):
""" An anonymous user should be redirected to the login page"""
# Set the google api's get_current_user method to return None
users.get_current_user.return_value = None
response = self.do_request()
# Make sure the mock method was called
self.assertTrue(users.get_current_user.called)
# And that the redirect took place... note we can't use
# the normal assertRedirects due to the app-engine specific
# login url.
self.assertEquals(response.status_code, 302)
self.assertEquals(
response['location'],
"http://testserver/_ah/login?continue=http%%3A//testserver%s" % self.url
)
Easy! Thanks Michael. The Mock object has lots of other goodies of course (such as auto-setting all the mock-methods from the real object, testing for call parameters etc.).
Subscribe to:
Posts (Atom)