<?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>Mike&#039;s Blabberings &#187; testing</title>
	<atom:link href="http://www.mike-griffith.com/blog/tag/testing/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mike-griffith.com/blog</link>
	<description>on software, testing, and the web.</description>
	<lastBuildDate>Mon, 14 Feb 2011 10:51:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Python decorators, SRP, and testability</title>
		<link>http://www.mike-griffith.com/blog/2010/06/python-decorators-srp-and-testability/</link>
		<comments>http://www.mike-griffith.com/blog/2010/06/python-decorators-srp-and-testability/#comments</comments>
		<pubDate>Fri, 04 Jun 2010 06:30:02 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[software development]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://www.mike-griffith.com/blog/?p=504</guid>
		<description><![CDATA[On the SRP:
For those unfamiliar with the Single Responsibility Principle (SRP), it states that there should never be more than one reason for a class to change.
That is to say: do one thing, do it well.
Decorators (not to be confused with the decorator pattern) can add behaviors or side-effects to a method, and this can [...]]]></description>
			<content:encoded><![CDATA[<p><strong>On the SRP:</strong><br />
For those unfamiliar with the <a href="http://www.butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod" target="_blank">Single Responsibility Principle</a> (SRP), it states that <em>there should never be more than one reason for a class to change</em>.</p>
<p>That is to say: do one thing, do it well.</p>
<p><a href="http://www.python.org/dev/peps/pep-0318/" target="_blank">Decorators</a> (not to be confused with the <a href="http://en.wikipedia.org/wiki/Decorator_pattern" target="_blank">decorator pattern</a>) can add behaviors or side-effects to a method, and this can be dangerous.  It seems harmless, because by adding a decorator, you&#8217;re likely taking boilerplate code and shuffling it elsewhere.  However, they often encourage badness because of how easy it is to add these behaviors.</p>
<p><strong>On testing decorated methods:</strong></p>
<p>Adding an @decorator to a python object unarguably makes the undecorated code difficult to test in isolation.  Decorators are applied at compile-time, and cannot be mocked or made to not-execute without some pain.</p>
<p>There are certainly a few common tricks that can help test a decorated method with minimal side-effects, but they require changes to the decorator itself.  There&#8217;s just plain and simple no way to un-decorate a method for isolated testing.</p>
<p><strong>Let&#8217;s look at a few common examples:</strong></p>
<p><strong><em>@expose</em></strong>: register a URL for a view function in a web framework</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> BlogPostController<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    @expose<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/blog/{post_id}&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> index<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, request, post_id=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot; show a blog post &quot;&quot;&quot;</span>
        post = adapter.<span style="color: black;">get_post</span><span style="color: black;">&#40;</span>post_id<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> render<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;show_entry.html&quot;</span>, <span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>post=post<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Without the `@expose`, your `show_entry` knows how to get a given post and render it in the proper template.  With the decorator, it also now knows which URL corresponds to that.  You now have multiple reasons for this block of code to change, including pointing to a different URL or using a different template.  It&#8217;s preferred to have a separate module for managing which urls point to which views.</p>
<p>Harm factor: low.  Ick factor: medium &#8211; high.</p>
<p><strong><em>@cache</em></strong>: try to get the result from memcache, otherwise, execute the function and stick it in cache for next time</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> PostAdapter<span style="color: black;">&#40;</span>DataAdapter<span style="color: black;">&#41;</span>:
    @cache
    <span style="color: #ff7700;font-weight:bold;">def</span> get_post<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, post_id<span style="color: black;">&#41;</span>
        <span style="color: #483d8b;">&quot;&quot;&quot; grab a blog post from the database &quot;&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">query</span><span style="color: black;">&#40;</span>Post<span style="color: black;">&#41;</span>.<span style="color: #008000;">filter</span><span style="color: black;">&#40;</span><span style="color: #008000;">id</span>=post_id<span style="color: black;">&#41;</span>.<span style="color: black;">one</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># SQLAlchemy folks need to talk to Mr Demeter...</span></pre></div></div>

<p>OK this seems cool right?  You only hit the database when you have to, otherwise we get it even quicker by looking it up in the cache.</p>
<p>What happens if you want to disable caching?  A separate cache abstraction layer would reduce volatility in your data adapter.</p>
<p>And what does the unit test look like?</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> TestGettingAPost<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> setup<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">query</span> = Mock<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#don't hit the production database!</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">post_adapter</span> = PostAdapter<span style="color: black;">&#40;</span>query=<span style="color: #008000;">self</span>.<span style="color: black;">query</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> test_getting_a_post<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #008000;">self</span>.<span style="color: black;">post_adapter</span>.<span style="color: black;">get_post</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">123</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Damn, there&#8217;s no way to mock out the @cache decorator so it doesn&#8217;t run.  Try to, I dare you.  You&#8217;re likely going to actually get post 123 from your production memcache.  Crappy.  The only thing you can do is make the @cache grab the cache implementation from the PostAdapter instance (and mock that out in you test), or find some other sneaky way of disabling caching for test runs.  But the @cache decorator isn&#8217;t all self-contained and fun anymore.</p>
<p>Harm factor: medium &#8211; high.</p>
<p><strong><em>@validate</em></strong>: Make sure the request matches the specified schema, otherwise hand-off to error handler</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> EditPostController<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> _save_error<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, request, errors<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot; @validate decorator kicked flow here, redisplay edit page with errors &quot;&quot;&quot;</span>
        ...
    @validate<span style="color: black;">&#40;</span>schema, error_handler=_save_error<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> save<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, request<span style="color: black;">&#41;</span>
        post = <span style="color: #008000;">self</span>.<span style="color: black;">schema</span>.<span style="color: black;">to_python</span><span style="color: black;">&#40;</span>request.<span style="color: black;">params</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">post_adapter</span>.<span style="color: black;">save_post</span><span style="color: black;">&#40;</span>post<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> redirect<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/blog/{0}&quot;</span>.<span style="color: black;">format</span><span style="color: black;">&#40;</span>post_id<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Without this @validate, there would be a lot of boilerplate code inside the `save` method.  With it, any unit test for the save method will be likely linked to your schema.  You&#8217;d have to make an actual valid request in order to test this method.  That&#8217;s outside of any tests for your schema directly. That means double-coverage but 2 tests to update when requirements shift.</p>
<p>Harm factor: low-medium</p>
<p><strong>Conclusions (or tl;dr):</strong></p>
<p>As easy as it is to become infatuated with Python decorators, they definitely encourage you to violate the SRP.  This can create a myriad of problems:</p>
<ul>
<li>Difficultly in isolating system under test</li>
<li>Added complexity to enable testing</li>
<li>Redundant redundant unit tests</li>
<li>Making a code module more volatile than it ought to</li>
</ul>
<p>They still have some valid use cases and can lead to cleaner code, however,  as Master Yoda once said, &#8220;when you look at the dark side, careful you must be&#8230;&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mike-griffith.com/blog/2010/06/python-decorators-srp-and-testability/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Show me the $80 million dollar Blue (#0044cc)</title>
		<link>http://www.mike-griffith.com/blog/2010/03/show-me-the-80-million-dollar-blue-0044cc/</link>
		<comments>http://www.mike-griffith.com/blog/2010/03/show-me-the-80-million-dollar-blue-0044cc/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 17:01:40 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[software development]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[design]]></category>

		<guid isPermaLink="false">http://www.mike-griffith.com/blog/?p=371</guid>
		<description><![CDATA[So what&#8217;s this fancy shade of blue that made Bing so much money look like?

&#160;

Eh.  Doesn&#8217;t really do it for me as a blob of color.
How about on a link?  Well, that is actually quite pleasant against a white background.
Regardless, the takeaway from the whole story isn&#8217;t that you should switch all your [...]]]></description>
			<content:encoded><![CDATA[<p>So what&#8217;s this <a href="http://www.lukew.com/ff/entry.asp?1025" target="_blank">fancy shade of blue that made Bing so much money</a> look like?</p>
<div style="border: 1px solid #888888;background-color: #0044cc;width: 150px;height: 50px;">
&nbsp;
</div>
<p>Eh.  Doesn&#8217;t really do it for me as a blob of color.</p>
<p>How about <a style="color: #0044cc;" href="javascript:void(0);">on a link</a>?  Well, that is actually quite pleasant against a white background.</p>
<p>Regardless, the takeaway from the whole story isn&#8217;t that you should switch all your colors to #0044cc, but rather that you need to rigorously test your audience and be able to make changes based on the observed behavior.  Having the discipline to carefully react to the measurements can and will drive success.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mike-griffith.com/blog/2010/03/show-me-the-80-million-dollar-blue-0044cc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

