<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Labix Blog &#187; Test</title>
	<atom:link href="http://blog.labix.org/tag/test/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.labix.org</link>
	<description>by Gustavo Niemeyer</description>
	<lastBuildDate>Fri, 09 Jul 2010 19:15:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Mocker 1.0 for Python released!</title>
		<link>http://blog.labix.org/2010/06/20/mocker-1-0-for-python-released</link>
		<comments>http://blog.labix.org/2010/06/20/mocker-1-0-for-python-released#comments</comments>
		<pubDate>Mon, 21 Jun 2010 00:09:02 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Project]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Test]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=323</guid>
		<description><![CDATA[After a few years in development, version 1.0 of Mocker is now available! Check out the changes since 0.10.1, the supported features, or go straight to the download page.]]></description>
			<content:encoded><![CDATA[<p>After a few years in development, version 1.0 of <a href="http://bit.ly/dm0GGy" _href="http://labix.org/mocker">Mocker</a> is now <a href="http://bit.ly/dez9jQ" _href="https://launchpad.net/mocker/trunk/1.0">available</a>!  Check out the <a href="http://bit.ly/czhiru " _href="http://bazaar.launchpad.net/~niemeyer/mocker/trunk/annotate/head:/NEWS">changes since 0.10.1</a>, the <a href="http://bit.ly/dm0GGy" _href="http://labix.org/mocker">supported features</a>, or go straight to the <a href="http://bit.ly/9Wszmp" _href="https://launchpad.net/mocker/+download">download page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2010/06/20/mocker-1-0-for-python-released/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The forgotten art of error checking</title>
		<link>http://blog.labix.org/2010/06/17/the-forgotten-art-of-error-checking</link>
		<comments>http://blog.labix.org/2010/06/17/the-forgotten-art-of-error-checking#comments</comments>
		<pubDate>Thu, 17 Jun 2010 15:15:59 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Lua]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Snippet]]></category>
		<category><![CDATA[Test]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=275</guid>
		<description><![CDATA[I was just rambling randomly yesterday, in the usual microblogging platforms, about how result checking seems to be ignored or done badly. The precise wording was: It&#8217;s really amazing how little attention error handling receives in most software development. Even &#8230; <a href="http://blog.labix.org/2010/06/17/the-forgotten-art-of-error-checking">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was just rambling randomly yesterday, in the usual microblogging platforms, about how result checking seems to be ignored or done badly.  The precise wording was:</p>
<blockquote><p>
It&#8217;s really amazing how little attention error handling receives in most software development. Even *tutorials* often ignore it.
</p></blockquote>
<p>It indeed does amaze me.  It sometimes feels like we write code for theoretical perfect worlds.. <i>&#8220;If the processor executes exactly in this order, and the weather is calm, this program will work.&#8221;</i>.  There are countless examples of bad assumptions.. someday I will come with some statistics of the form <i>&#8220;Every N seconds someone forgets to check the result of write().&#8221;</i>.</p>
<p><span id="more-275"></span></p>
<p>If you are a teacher, or a developer that enjoys writing snippets of code to teach people, please join me in the quest of building a better future.  Do <i>not</i> tell us that you&#8217;re &#8220;avoiding result checking for terseness&#8221;, because that&#8217;s exactly what we people will do (terseness is good, right?).  On the contrary, take this chance to make us feel <i>bad</i> about avoiding result checking.  You might do this by putting a comment like &#8220;If you don&#8217;t do this, you&#8217;re a bad programmer.&#8221; right next to the logic which is handling the result, and might take this chance to teach people how proper result handling is done.</p>
<p>Of course, there&#8217;s another forgotten art related to result checking.  It sits on the other side of the fence.  If you are a library author, do think through about how you plan to make us check conditions which happen inside your library, and try to imagine how to make our lives easier.  If we suck at handling results when there are obvious ways to handle it, you can imagine what happens when you structure your result logic badly.</p>
<p>Here is a clear example of what <i>not</i> to do, coming straight from Python&#8217;s standard library, in the <i>imaplib</i> module:</p>
<pre>
    def login(self, user, password):
        typ, dat = self._simple_command('LOGIN', user, self._quote(password))
        if typ != 'OK':
            raise self.error(dat[-1])
        self.state = 'AUTH'
        return typ, dat
</pre>
<p>You see the problem there?  How do you handle errors from this library?  Should we catch the exception, or should we verify the result code? <i>&#8220;Both!&#8221;</i> is the right answer, unfortunately, because the author decided to do us a little favor and check the error condition himself in some arbitrary cases and raise the error, while letting it go through and end up in the result code in a selection of other arbitrary cases.</p>
<p>I may provide some additional advice on result handling in the future, but for now I&#8217;ll conclude with the following suggestion: please check the results from your actions, and help others to check theirs.  That&#8217;s a good life-encompassing recommendation, actually.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2010/06/17/the-forgotten-art-of-error-checking/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Xpresser &#8211; Python library for GUI automation with image matching</title>
		<link>http://blog.labix.org/2010/05/18/xpresser-python-library-for-gui-automation-with-image-matching</link>
		<comments>http://blog.labix.org/2010/05/18/xpresser-python-library-for-gui-automation-with-image-matching#comments</comments>
		<pubDate>Tue, 18 May 2010 20:43:24 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Project]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Test]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=267</guid>
		<description><![CDATA[In a hurry? Go check it out! The context A while ago I found out about Sikuli, a very interesting project which allows people to script actions in GUIs based on screenshot excerpts. The idea is that you basically take &#8230; <a href="http://blog.labix.org/2010/05/18/xpresser-python-library-for-gui-automation-with-image-matching">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><b>In a hurry?</b></p>
<p><a href="http://wiki.ubuntu.com/Xpresser">Go check it out!</a></p>
<p><b>The context</b></p>
<p>A while ago I found out about <a href="http://sikuli.org">Sikuli</a>, a very interesting project which allows people to script actions in GUIs based on screenshot excerpts.  The idea is that you basically take images representing portions of your screen, like a button, or a label, or an icon, and then create a script which can detect a position in the screen which resembles one of these images, and perform actions on them, such as clicking, or hovering.</p>
<p><span id="more-267"></span></p>
<p>I had never imagined something like this, and the idea got me really excited about the possibilities.   Imagine, for instance, what can be done in terms of testing.  Testing of GUIs is unfortunately not yet a trivial task nowadays.  We do have frameworks which are based on accessibility hooks, for instance, but these sometimes can&#8217;t be used because the hook is missing, or is even far off in terms of the context being tested (imagine testing that a browser can open a specific flash site successfully, for instance).</p>
<p>So, Sikuli opened my eyes to the possibility of using image matching technology in a GUI automation context, and I really wanted to play with it.  In the days following the discovery, I fiddled a bit, communicated with the author, and even submitted some changes to make it work well in Ubuntu.</p>
<p>Then, the idea cooled down in my head, and I moved on with life.  Well&#8230; until two weeks ago.</p>
<p>Right before heading to the <a href="http://wiki.ubuntu.com/UDS-M">Ubuntu Developer Summit</a> for the next Ubuntu release, the desire of automating GUIs appeared again in the context of the widely scoped Ubuntu-level testing suite.  Then, over the first few days last week, I was able to catch up with quite a few people which were interested in the concept of automating GUIs, with different purposes (testing, design approval, etc), which of course was all I needed to actually push that old desire forward.</p>
<p>Trying to get Sikuli to work, though, was quite painful.  Even though I had sent patches upstream before, it looks like the build process isn&#8217;t working in Ubuntu again for other reasons (it&#8217;s not a polished build process, honestly), and even if I managed to make it work and contributed that to the upstream, in the end the path to integrate the Java-based tool in the Python-based testing framework which Ubuntu uses (<a href="https://launchpad.net/mago">Mago</a>) wasn&#8217;t entirely straightforward either.</p>
<p><b>Reinventing the wheel</b></p>
<p>So, the the itch was in place, and there was a reason to let the <a href="http://en.wikipedia.org/wiki/Not_Invented_Here">NIH</a> syndrome take over a bit.  Plus, image processing is something I&#8217;d like to get a foot in anyway, so it felt like a good chance to have a closer look and at the same time contribute a small bit to potential quality improvements of Ubuntu.</p>
<p>That&#8217;s when <a href="http://wiki.ubuntu.com/Xpresser">Xpresser</a> was born.  Xpresser is a clean room implementation of the concepts explored by Sikuli, in the form of a Python library which can be used standalone, or embedded into other programs and testing frameworks such as Mago.</p>
<p>The project is sponsored by <a href="http://canonical.com">Canonical</a>, and licensed under the LGPL.</p>
<p>Internally, it makes use of opencv for the image matching, pyatspi for the event generation (mouse clicks, etc), gtk for screen capturing and testing (of itself), and numpy for matrix operations. Clearly, the NIH syndrome, wasn&#8217;t <i>entirely</i> active. <img src='http://blog.labix.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />   As a side note, I haven&#8217;t played with numpy and gtk for some time, and I&#8217;m always amazed by the quality of these modules.</p>
<p><b>Contribute code and ideas</b></p>
<p>Concluding this post, which is already longer than I expected, the basics of Xpresser are in place, so go ahead and play with it!  That said, there are quite a few low hanging fruits to get it to a point of being a really compelling GUI-driving library, so if you have any interest in the concept, I invite you to play with the code and submit contributions too.  If you want ideas of what else could be done, let&#8217;s have a chat.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2010/05/18/xpresser-python-library-for-gui-automation-with-image-matching/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Mocker 0.10 and trivial patch-mocking of existing objects</title>
		<link>http://blog.labix.org/2007/12/09/mocker-010-and-trivial-patch-mocking-of-existing-objects</link>
		<comments>http://blog.labix.org/2007/12/09/mocker-010-and-trivial-patch-mocking-of-existing-objects#comments</comments>
		<pubDate>Sun, 09 Dec 2007 23:07:13 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Project]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Snippet]]></category>
		<category><![CDATA[Test]]></category>

		<guid isPermaLink="false">http://blog.labix.org/2007/12/09/mocker-010-and-trivial-patch-mocking-of-existing-objects/</guid>
		<description><![CDATA[Mocker 0.10 is out, with a number of improvements! While we&#8217;re talking about Mocker, here is another interesting use case, exploring a pretty unique feature it offers. Suppose we want to test that a method hello() on an object will &#8230; <a href="http://blog.labix.org/2007/12/09/mocker-010-and-trivial-patch-mocking-of-existing-objects">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://labix.org/mocker">Mocker</a> 0.10 is out, with a <a href="https://launchpad.net/mocker/trunk/0.10">number of improvements</a>!</p>
<p>While we&#8217;re talking about Mocker, here is another interesting use case, exploring a pretty unique feature it offers.</p>
<p>Suppose we want to test that a method <i>hello()</i> on an object will call <i>self.show(&#8220;Hello world!&#8221;)</i> at some point.  Let&#8217;s say that the code we want to test is this:</p>
<pre>
 class Greeting(object):

     def show(self, sentence):
         print sentence

     def hello(self):
         self.show("Hello world!")
</pre>
<p>This is the <i>entire</i> test method:</p>
<pre>
def test_hello(self):
    # Define expectation.
    mock = self.mocker.patch(Greeting)
    mock.show("Hello world!")
    self.mocker.replay()

    # Rock on!
    Greeting().hello()
</pre>
<p>This has helped me in practice a few times already, when testing some involved situations.</p>
<p>Note that you can also <i>passthrough</i> the call.  In other words, the call may actually be made on the real method, and mocker will just assert that the call was really made, whatever the effect is.</p>
<p>One more important point: mocker ensures that the real method <i>exists</i> in the real object, and has a specification compatible with the call made.  If it doesn&#8217;t, and assertion error is raised in the test with a nice error message.</p>
<p><b>UPDATE:</b> <i>The method for doing this is actually mocker.patch() rather than mocker.mock(), as documented. Apologies.</i></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2007/12/09/mocker-010-and-trivial-patch-mocking-of-existing-objects/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Partial stubbing of os.path.isfile() with Mocker</title>
		<link>http://blog.labix.org/2007/11/22/partial-stubbing-of-ospathisfile-with-mocker</link>
		<comments>http://blog.labix.org/2007/11/22/partial-stubbing-of-ospathisfile-with-mocker#comments</comments>
		<pubDate>Thu, 22 Nov 2007 23:27:14 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Project]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Snippet]]></category>
		<category><![CDATA[Test]]></category>

		<guid isPermaLink="false">http://blog.labix.org/2007/11/22/partial-stubbing-of-ospathisfile-with-mocker/</guid>
		<description><![CDATA[One neat feature which Mocker offers is the ability to very easily implement custom behavior on specific functions or methods. Take for instance the case where you want to pretend to some code that a given file exists, but you &#8230; <a href="http://blog.labix.org/2007/11/22/partial-stubbing-of-ospathisfile-with-mocker">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One neat feature which Mocker offers is the ability to very easily implement custom behavior on specific functions or methods.</p>
<p>Take for instance the case where you want to pretend to some code that a given file exists, but you don&#8217;t want to get on the way of everything else which needs the same function: </p>
<pre>
>>> from mocker import *
>>> mocker = Mocker()
>>> isfile = mocker.replace("os.path.isfile", count=False)
>>> _ = expect(isfile("/non/existent")).result(True)
>>> _ = expect(isfile(ANY)).passthrough()

>>> mocker.replay()

>>> import os
>>> os.path.isfile("/non/existent")
True
>>> os.path.isfile("/etc/passwd")
True
>>> os.path.isfile("/other")
False

>>> mocker.restore()

>>> os.path.isfile("/non/existent")
False
</pre>
<p>Notice that the <i>count=False</i> parameter is available in version 0.9.2.  Without it Mocker will act in a more <i>mocking-strict</i> way and enforce that the given expressions should be executed precisely the given number of times (which defaults to one, and may be modified with the <i>count()</i> method). </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2007/11/22/partial-stubbing-of-ospathisfile-with-mocker/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mocker for Python released!</title>
		<link>http://blog.labix.org/2007/11/11/mocker-for-python-released</link>
		<comments>http://blog.labix.org/2007/11/11/mocker-for-python-released#comments</comments>
		<pubDate>Mon, 12 Nov 2007 02:17:00 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Project]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Test]]></category>

		<guid isPermaLink="false">http://blog.labix.org/2007/11/11/mocker-for-python-released/</guid>
		<description><![CDATA[After being bored for a long time for the lack of a better infrastructure for creating test doubles in Python, I decided to give it a go. I&#8217;m actually quite happy with what came out.. it took me about four &#8230; <a href="http://blog.labix.org/2007/11/11/mocker-for-python-released">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>After being bored for a long time for the lack of a better infrastructure for creating <a href="http://martinfowler.com/articles/mocksArentStubs.html">test doubles</a> in Python, I decided to give it a go.</p>
<p>I&#8217;m actually quite happy with what came out.. it took me about four weekends (was developed as a personal project), and I&#8217;ll dare to say that it&#8217;s the best mocking system for Python at the present time.  Not only that, but it has features that I&#8217;ve not seen in any other mocking/stubing infrastructure, independent of language.</p>
<p>Here&#8217;s a feature list to catch your attention:</p>
<ul>
<li> Graceful platform for test doubles in Python (mocks, stubs, fakes, and dummies).
<li> Inspiration from real needs, and also from pmock, jmock, pymock, easymock, etc.
<li> Expectation of expressions defined by actually using mock objects.
<li> Expressions may be replayed in any order by default,
<li> Trivial specification of ordering between expressions when wanted.
<li> Nice parameter matching for defining expectations on method calls.
<li> Good error messages when expectations are broken.
<li> Mocking of many kinds of expressions (getting/setting/deleting attributes, calling, iteration, containment, etc)
<li> Graceful handling of nested expressions (e.g. &#8221;person.details.get_phone().get_prefix()&#8221;)
<li> Mock &#8221;proxies&#8221;, which allow passing through to the real object on specified expressions (e.g. useful with &#8221;os.path.isfile()&#8221;).
<li> Mocking via temporary &#8221;patching&#8221; of existent classes and instances.
<li> Trivial mocking of any external module (e.g. &#8221;time.time()&#8221;) via &#8221;proxy replacement&#8221;.
<li> Mock objects may have method calls checked for conformance with real class/instance to prevent API divergence.
<li> Type simulation for using mocks while still performing certain type-checking operations.
<li> Nice (optional) integration with &#8221;unittest.TestCase&#8221;, including additional assertions (e.g. &#8221;assertIs&#8221;, &#8221;assertIn&#8221;, etc).
<li> More &#8230;
</ul>
<p>Worked?  <a href="http://labix.org/mocker">Check it out!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2007/11/11/mocker-for-python-released/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
