<?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>Coyote Tracks &#187; best practices</title>
	<atom:link href="http://kai.mactane.org/blog/tag/best-practices/feed/" rel="self" type="application/rss+xml" />
	<link>http://kai.mactane.org/blog</link>
	<description>The prints of an Internet-enabled coyote.</description>
	<lastBuildDate>Fri, 10 Sep 2010 01:40:02 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Can You Learn From a Prediction That Was Wrong?</title>
		<link>http://kai.mactane.org/blog/2010/04/07/can-you-learm-from-a-prediction/</link>
		<comments>http://kai.mactane.org/blog/2010/04/07/can-you-learm-from-a-prediction/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 04:07:38 +0000</pubDate>
		<dc:creator>Kai MacTane</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[opinion]]></category>
		<category><![CDATA[should have known better]]></category>
		<category><![CDATA[the world-wide conversation]]></category>
		<category><![CDATA[where are we going?]]></category>

		<guid isPermaLink="false">http://kai.mactane.org/blog/?p=204</guid>
		<description><![CDATA[Recently, a bunch of the blogs and journals I read (including my friends, not just big, famous sources) have had some bones to pick with Clifford Stoll&#8217;s 1995 Newsweek opinion piece, &#8220;Why Web Won&#8217;t Be Nirvana&#8221;. Stoll said: &#8220;no online database will replace your daily newspaper, no CD-ROM can take the place of a competent [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, a bunch of the blogs and journals I read (including my friends, not just big, famous sources) have had some bones to pick with <a href="http://www.newsweek.com/id/106554/">Clifford Stoll&#8217;s 1995 <cite>Newsweek</cite> opinion piece, &#8220;Why Web Won&#8217;t Be Nirvana&#8221;</a>. Stoll said: &#8220;no online database will replace your daily newspaper, no CD-ROM can take the place of a competent teacher and no computer network will change the way government works.&#8221;</p>
<p>A lot of people have been, effectively, pointing and laughing at Stoll&#8217;s failed prediction. I&#8217;d rather consider it a cautionary tale: The man who was so totally wrong wasn&#8217;t just a random pundit who didn&#8217;t know what he was talking about. He was Clifford Stoll&nbsp;&mdash; author of <cite>The Cuckoo&#8217;s Egg</cite>, a man who had been online for 20 years at a time when most people were just beginning to hear that there was a such thing as the World-Wide Web, and the man who traced German <a href="http://catb.org/~esr/jargon/html/C/cracker.html">cracker</a> Markus Hess through umpteen layers of insecure computer systems and networks.</p>
<p>In short, the man <em>knew what he was talking about</em>. He wasn&#8217;t a <a href="http://www.boingboing.net/2006/07/02/sen_stevens_hilariou.html">Senator Ted Stevens</a>. If he could be so wrong, <strong>how much faith can I place in my own predictions</strong> about where the Internet&#8217;s headed?</p>
<p>But wait, there&#8217;s more&nbsp;&mdash; <em>how wrong was he?</em> <span id="more-204"></span>Sure, Stoll claims that &#8220;no online database will replace your daily newspaper&#8221;, which has turned out to be completely false. But how about &#8220;no CD-ROM can take the place of a competent teacher&#8221;? No matter how interactive the CD, it can&#8217;t substitute for a <em>good</em> human teacher&#8217;s ability to guide and nurture a student&#8217;s intellect. (Not without AI, which is still at least 20 years away &#8212; just like it&#8217;s been for the past 50 years.)</p>
<p>And maybe you think it&#8217;s obvious that CD-ROMs can&#8217;t replace real teachers. But there have been, and <em>there still are</em>, people who claim their CDs are just effective as face-to-face teaching methods &#8212; <a href="http://www.rosettastone.com/personal/how-it-works/faq#qa3">or even more effective</a>.</p>
<p>Stoll gripes about the problems of Usenet. Okay, the main bulk of Internet conversation has moved to blogs and comment threads, but his words still apply: &#8220;Every voice can be heard cheaply and instantly. The result? Every voice is heard. The cacophony more closely resembles citizens band radio, complete with handles, harassment, and anonymous threats.&#8221;* There&#8217;s a reason why many of my friends say, &#8220;Never waste your time reading the comments.&#8221;</p>
<p>I&#8217;ve <a href="http://kai.mactane.org/blog/2009/02/25/death-threats-against-bloggers/">written before about the effects of &#8220;harassment and anonymous threats&#8221;</a>. That was just last year, and I doubt that all the anonymous threateners have suddenly left the Internet.</p>
<p>It&#8217;s very easy to look at Stoll&#8217;s rant and get distracted by the petty details: &#8220;Usenet? Hah! How archaic!&#8221; But that&#8217;s just a way of trying to remain comfortable, and ignoring the ways in which things haven&#8217;t changed one bit. Because <a href="http://www.penny-arcade.com/comic/2004/3/19/" title="also known as the &quot;Greater Internet Fuckwad Theory&quot;">the problems of anonymity</a> aren&#8217;t technological problems; they&#8217;re problems of human nature.</p>
<p>But even in the places where Stoll was wrong &#8212; demonstrably, ridiculously wrong &#8212; it does me no good to simply point and laugh. Instead, I&#8217;d rather ask myself, &#8220;Could I have done any better?&#8221; Stoll claimed that online shopping would never take off:</p>
<blockquote><p>[Internet hucksters promise that] We&#8217;ll order airline tickets over the network, make restaurant reservations and negotiate sales contracts. Stores will become obsolete. So how come my local mall does more business in an afternoon than the entire Internet handles in a month? Even if there were a trustworthy way to send money over the Internet &#8212; which there isn&#8217;t &#8212; the network is missing a most essential ingredient of capitalism: salespeople.</p></blockquote>
<p>He&#8217;s wrong on almost every particular; the only one that might possibly be an exception is &#8220;negotiat[ing] sales contracts&#8221;. Aside from that? I&#8217;ve lost track of how many restaurant reservations I&#8217;ve made online and how many airplane tickets I&#8217;ve bought online; over the past ten years, I&#8217;m quite positive that I&#8217;ve done those things far more often online than by &#8220;traditional&#8221; methods. Even if you don&#8217;t consider PayPal to be quite trustworthy, online credit-card transactions are now safe and secure.</p>
<p>And salespeople? Most of the time, I can do without them. I can&#8217;t help but remember the last time my girlfriend and I visited a Victoria&#8217;s Secret; after being approached by 5 different salespeople in as many minutes, we left the store in frustration at being interrupted and distracted so much &#8212; to the point that we couldn&#8217;t even browse the merchandise in peace!</p>
<p>Great, so Stoll was totally wrong about online shopping. If you&#8217;d asked me about it in 1995, <em>what would <strong>I</strong> have said?</em> Would my predictions have been any better?</p>
<p>And more to the point: What am I predicting right now? And how wrong am I? And how can I learn from Stoll&#8217;s mistakes &#8212; or my own &#8212; and make better predictions?</p>
<p>That&#8217;s the real take-away from Stoll&#8217;s article. And those are question I don&#8217;t have the answers for yet. (If you&#8217;ve got answers, leave a comment and tell me!)</p>
<p>* All quotes from <cite>Newsweek</cite> edited to fix simple spelling mistakes.</p>
]]></content:encoded>
			<wfw:commentRss>http://kai.mactane.org/blog/2010/04/07/can-you-learm-from-a-prediction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How Many Ways Is Your Imitation Scrollbar Broken?</title>
		<link>http://kai.mactane.org/blog/2009/12/13/why-your-imitation-scrollbar-is-broken/</link>
		<comments>http://kai.mactane.org/blog/2009/12/13/why-your-imitation-scrollbar-is-broken/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 20:25:39 +0000</pubDate>
		<dc:creator>Kai MacTane</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[bad ideas]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[opinion]]></category>
		<category><![CDATA[snark]]></category>
		<category><![CDATA[ui]]></category>
		<category><![CDATA[usability]]></category>
		<category><![CDATA[ux]]></category>

		<guid isPermaLink="false">http://kai.mactane.org/blog/?p=155</guid>
		<description><![CDATA[If you&#8217;re going to reinvent the wheel, you should at least make sure your new version is somehow better than the previous kind. Reimplementing standard UI and OS widgets is one of the most common ways developers reinvent the wheel these days&#160;&#8212; it started with Flash developers building their own controls, and has now spread [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re going to reinvent the wheel, you should at least make sure your new version is somehow better than the previous kind. Reimplementing standard UI and OS widgets is one of the most common ways developers reinvent the wheel these days&nbsp;&mdash; it started with Flash developers building their own controls, and has now spread to Adobe&nbsp;AIR and Silverlight.</p>
<p>It might be a welcome trend, if the replacement widgets people were building had more functionality than the OS-native ones that are available for free in any other context. But usually, the widgets I see in these frameworks have less than half the functionality of the things they try to replace. I&#8217;m going to pick on scroll bars for now, because I&#8217;ve seen them horribly mangled too many times.</p>
<p>To start with one aspect of scroll bars that we often take for granted: Can you guess which of these text boxes contains more text?</p>
<p><textarea style="float: left; width: 40%; height: 10em; margin: 0 1em;">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Quisque est est, luctus quis suscipit et, lacinia ac odio.</textarea></p>
<p><textarea style="float: left; width: 40%; height: 10em; margin: 0 1em;">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.</textarea><br />
<br clear="left"><br />
<span id="more-155"></span><br />
Of course you can; you don&#8217;t even need to guess. The one on the left has more, and you can tell immediately because the movable slider on its scrollbar <em>is smaller</em>. This is a feature you get for free from the native OS widget, and one I have never seen implemented in a Flash, AIR, or similar interface.</p>
<p>Here are all the things a native scrollbar does. I absolutely guarantee you, if you&#8217;ve reinvented a scrollbar, your implementation is missing at least two of these features:</p>
<ol>
<li>As mentioned above, the slider object changes size automatically, to give a general impression of how much content the scrollable area contains.</li>
<li>The arrows at the top and bottom of the scrollbar are clickable, and clicking them once will move the content up and down by a small amount (typically 1 or 2 lines).</li>
<li>Clicking and holding the top and bottom arrows will cause the content to scroll more rapidly.</li>
<li>Clicking and dragging on the slider will scroll the content smoothly to any position the user chooses. (Yes, I have seen scrollbar implementations in which the slider <em>was not</em> a draggable item!)</li>
<li><strong>Scroll wheel support:</strong> If the user&#8217;s hardware includes a scroll wheel, scrolling it will move the content up and down. This is many users&#8217; preferred method of scrolling content these days, and yet it&#8217;s totally ignored by over half the Flash interfaces I&#8217;ve encountered in the past year. I&#8217;ve bolded it because it&#8217;s the one that gets so egregiously ignored.</li>
<li>The &#8220;gutter&#8221; <em>in between</em> the arrows and slider is also clickable. Clicking on it once will scroll the content up or down by, roughly, the size of the visible area (a &#8220;page&#8221;, as it were).</li>
<li>Of course, clicking and holding in the &#8220;gutter&#8221; area will repeatedly and rapidly scroll the content. (This is rarely apparent unless you&#8217;re dealing with a tall scrollable area <em>and</em> a fairly long document. Try loading a 25-page or longer document into a word processing program, and set the program to full-screen.)</li>
<li>When the content is scrolled (by whatever method), the slider will move up or down to indicate how far from the beginning or end you are. (Essentially the converse of item #4: Moving the slider scrolls the content, and scrolling through the content moves the slider.)</li>
<li>The arrow buttons and the gutter area give a visual indication when they&#8217;ve been clicked, so the user has better feedback. (This is one of those little things that makes the user experience so much better. It&#8217;d be so easy to do, and yet I&#8217;ve seen about 2 Flash scrollbars in my life that have bothered with that feature.)</li>
<li>If you set your cursor focus on the scrollable area, using the up and down arrow keys will scroll the content. Either the Home and End or Ctrl+Home and Ctrl+End keystrokes will move directly to the beginning and end of the content. The PgUp and PgDown keys may also move the content by an amount similar to clicking in the gutter.</li>
<li>The scrollbar&nbsp;&mdash; including its arrows, gutter and slider&nbsp;&mdash; looks just like every other scrollbar on the user&#8217;s computer. The user can immediately identify the items and finds them familiar.</li>
</ol>
<p>Even if you have done a smashing job of replicating the first 10 points on this list, you simply can&#8217;t get the final one in an AIR, Silverlight, or Flash interface. If your whiz-bang interface platform provides some other benefit, then dropping that last feature might be worth it.</p>
<p>But it&#8217;s no excuse for dropping all the other stuff. Most non-native scroll bars I&#8217;ve seen support only 3 or 4 of these features, which means anyone who normally uses any other ways of interacting with scrollbars winds up cursing and deciding that this broken implementation is cheap and chintzy.</p>
<p>Which it is. If you&#8217;re going to reimplement the wheel, at least make it something that will roll smoothly.</p>
]]></content:encoded>
			<wfw:commentRss>http://kai.mactane.org/blog/2009/12/13/why-your-imitation-scrollbar-is-broken/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Testing Backward-Incompatible Changes</title>
		<link>http://kai.mactane.org/blog/2009/10/12/testing-backward-incompatible-changes/</link>
		<comments>http://kai.mactane.org/blog/2009/10/12/testing-backward-incompatible-changes/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 18:06:20 +0000</pubDate>
		<dc:creator>Kai MacTane</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://kai.mactane.org/blog/?p=135</guid>
		<description><![CDATA[Let&#8217;s say one day you decide to add a feature to your software or service. For example, you need a new flag on user accounts, so that different types of users get different features. (These don&#8217;t even have to be tiered account levels; maybe accounts of type &#8220;music lover&#8221; get a widget in the sidebar [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s say one day you decide to add a feature to your software or service. For example, you need a new flag on user accounts, so that different types of users get different features. (These don&#8217;t even have to be tiered account levels; maybe accounts of type &#8220;music lover&#8221; get a widget in the sidebar with suggestions for bands they might like while &#8220;sports fan&#8221; accounts get a sports scores widget instead.)</p>
<p>So, following good software development processes, you first write a couple of tests:</p>
<p><span id="more-135"></span>UserTypeOne gets features A, B, and C<br />
UserTypeOne does not get features D, E, or F<br />
UserTypeTwo does not get features A, B, or C<br />
UserTypeTwo gets features D, E, and F</p>
<p>Then you write some code that meets these tests, including creating a pair of mock users with the new flag set in both possible ways. You run the tests, and they all pass. Yay! Your new feature is ready!</p>
<p>Except that, of course, the moment you check this code in, you find that suddenly, <em>nobody can log in any more</em>. After all, the new flag is supposed to be mandatory, and that requirement is reflected in one of the changes you made to the login code. But the only users that have the NewFlag at all are the ones you just created in your fixture.</p>
<p>Sure, this will probably get caught before it goes live. Even if your entire QA department is asleep at the switch, if just one person in your organization tries to run even the most rudimentary tests, they&#8217;ll get back an error message. But &#8220;it didn&#8217;t get pushed to production&#8221; is only the most minimal level of success; I&#8217;d like to look at how <em>you</em>, the coder, could have prevented this problem. How could you keep this error from even getting checked in (and thus breaking the build and flat-lining your co-workers&#8217; productivity for a few hours)?</p>
<p>The way a real QA department would spot this problem is regression testing. But it&#8217;s not reasonable to ask every coder to do a full suite of regression tests before every commit.</p>
<p>The real failure, of course, is that you made a change that you didn&#8217;t test. But saying &#8220;force programmers to write better tests&#8221; is not a viable answer; people are imperfect. You might as well mandate &#8220;developers may not check in any code that contains bugs&#8221; as one of your organization&#8217;s rules.</p>
<p>I don&#8217;t have a good answer to this problem. Asking developers to also be QA people is completely impractical. The current solution seems to be &#8220;developers sometimes check in code which breaks the build, and blocks people&#8217;s productivity for a while&#8221;. (Distributed SCM can help mitigate this.)</p>
<p>Is there something QA people know that developers don&#8217;t, that would make an easy solution that we could adopt?</p>
]]></content:encoded>
			<wfw:commentRss>http://kai.mactane.org/blog/2009/10/12/testing-backward-incompatible-changes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Notes on LJ Content Sieve</title>
		<link>http://kai.mactane.org/blog/2009/07/04/notes-on-lj-content-sieve/</link>
		<comments>http://kai.mactane.org/blog/2009/07/04/notes-on-lj-content-sieve/#comments</comments>
		<pubDate>Sat, 04 Jul 2009 21:07:42 +0000</pubDate>
		<dc:creator>Kai MacTane</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[my projects]]></category>
		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://kai.mactane.org/blog/?p=78</guid>
		<description><![CDATA[My latest project is something I call &#8220;LJ Content Sieve&#8221;: a Greasemonkey script to filter out content on one&#8217;s Livejournal views based on nearly any attribute of a post or comment.
However, Livejournal is very customizable. It has 31 different &#8220;layouts&#8221;, each of which can then be further &#8220;themed&#8221; by application of CSS. This means that [...]]]></description>
			<content:encoded><![CDATA[<p>My latest project is something I call &#8220;LJ Content Sieve&#8221;: a Greasemonkey script to filter out content on one&#8217;s Livejournal views based on nearly any attribute of a post or comment.</p>
<p>However, Livejournal is very customizable. It has 31 different &#8220;layouts&#8221;, each of which can then be further &#8220;themed&#8221; by application of CSS. This means that a user viewing a given journal, community, or single post, at a given time, may receive an HTML document containing any of 31 different DOM structures.</p>
<p>This means that finding a post&#8217;s author, or title, or even just a single post or comment, is not a straightforward process. I&#8217;ve set myself up a Ruby script that downloaded my &#8220;friends&#8221; view, a representative entry with lots of comments, and my own journal view, thus giving me a set of 93 fixtures that I can test against. The Ruby script also tweaked each fixture in the process of spooling it to my hard drive, by adding the proper calls to JSUnit files.</p>
<p>At the end of each document&#8217;s &lt;head&gt; element, there&#8217;s a call to <code>jsUnitCore.js</code>. Then, at the end of each &lt;body&gt;, I add a call to the <code>lj-content-sieve.user.js</code> script itself, as well as a set of test files that depends on which fixture this is. Every fixture gets an <code>ljcs-global-tests.js</code> call added to it&nbsp;&mdash; that file contains tests that should work anywhere, regardless of what sort of page you&#8217;re on.</p>
<p>Then all the &#8220;friends&#8221; page fixtures get an <code>ljcs-friends-tests.js</code> file, which tests operations that should happen on every friends page. For example, determining which entries need to be deleted. (In contrast, single-entry pages get <code>ljcs-entry-tests.js</code>, and the page from my own journal&nbsp;&mdash; which stands in for a view of a community&nbsp;&mdash; gets <code>ljcs-self-tests.js</code>.)</p>
<p>Finally, each fixture page gets a test file based on its layout: the &#8220;3 Column&#8221; layout gets <code>ljcs-3&nbsp;Column-tests.js</code>, while &#8220;Cuteness Attack&#8221; gets <code>ljcs-Cuteness&nbsp;Attack-tests.js</code>. (Hey, I didn&#8217;t write or name the layouts; I just have to make sure LJCS works with all of &#8216;em.) These files will test that the actual DOM manipulations work properly.</p>
<p>Without test-driven development and automated testing to ensure that each layout and page-type is being handled properly, I don&#8217;t think this project would be manageable at all.</p>
]]></content:encoded>
			<wfw:commentRss>http://kai.mactane.org/blog/2009/07/04/notes-on-lj-content-sieve/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Would Shlemiel the Painter Optimize Prematurely?</title>
		<link>http://kai.mactane.org/blog/2009/06/18/would-shlemiel-the-painter-optimize-prematurely/</link>
		<comments>http://kai.mactane.org/blog/2009/06/18/would-shlemiel-the-painter-optimize-prematurely/#comments</comments>
		<pubDate>Thu, 18 Jun 2009 21:34:51 +0000</pubDate>
		<dc:creator>Kai MacTane</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[big o notation]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[diary]]></category>
		<category><![CDATA[my projects]]></category>

		<guid isPermaLink="false">http://kai.mactane.org/blog/?p=73</guid>
		<description><![CDATA[I don&#8217;t want to optimize this code prematurely. And &#8220;while you&#8217;re still writing it&#8221; is probably premature. On the other hand, totally ignoring algorithmic complexity is a sure route to a Shlemiel the Painter&#8217;s algorithm.
Do I really want to just write the whole thing, and then start profiling it to see where the hot spots [...]]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t want to <a href="http://shreevatsa.wordpress.com/2008/05/16/premature-optimization-is-the-root-of-all-evil/">optimize this code prematurely</a>. And &#8220;while you&#8217;re still writing it&#8221; is probably premature. On the other hand, totally ignoring algorithmic complexity is a sure route to a <a href="http://www.joelonsoftware.com/articles/fog0000000319.html">Shlemiel the Painter&#8217;s algorithm</a>.</p>
<p>Do I really want to just write the whole thing, and then start profiling it to see where the hot spots are, and then possibly have to re-design the whole thing? That seems like the complete opposite of &#8220;work smarter, not harder&#8221;. Then again, it doesn&#8217;t matter if you write an O(<i>n</i><sup>2</sup>) or even O(<i>n</i>!) algorithm if <i>n</i> is always going to be small&#8230; and in this application, I expect low-to-middling <i>n</i> values.</p>
<p>Of course, even if <i>n</i> will always be small, and increasing CPU power is my friend&#8230; even if it performs fast enough to make users happy, I&#8217;ll still know there&#8217;s a problem down there in the details. That may be the deciding factor.</p>
]]></content:encoded>
			<wfw:commentRss>http://kai.mactane.org/blog/2009/06/18/would-shlemiel-the-painter-optimize-prematurely/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>TDD and Peace of Mind</title>
		<link>http://kai.mactane.org/blog/2009/05/04/tdd-and-peace-of-mind/</link>
		<comments>http://kai.mactane.org/blog/2009/05/04/tdd-and-peace-of-mind/#comments</comments>
		<pubDate>Mon, 04 May 2009 16:53:10 +0000</pubDate>
		<dc:creator>Kai MacTane</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[my projects]]></category>
		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://kai.mactane.org/blog/2009/05/04/tdd-and-peace-of-mind/</guid>
		<description><![CDATA[Let&#8217;s face it, we&#8217;re not perfect. As much as I might realize that automated testing is a good practice, it still feels like a chore sometimes. In my latest round of personal-project development, just setting up a decent set of test fixtures and a working test framework turned into something of a hassle, as it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s face it, we&#8217;re not perfect. As much as I might realize that automated testing is a good practice, it still <em>feels</em> like a chore sometimes. In my latest round of personal-project development, just setting up a decent set of test fixtures and a working test framework turned into something of a hassle, as it&#8217;s my first attempt both at Greasemonkey scripting <em>and</em> at building a script that will act on Livejournal pages. (Since LJ users can customize their views with any of 36 basic &#8220;styles&#8221;, this means quite a few fixtures.)</p>
<p>So it was awfully tempting to say &#8220;screw this!&#8221; and just start writing code&nbsp;&mdash; you know, &#8220;code that works, code that gets stuff done&#8221;. Actual <em>program logic</em>, instead of testing tools. &#8220;Why don&#8217;t I just get something built to begin with,&#8221; I asked myself, &#8220;and then I can try to test that?&#8221;</p>
<p>Ha, ha. Of course, we all know that starting off without any tests just makes it easier to continue without them later. So I took the virtuous road, forced myself to get tests working, but allowed myself to skimp by only setting up fixtures for 3 of the 36 styles. The other styles are something I will <em>have to</em> go back and fill in before I can release, so there&#8217;s no chance I&#8217;ll &#8220;give myself permission&#8221; to blow them off.</p>
<p>When you really want to be writing code (because let&#8217;s face it, you consider yourself a coder, not a tester), it&#8217;s pretty annoying to write tests instead. But writing tests is at least a form of writing; if you&#8217;re not even writing tests, but rather setting up a test framework and fixtures, that&#8217;s almost excruciating.</p>
<p>But it all became worth it the moment I made a change in one of my basic data structures. I had a structure (what a Perlist would call a hash of arrays) that held information about how to identify which LJ style the page uses. Then I realized I didn&#8217;t want to have a separate structure for how to manipulate the page; instead, all information about LJ&#8217;s styles and DOM structure should live in one place.</p>
<p>So I altered the structure, then altered the functions created so far that rely on it. And that&#8217;s where I would then have to wonder, &#8220;How badly did I break everything?&#8221; Instead, I just ran my JSunit tests again. And seeing them pass was instant peace of mind. I don&#8217;t have to worry that there&#8217;s some hidden flaw waiting there, ready to be exposed by a user doing something unexpected. And as I add the other styles, I can easily be sure my code works for them, as well.</p>
<p>I&#8217;m still fairly early in the development of this code, and while unit testing has cost me a bit of time, it&#8217;s given me back <em>peace of mind</em>. The time profit? I have no doubt that will come later. (And had I made any errors in my data-structure change, the unit tests would have helped me find them more quickly than the usual debugging methods.)</p>
]]></content:encoded>
			<wfw:commentRss>http://kai.mactane.org/blog/2009/05/04/tdd-and-peace-of-mind/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
