<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" gd:etag="W/&quot;CUYFSHkyeSp7ImA9WhZQFE8.&quot;"><id>tag:blogger.com,1999:blog-908080082616606516</id><updated>2011-04-21T23:58:39.791+02:00</updated><category term="testing" /><category term="python" /><title>Michael Nelson - Something driven development</title><subtitle type="html">Software development thoughts and musings around Python, Ruby and other tools.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://michael-a-nelson.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://michael-a-nelson.blogspot.com/" /><author><name>Michael</name><uri>http://www.blogger.com/profile/13080395092257355476</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://2.bp.blogspot.com/_mJOx6nkhQuA/SN5zFNH9csI/AAAAAAAAANI/rhaB2C44RDA/S220/MikeSooksWedding.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/MichaelNelson-DrivenDevelopment" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="michaelnelson-drivendevelopment" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;D0MBR3w6fCp7ImA9WxJRGEg.&quot;"><id>tag:blogger.com,1999:blog-908080082616606516.post-1030793217322498671</id><published>2009-05-20T23:12:00.002+02:00</published><updated>2009-05-20T23:37:36.214+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-20T23:37:36.214+02:00</app:edited><title>Outside-in development on Ubuntu</title><content type="html">For over 6 months now I've been working on &lt;a href="http://launchpad.net/"&gt;launchpad.net&lt;/a&gt; - 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:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The ability to do outside-in development properly - as is possible with ruby's &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt; project (although, this could be used, but it'd be adding yet-another-technology to the stack - I haven't tried &lt;a href="http://github.com/cpennington/pycucumber/tree/master"&gt;pyCucumber&lt;/a&gt;, but it doesn't look too active), and&lt;/li&gt;&lt;li&gt;Something similar to &lt;a href="http://rspactorapp.com/"&gt;rspactor&lt;/a&gt; - allowing tests to be run automatically as I edit files, and reporting them via the OS's notification system.&lt;/li&gt;&lt;/ol&gt;But trying to communicate exactly what I mean by that to people who haven't used rspactor or Cucumber is kind-of tricky, so here's a video demo'ing how I'd love to do inside-out development on Ubuntu...&lt;br /&gt;&lt;br /&gt;&lt;object width="660" height="525"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/bvUDYmllVrM&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0&amp;amp;hd=1&amp;amp;border=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube-nocookie.com/v/bvUDYmllVrM&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0&amp;amp;hd=1&amp;amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="660" height="525"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/908080082616606516-1030793217322498671?l=michael-a-nelson.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://michael-a-nelson.blogspot.com/feeds/1030793217322498671/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=908080082616606516&amp;postID=1030793217322498671" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/908080082616606516/posts/default/1030793217322498671?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/908080082616606516/posts/default/1030793217322498671?v=2" /><link rel="alternate" type="text/html" href="http://michael-a-nelson.blogspot.com/2009/05/outside-in-development-on-ubuntu.html" title="Outside-in development on Ubuntu" /><author><name>Michael</name><uri>http://www.blogger.com/profile/13080395092257355476</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://2.bp.blogspot.com/_mJOx6nkhQuA/SN5zFNH9csI/AAAAAAAAANI/rhaB2C44RDA/S220/MikeSooksWedding.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0IFQnk_eyp7ImA9WxRQGUg.&quot;"><id>tag:blogger.com,1999:blog-908080082616606516.post-2986572290392200891</id><published>2008-10-14T06:31:00.000+02:00</published><updated>2008-10-14T06:45:13.743+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-14T06:45:13.743+02:00</app:edited><title>Mocking in Python just got easier</title><content type="html">Voidspace just released &lt;a href="http://www.voidspace.org.uk/python/weblog/arch_d7_2008_10_11.shtml"&gt;Mock 0.4.0&lt;/a&gt; - an update to the excellent Mock library which brings a few conveniences and easier patching of module and class-level attributes.&lt;br /&gt;&lt;br /&gt;This makes tests using mocks easier to read, for example inside a test case:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;self.assertEquals(my_mock.my_method.call_args, &lt;br /&gt;    (('goodbye',),{'hello': False}))&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Can now be written as:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;my_mock.my_method.assert_called_with('goodbye', hello=False)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Check it out!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/908080082616606516-2986572290392200891?l=michael-a-nelson.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://michael-a-nelson.blogspot.com/feeds/2986572290392200891/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=908080082616606516&amp;postID=2986572290392200891" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/908080082616606516/posts/default/2986572290392200891?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/908080082616606516/posts/default/2986572290392200891?v=2" /><link rel="alternate" type="text/html" href="http://michael-a-nelson.blogspot.com/2008/10/mocking-in-python-just-got-easier.html" title="Mocking in Python just got easier" /><author><name>Michael</name><uri>http://www.blogger.com/profile/13080395092257355476</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://2.bp.blogspot.com/_mJOx6nkhQuA/SN5zFNH9csI/AAAAAAAAANI/rhaB2C44RDA/S220/MikeSooksWedding.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C04GQ3k8eip7ImA9WxRQE0s.&quot;"><id>tag:blogger.com,1999:blog-908080082616606516.post-1169768136746142869</id><published>2008-09-27T20:07:00.000+02:00</published><updated>2008-10-07T08:45:22.772+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-07T08:45:22.772+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Mocking with Django and Google AppEngine</title><content type="html">Since working with &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt; 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 &lt;a href="http://www.mockobjects.com/"&gt;Mock objects&lt;/a&gt; can be used to keep tests focused.&lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://www.voidspace.org.uk/python/mock.html"&gt;Mocking and Testing utilities&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;from mock import Mock&lt;br /&gt;from google.appengine.api import users&lt;br /&gt;   &lt;br /&gt;&lt;br /&gt;class MySpecialView(TestCase):&lt;br /&gt;&lt;br /&gt;    def setUp():&lt;br /&gt;        """ Create the required mocks for the view tests """&lt;br /&gt;        # Mock the get_current_user method of the google users api&lt;br /&gt;        users.get_current_user = Mock()&lt;br /&gt;&lt;br /&gt;        # Create a mock user that we'll pretend is logged in&lt;br /&gt;        mock_user = Mock()&lt;br /&gt;&lt;br /&gt;        # Just for readability, save the special app-engine login url as &lt;br /&gt;        # an instance variable&lt;br /&gt;        self.url = reverse('my-special-view-name')&lt;br /&gt;        self.login_url = "http://testserver/_ah/login?continue=http%%3A//testserver%s" % self.url&lt;br /&gt;&lt;br /&gt;    def test_logged_in_user_can_access_page(self):&lt;br /&gt;        """A logged in user should not be redirected to the login page"""&lt;br /&gt;        # Set the return value for the mocked &lt;br /&gt;        # get_current_user method:&lt;br /&gt;        users.get_current_user.return_value = mock_user&lt;br /&gt;&lt;br /&gt;        response = do_request()&lt;br /&gt;&lt;br /&gt;        # Make sure the mock method was called&lt;br /&gt;        self.assertTrue(users.get_current_user.called)&lt;br /&gt;&lt;br /&gt;        # And the redirect did not take place, but the &lt;br /&gt;        # normal template was rendered...&lt;br /&gt;        self.assertTemplateUsed(response, 'myapp/overview.html')&lt;br /&gt;       &lt;br /&gt;    def test_anonymous_user_is_redirected_to_login(self):&lt;br /&gt;        """ An anonymous user should be redirected to the login page"""&lt;br /&gt;        # Set the google api's get_current_user method to return None&lt;br /&gt;        users.get_current_user.return_value = None&lt;br /&gt;&lt;br /&gt;        response = self.do_request()&lt;br /&gt;&lt;br /&gt;        # Make sure the mock method was called&lt;br /&gt;        self.assertTrue(users.get_current_user.called)&lt;br /&gt;&lt;br /&gt;        # And that the redirect took place... note we can't use&lt;br /&gt;        # the normal assertRedirects due to the app-engine specific&lt;br /&gt;        # login url.&lt;br /&gt;        self.assertEquals(response.status_code, 302)&lt;br /&gt;        self.assertEquals(&lt;br /&gt;            response['location'],&lt;br /&gt;            "http://testserver/_ah/login?continue=http%%3A//testserver%s" % self.url&lt;br /&gt;        )&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Easy! Thanks &lt;a href="http://www.voidspace.org.uk/python/weblog/index.shtml"&gt;Michael&lt;/a&gt;. 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.).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/908080082616606516-1169768136746142869?l=michael-a-nelson.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://michael-a-nelson.blogspot.com/feeds/1169768136746142869/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=908080082616606516&amp;postID=1169768136746142869" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/908080082616606516/posts/default/1169768136746142869?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/908080082616606516/posts/default/1169768136746142869?v=2" /><link rel="alternate" type="text/html" href="http://michael-a-nelson.blogspot.com/2008/09/mocking-with-django-and-google-app.html" title="Mocking with Django and Google AppEngine" /><author><name>Michael</name><uri>http://www.blogger.com/profile/13080395092257355476</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://2.bp.blogspot.com/_mJOx6nkhQuA/SN5zFNH9csI/AAAAAAAAANI/rhaB2C44RDA/S220/MikeSooksWedding.gif" /></author><thr:total>0</thr:total></entry></feed>

