<?xml version="1.0" encoding="iso-8859-1"?>
<!-- name="generator" content="pyblosxom/1.4.3 01/10/2008" -->
<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://my.netscape.com/publish/formats/rss-0.91.dtd">

<rss version="0.91">
<channel>
<title>Phil Groce   </title>
<link>http://philgroce.com/blog</link>
<description>programming, computing and vanity blogging</description>
<language>en</language>
<item>
  <title>PyBlosxom Recent Posts Plugin</title>
  <link>http://philgroce.com/blog/geekery/python/pyrecentposts.html</link>
  <description><![CDATA[
<p>I&#8217;ve been using <a href="http://pyblosxom.sourceforge.net/">PyBlosxom</a> to run this blog and, increasingly, the static content of the site.</p>

<p>PyBlosxom tries to do as little as possible in the core, saving most features for its plugin framework. Nice technically, but leaving features up to &#8220;the community&#8221; to implement sometimes leaves some frustrating holes, as I discovered when I searched in vain for a plugin to implement &#8220;recent posts&#8221; functionality.</p>

<p>The upside is that it was really easy to implement&#8212;about 100 lines of Python. It&#8217;s available from the <a href="/static/software">software</a> page if you want to run it yourself; if you have any questions about it, feel free to contact me. about it.</p>

<p><strong>Update</strong>: I posted about my plugin to <a href="http://news.gmane.org/gmane.comp.web.pyblosxom.devel">pyblosxom-devel</a> and they added it to the <a href="http://pyblosxom.sourceforge.net/registry/display/pyrecentposts.html">plugins list</a>. w00t, as the kids say. If you&#8217;re coming here looking for more information on the plugin, I suggest you read the docstring comments of the  <a href="/software/pyrecentposts.py">plugin itself</a>.</p>
]]></description>
</item>

<item>
  <title>Python Decorators and Unit Tests</title>
  <link>http://philgroce.com/blog/geekery/python/python-unit-tests.html</link>
  <description><![CDATA[
<p>Here&#8217;s one thing that&#8217;s always bugged me about Python&#8217;s <code>unittest</code> module. Consider the following:</p>

<pre>
<code class="codelisting">
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MyTest</span><span class="py-src-op">(</span><span class="py-src-parameter">unittest</span><span class="py-src-op">.</span><span class="py-src-parameter">TestCase</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">    </span><span class="py-src-keyword">def</span> <span class="py-src-identifier">setUp</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">x</span> <span class="py-src-op">=</span> <span class="py-src-variable">foo</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
        <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">y</span> <span class="py-src-op">=</span> <span class="py-src-variable">bar</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span>    <span class="py-src-dedent"></span><span class="py-src-keyword">def</span> <span class="py-src-identifier">tearDown</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-keyword">del</span> <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">x</span><span class="py-src-newline"></span>
        <span class="py-src-keyword">del</span> <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">y</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span>    <span class="py-src-dedent"></span><span class="py-src-keyword">def</span> <span class="py-src-identifier">test_something</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-string">"Run a test here."</span><span class="py-src-newline"></span>
    <span class="py-src-comment">#   The only way I can get hold
</span>    <span class="py-src-comment">#   of any state initialized in
</span>    <span class="py-src-comment">#   startUp() is via my self reference.
</span>    <span class="py-src-comment">#   So...
</span>        <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">assertEqual</span><span class="py-src-op">(</span><span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">x</span><span class="py-src-op">,</span> <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">y</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span><span class="py-src-dedent"></span><span class="py-src-dedent"></span><span class="py-src-endmarker"></span>
</code>
</pre>

<p>It&#8217;s a little bit annoying to have to refer to <code>x</code> and <code>y</code> as <code>self.x</code> and <code>self.y</code>. In a more perfect world, <code>x</code> and <code>y</code> could be passed into the test as function arguments.</p>

<p>Enter Python 2.4 and the new (and unfortunately-named) <a href="http://python.org/dev/peps/peps-0318">decorator syntax</a>. (It has nothing to do with the GoF pattern of the same name.) I was learning a lot about this new language feature for another project, and while writing tests for it, it occurred to me that I could use decorators to put this little annoyance behind me:</p>

<pre>
<code class="codelisting">
<span class="py-src-keyword">def</span> <span class="py-src-identifier">test_a</span><span class="py-src-op">(</span><span class="py-src-parameter">fn</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">    </span><span class="py-src-keyword">def</span> <span class="py-src-identifier">wrapped</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-variable">fn</span><span class="py-src-op">(</span><span class="py-src-variable">foo</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-op">,</span> <span class="py-src-variable">bar</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
<span class="py-src-comment">#   The following is good form to make the
</span><span class="py-src-comment">#   decoration as transparent as possible:
</span>    <span class="py-src-dedent"></span><span class="py-src-variable">wrapped</span><span class="py-src-op">.</span><span class="py-src-variable">__name__</span> <span class="py-src-op">=</span> <span class="py-src-variable">fn</span><span class="py-src-op">.</span><span class="py-src-variable">__name__</span><span class="py-src-newline"></span>
    <span class="py-src-variable">wrapped</span><span class="py-src-op">.</span><span class="py-src-variable">__doc__</span>  <span class="py-src-op">=</span> <span class="py-src-variable">fn</span><span class="py-src-op">.</span><span class="py-src-variable">__doc__</span><span class="py-src-newline"></span>
    <span class="py-src-variable">wrapped</span><span class="py-src-op">.</span><span class="py-src-variable">__dict__</span> <span class="py-src-op">=</span> <span class="py-src-variable">fn</span><span class="py-src-op">.</span><span class="py-src-variable">__dict__</span><span class="py-src-newline"></span>
    <span class="py-src-keyword">return</span> <span class="py-src-variable">wrapped</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span><span class="py-src-dedent"></span><span class="py-src-keyword">class</span> <span class="py-src-identifier">MyTest</span><span class="py-src-op">(</span><span class="py-src-parameter">unittest</span><span class="py-src-op">.</span><span class="py-src-parameter">TestCase</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span><span class="py-src-indent">    </span><span class="py-src-op">@</span><span class="py-src-variable">test_a</span><span class="py-src-newline"></span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">test_something</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">,</span> <span class="py-src-parameter">x</span><span class="py-src-op">,</span> <span class="py-src-parameter">y</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-string">"Run a test here."</span><span class="py-src-newline"></span>
    <span class="py-src-comment">#   Yay! Clarity!
</span>        <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">assertEqual</span><span class="py-src-op">(</span><span class="py-src-variable">x</span><span class="py-src-op">,</span> <span class="py-src-variable">y</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span><span class="py-src-dedent"></span><span class="py-src-dedent"></span><span class="py-src-endmarker"></span>
</code>
</pre>

<p>To me, that&#8217;s really clear. As a bonus, you don&#8217;t need to explicitly un-define the variables you create during setup&#8212;although you can finalize them however you need to in the <code>wrapped</code> function defined by the decorator.</p>

<p>But wait, there&#8217;s more! Another thing that irritates me about <code>unittest</code> (and JUnit, for that matter, but I haven&#8217;t written any Java in forever) is that you get as many test methods as you want per class, but only one pair of setup and teardown methods. Want to set up a test a different way? Either do it in the test method, or make a whole new class. That can get annoying:</p>

<pre>
<code class="codelisting">
<span class="py-src-keyword">def</span> <span class="py-src-identifier">test_a</span><span class="py-src-op">(</span><span class="py-src-parameter">fn</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">    </span><span class="py-src-keyword">def</span> <span class="py-src-identifier">wrapped</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-variable">fn</span><span class="py-src-op">(</span><span class="py-src-variable">foo</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-op">,</span> <span class="py-src-variable">bar</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
<span class="py-src-comment">#   The following is good form to make the
</span><span class="py-src-comment">#   decoration as transparent as possible:
</span>    <span class="py-src-dedent"></span><span class="py-src-variable">wrapped</span><span class="py-src-op">.</span><span class="py-src-variable">__name__</span> <span class="py-src-op">=</span> <span class="py-src-variable">fn</span><span class="py-src-op">.</span><span class="py-src-variable">__name__</span><span class="py-src-newline"></span>
    <span class="py-src-variable">wrapped</span><span class="py-src-op">.</span><span class="py-src-variable">__doc__</span>  <span class="py-src-op">=</span> <span class="py-src-variable">fn</span><span class="py-src-op">.</span><span class="py-src-variable">__doc__</span><span class="py-src-newline"></span>
    <span class="py-src-variable">wrapped</span><span class="py-src-op">.</span><span class="py-src-variable">__dict__</span> <span class="py-src-op">=</span> <span class="py-src-variable">fn</span><span class="py-src-op">.</span><span class="py-src-variable">__dict__</span><span class="py-src-newline"></span>
    <span class="py-src-keyword">return</span> <span class="py-src-variable">wrapped</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span><span class="py-src-dedent"></span><span class="py-src-keyword">class</span> <span class="py-src-identifier">BaseTest</span><span class="py-src-op">(</span><span class="py-src-parameter">unittest</span><span class="py-src-op">.</span><span class="py-src-parameter">TestCase</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">    </span><span class="py-src-string">"""Superfluous base class to hold
    some utility methods."""</span><span class="py-src-newline"></span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">assert_squared</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">,</span> <span class="py-src-parameter">x</span><span class="py-src-op">,</span> <span class="py-src-parameter">y</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">assertEquals</span><span class="py-src-op">(</span><span class="py-src-variable">x</span><span class="py-src-op">*</span><span class="py-src-variable">x</span><span class="py-src-op">,</span> <span class="py-src-variable">y</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span><span class="py-src-dedent"></span><span class="py-src-dedent"></span><span class="py-src-keyword">class</span> <span class="py-src-identifier">MyTest</span><span class="py-src-op">(</span><span class="py-src-parameter">BaseTest</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">    </span><span class="py-src-string">"Tests set up a certain way."</span><span class="py-src-newline"></span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">setUp</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">x</span> <span class="py-src-op">=</span> <span class="py-src-variable">foo</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
        <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">y</span> <span class="py-src-op">=</span> <span class="py-src-variable">bar</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span>    <span class="py-src-dedent"></span><span class="py-src-keyword">def</span> <span class="py-src-identifier">tearDown</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-keyword">del</span> <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">x</span><span class="py-src-newline"></span>
        <span class="py-src-keyword">del</span> <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">y</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span>    <span class="py-src-dedent"></span><span class="py-src-keyword">def</span> <span class="py-src-identifier">test_something</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-string">"Run a test here."</span><span class="py-src-newline"></span>
        <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">assert_squared</span><span class="py-src-op">(</span><span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">x</span><span class="py-src-op">,</span> <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">y</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span><span class="py-src-dedent"></span><span class="py-src-dedent"></span><span class="py-src-keyword">class</span> <span class="py-src-identifier">MyOtherTest</span><span class="py-src-op">(</span><span class="py-src-parameter">BaseTest</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">    </span><span class="py-src-string">"Tests set up a certain way."</span><span class="py-src-newline"></span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">setUp</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">x</span> <span class="py-src-op">=</span> <span class="py-src-variable">foo</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
        <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">y</span> <span class="py-src-op">=</span> <span class="py-src-variable">bar</span><span class="py-src-op">(</span><span class="py-src-op">)</span> <span class="py-src-op">+</span> <span class="py-src-number">1</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span>    <span class="py-src-dedent"></span><span class="py-src-keyword">def</span> <span class="py-src-identifier">tearDown</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-keyword">del</span> <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">x</span><span class="py-src-newline"></span>
        <span class="py-src-keyword">del</span> <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">y</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span>    <span class="py-src-dedent"></span><span class="py-src-keyword">def</span> <span class="py-src-identifier">test_something_else</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-string">"Run a test here."</span><span class="py-src-newline"></span>
        <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">assert_squared</span><span class="py-src-op">(</span><span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">x</span><span class="py-src-op">,</span> <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">y</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span><span class="py-src-dedent"></span><span class="py-src-dedent"></span><span class="py-src-endmarker"></span>
</code>
</pre>

<p>So much redundant code, so little point. But with decorators, this can get a whole lot cleaner:</p>

<pre>
<code class="codelisting">
<span class="py-src-keyword">def</span> <span class="py-src-identifier">bless</span><span class="py-src-op">(</span><span class="py-src-parameter">wrapped</span><span class="py-src-op">,</span> <span class="py-src-parameter">fn</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">    </span><span class="py-src-string">"Do some decorator bureaucracy."</span><span class="py-src-newline"></span>
    <span class="py-src-variable">wrapped</span><span class="py-src-op">.</span><span class="py-src-variable">__name__</span> <span class="py-src-op">=</span> <span class="py-src-variable">fn</span><span class="py-src-op">.</span><span class="py-src-variable">__name__</span><span class="py-src-newline"></span>
    <span class="py-src-variable">wrapped</span><span class="py-src-op">.</span><span class="py-src-variable">__doc__</span>  <span class="py-src-op">=</span> <span class="py-src-variable">fn</span><span class="py-src-op">.</span><span class="py-src-variable">__doc__</span><span class="py-src-newline"></span>
    <span class="py-src-variable">wrapped</span><span class="py-src-op">.</span><span class="py-src-variable">__dict__</span> <span class="py-src-op">=</span> <span class="py-src-variable">fn</span><span class="py-src-op">.</span><span class="py-src-variable">__dict__</span><span class="py-src-newline"></span>
    <span class="py-src-keyword">return</span> <span class="py-src-variable">wrapped</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span><span class="py-src-dedent"></span><span class="py-src-keyword">def</span> <span class="py-src-identifier">test_a</span><span class="py-src-op">(</span><span class="py-src-parameter">fn</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">    </span><span class="py-src-keyword">def</span> <span class="py-src-identifier">wrapped</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-variable">fn</span><span class="py-src-op">(</span><span class="py-src-variable">foo</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-op">,</span> <span class="py-src-variable">bar</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
    <span class="py-src-dedent"></span><span class="py-src-keyword">return</span> <span class="py-src-variable">bless</span><span class="py-src-op">(</span><span class="py-src-variable">wrapped</span><span class="py-src-op">,</span> <span class="py-src-variable">fn</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span><span class="py-src-dedent"></span><span class="py-src-keyword">def</span> <span class="py-src-identifier">test_b</span><span class="py-src-op">(</span><span class="py-src-parameter">fn</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">    </span><span class="py-src-keyword">def</span> <span class="py-src-identifier">wrapped</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-variable">fn</span><span class="py-src-op">(</span><span class="py-src-variable">foo</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-op">,</span> <span class="py-src-variable">bar</span><span class="py-src-op">(</span><span class="py-src-op">)</span> <span class="py-src-op">+</span> <span class="py-src-number">1</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
    <span class="py-src-dedent"></span><span class="py-src-keyword">return</span> <span class="py-src-variable">bless</span><span class="py-src-op">(</span><span class="py-src-variable">wrapped</span><span class="py-src-op">,</span> <span class="py-src-variable">fn</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span><span class="py-src-nl">
</span><span class="py-src-dedent"></span><span class="py-src-keyword">class</span> <span class="py-src-identifier">MyTest</span><span class="py-src-op">(</span><span class="py-src-parameter">unittest</span><span class="py-src-op">.</span><span class="py-src-parameter">TestCase</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">    </span><span class="py-src-string">"A blissfully clear test class."</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span><span class="py-src-comment">#   Because I can keep everything on one class,
</span><span class="py-src-comment">#   there's no need for a base class to hold this.
</span>    <span class="py-src-keyword">def</span> <span class="py-src-identifier">assert_squared</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">,</span> <span class="py-src-parameter">x</span><span class="py-src-op">,</span> <span class="py-src-parameter">y</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">assertEquals</span><span class="py-src-op">(</span><span class="py-src-variable">x</span><span class="py-src-op">*</span><span class="py-src-variable">x</span><span class="py-src-op">,</span> <span class="py-src-variable">y</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span>    <span class="py-src-dedent"></span><span class="py-src-op">@</span><span class="py-src-variable">test_a</span><span class="py-src-newline"></span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">test_something</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">,</span> <span class="py-src-parameter">x</span><span class="py-src-op">,</span> <span class="py-src-parameter">y</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-string">"Run a test here."</span><span class="py-src-newline"></span>
        <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">assert_squared</span><span class="py-src-op">(</span><span class="py-src-variable">x</span><span class="py-src-op">,</span> <span class="py-src-variable">y</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span>    <span class="py-src-dedent"></span><span class="py-src-op">@</span><span class="py-src-variable">test_b</span><span class="py-src-newline"></span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">test_something</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">,</span> <span class="py-src-parameter">x</span><span class="py-src-op">,</span> <span class="py-src-parameter">y</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-string">"Run another test here."</span><span class="py-src-newline"></span>
        <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">assert_squared</span><span class="py-src-op">(</span><span class="py-src-variable">x</span><span class="py-src-op">,</span> <span class="py-src-variable">y</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span><span class="py-src-dedent"></span><span class="py-src-dedent"></span><span class="py-src-endmarker"></span>
</code>
</pre>

<p><em>(Hmm, I can&#8217;t ever seem to make all my tests pass at the same time&#8230;.)</em></p>

<p>There are some rough edges to this trick. To get the same semantics as <code>setUp</code> and <code>tearDown</code>, you have to write your decorator with a <code>try/finally</code> block like this:</p>

<pre>
<code class="codelisting">
<span class="py-src-keyword">def</span> <span class="py-src-identifier">test_a</span><span class="py-src-op">(</span><span class="py-src-parameter">fn</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">    </span><span class="py-src-keyword">def</span> <span class="py-src-identifier">wrapped</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">        </span><span class="py-src-variable">a</span><span class="py-src-op">,</span> <span class="py-src-variable">b</span> <span class="py-src-op">=</span> <span class="py-src-variable">do_setup</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
        <span class="py-src-keyword">try</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">            </span><span class="py-src-variable">fn</span><span class="py-src-op">(</span><span class="py-src-variable">a</span><span class="py-src-op">,</span> <span class="py-src-variable">b</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
        <span class="py-src-dedent"></span><span class="py-src-keyword">finally</span><span class="py-src-op">:</span><span class="py-src-newline"></span>
<span class="py-src-indent">            </span><span class="py-src-variable">do_teardown</span><span class="py-src-op">(</span><span class="py-src-variable">a</span><span class="py-src-op">,</span> <span class="py-src-variable">b</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
    <span class="py-src-dedent"></span><span class="py-src-dedent"></span><span class="py-src-keyword">return</span> <span class="py-src-variable">bless</span><span class="py-src-op">(</span><span class="py-src-variable">wrapped</span><span class="py-src-op">,</span> <span class="py-src-variable">fn</span><span class="py-src-op">)</span><span class="py-src-newline"></span>
<span class="py-src-nl">
</span><span class="py-src-dedent"></span><span class="py-src-endmarker"></span>
</code>
</pre>

<p>Furthermore, decorators can take arguments, and get considerably more complex when they do. (I&#8217;ll save my bitchfest about that for a later post.) For me, though, the benefits are significantly outweighing the costs.</p>

<p>Please feel free to share any caveats to this approach, or experiences making Python unit tests clearer and easier to write.</p>
]]></description>
</item>

</channel>
</rss>
