<?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>The Daily Build &#187; process</title>
	<atom:link href="http://blog.bstpierre.org/category/process/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.bstpierre.org</link>
	<description>Software Development, version 3.0</description>
	<lastBuildDate>Fri, 03 Feb 2012 02:59:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Who Else Wants Better Short Term Memory?</title>
		<link>http://blog.bstpierre.org/who-else-wants-better-short-term-memory</link>
		<comments>http://blog.bstpierre.org/who-else-wants-better-short-term-memory#comments</comments>
		<pubDate>Thu, 12 Nov 2009 13:13:24 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[engineering]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[codereview]]></category>
		<category><![CDATA[coding-standard]]></category>
		<category><![CDATA[software-engineering]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=197</guid>
		<description><![CDATA[In &#8220;Talent is Overrated&#8221;, Geoff Colvin at one point discusses how superstars in many fields use the memory technique of &#8220;chunking&#8221; to boost their short term memory. His simple example is the 13-letter word &#8220;lexicographer&#8221;. To you and I (assuming you speak English and have a decent vocabulary), it is easy to remember. We don&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>In <a title="&quot;Talent is Overrated&quot; by Geoff Colvin -- on Amazon" href="http://www.amazon.com/dp/1591842247/?tag=bstpierreorg-20">&#8220;Talent is Overrated&#8221;</a>, Geoff Colvin at one point discusses how superstars in many fields use the memory technique of &#8220;<a title="More about chunking on wikipedia." href="http://en.wikipedia.org/wiki/Chunking_(psychology)">chunking</a>&#8221; to boost their short term memory.</p>
<p>His simple example is the 13-letter word &#8220;lexicographer&#8221;. To you and I (assuming you speak English and have a decent vocabulary), it is easy to remember. We don&#8217;t have to remember 13 letters, we just remember the whole chunk. But when presented with &#8220;trgdpxhdewfwm&#8221; for 3 seconds, you probably can&#8217;t remember more than half a dozen letters.</p>
<p>Another example is that chess masters can recall board positions after being shown a chess board with pieces on it for just a few seconds. They do this by chunking sets of pieces together &#8212; almost like &#8220;words&#8221; &#8212; whereas novices will try to remember individual pieces (&#8220;letters&#8221;).</p>
<p>It struck me that programmers do the same thing when reading and writing code.</p>
<p>The coding standard helps us, by telling us where the chunks are and how to draw the boundaries between chunks.</p>
<p>If you have a coding standard.</p>
<p>And apply it consistently.</p>
<p><strong>When you choose names at random, you destroy your short term memory.</strong> You become a crappy programmer, and you drag everyone around you down too.</p>
<p>Quick example in C. Assume you&#8217;re writing a small module for checking environmental status.</p>
<pre style="padding-left: 30px;">BOOL isOverTemp();
BOOL isUnderTemp();

int GetCurTemperature();

BOOL env_isOverVoltage();
BOOL env_isUnderVoltage();</pre>
<p>Anyone writing this pile of gibberish should be <span style="text-decoration: line-through;">fired</span> excommunicated.</p>
<p>Why?</p>
<p>For starters, I just wrote it, and I can&#8217;t now remember which was camel case and which was underscored. Also: which one was abbreviated?</p>
<p>Before you object that this is a contrived example, two points: (1) yes, it is contrived, that&#8217;s the point of an example, and (2) I have worked with far worse on an almost daily basis &#8212; the example above is fairly tame.</p>
<p>On the other hand, if you know the coding standard has some simple rules &#8212; <strong>and they are followed uniformly</strong> &#8212; you can easily remember the function names.</p>
<ol>
<li>Initial 2-3 letter module prefix (&#8220;env&#8221; for this example).</li>
<li>All functions are lowercase with underscores.</li>
<li>No abbreviations.</li>
</ol>
<p>Then we have:</p>
<pre style="padding-left: 30px;">BOOL env_is_over_temperature();
BOOL env_is_under_temperature();

int env_get_cur_temperature();

BOOL env_is_over_voltage();
BOOL env_is_under_voltage();</pre>
<p>Now, when you&#8217;re writing, reviewing, or maintaining code, you don&#8217;t need to constantly refer to the header or documentation to get it right. A simple three-line coding standard just boosted your memory capacity by over 643%.</p>
<p>(In the interest of full disclosure: I made that number up.)</p>
<p>I realize that implementing even this simple three line standard is controversial because all the camel case folks are pulling out big sticks and the underscore people are grabbing rocks. To which I say: just flip a coin and enjoy the extra brain power. Adopt a three-line standard, <strong>follow it</strong>, and save the curly-brace debate for the next major coding standard revision.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/who-else-wants-better-short-term-memory/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Version Control Habits of Effective Developers</title>
		<link>http://blog.bstpierre.org/version-control-habits</link>
		<comments>http://blog.bstpierre.org/version-control-habits#comments</comments>
		<pubDate>Wed, 07 Jan 2009 14:55:47 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[process]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[codereview]]></category>
		<category><![CDATA[continuousintegration]]></category>
		<category><![CDATA[tool]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=61</guid>
		<description><![CDATA[(Apologies to Stephen R Covey for the title&#8230;) Through some odd coincidence these posts crossed my path recently: Check In Early, Check In Often [comments here are especially good] Best Practices for Version Control 5 SVN Best Practices Continuous Integration is an Attitude, Not a Tool What I got to thinking about is that version [...]]]></description>
			<content:encoded><![CDATA[<p>(Apologies to <a href="http://www.google.com/url?sa=t&amp;source=web&amp;ct=res&amp;cd=3&amp;url=http%3A%2F%2Fwww.amazon.com%2FHabits-Highly-Effective-People%2Fdp%2F0671708635&amp;ei=qdJkSZn1A4is8gTF45XSCQ&amp;usg=AFQjCNHcwbWdJxdTwjTERnp8lQ0alziYVw&amp;sig2=CAkQYh3m2s0tkwADLCxGvQ">Stephen R Covey</a> for the title&#8230;)</p>
<p>Through some odd coincidence these posts crossed my path recently:</p>
<ul>
<li><a href="http://www.codinghorror.com/blog/archives/001165.html">Check In Early, Check In Often</a> [comments here are especially good]</li>
<li><a href="http://blog.looplabel.net/2008/07/28/best-practices-for-version-control/">Best Practices for Version Control</a></li>
<li><a href="http://www.iovene.com/5-svn-best-practices/">5 SVN Best Practices</a></li>
<li><a href="http://jamesshore.com/Blog/Continuous-Integration-is-an-Attitude.html">Continuous Integration is an Attitude, Not a Tool</a></li>
</ul>
<p>What I got to thinking about is that version control is one of the foundation tools in your development process. It enables many other processes and practices. The posts above make great points, but I&#8217;d like to put them in the context of the overall process. (I&#8217;ve also given some thought to the conflicting advice given, again in the context of the forest instead of the trees.)</p>
<ol>
<li><strong>Use version control!</strong> If you&#8217;re not doing this, you should get out of the profession now.</li>
<li><strong>Check in often.</strong> This is frequently given advice, but I feel it&#8217;s often given out of context. <a href="http://www.codinghorror.com/blog/archives/001165.html">Jeff Atwood</a> includes a quote from AccuRev founder <a href="http://damonpoole.blogspot.com/2005/07/check-in-early-and-check-in-often.html">Damon Poole</a>:<br />
<q>My rule of thumb is &#8220;check-in early and often&#8221;, but <em>with the caveat that you have access to private versioning</em>. If a check-in is immediately visible to other users, then you run the risk of introducing immature changes and/or breaking the build.</q><br />
(My emphasis.) &#8220;Private versioning&#8221; means a private branch: you can check in without affecting anyone else (see #8). But even with a private branch, consider <a href="http://www.iovene.com/5-svn-best-practices/">Salvatore Iovene</a>&#8216;s advice: &#8220;SVN is not a backup tool&#8221;. He makes the point that you shouldn&#8217;t check in before you go home just because it&#8217;s the end of the day. Instead check in when you have a logical unit of work (e.g. everything compiles, most of the tests pass but you have to make some experimental changes to finish the feature or perform debugging, etc.). The danger is that if you have to revert because you&#8217;ve made some disastrous changes, you won&#8217;t have a sane state to revert to. Final point: Salvatore also reminds us that some tools don&#8217;t commit to a central repository by default (git, darcs, etc), so checking in doesn&#8217;t replace a good backup.</li>
<li><strong>Put everything in version control.</strong> This is a key enabler for continuous integration (CI). <a href="http://jamesshore.com/Blog/Continuous-Integration-on-a-Dollar-a-Day.html">James Shore</a> has several great posts on CI. I think he under-emphasizes the need to check in everything necessary to build. First, it should be easy for a new hire to pull down a source tree and immediately get a good build. It makes life easier for them and for you. Second, your CI server should be able to do the same thing. If someone upgrades one of the tools locally and the build depends on this then the integration build should break. The tool upgrade must be checked in so that everyone picks up the change.</li>
<li><strong>Don&#8217;t break the build.</strong> [When I say "build" I mean "build and tests". It's unfortunate naming but I think this is the way the term is used by a lot of people.] This is a promise that the team has to make to each other: &#8220;I will not break the build.&#8221; What it means is that every team member agrees not to check in code to the trunk that does not build and pass all tests. If you have jerks on your team that constantly break the build, ask them to play by the rules, and if they can&#8217;t then get rid of them because they&#8217;re dragging you down.</li>
<li><strong>Check in bite sized chunks.</strong> Too big and you&#8217;ve probably been working too long: did you go dark? Large checkins are also harder to review well, so quality will suffer. If a given feature is large, create a branch and continue to check in bite sized chunks (see #6).</li>
<li><strong>Branch, but only when needed.</strong> If you don&#8217;t have bite sized chunks, or if more than one person needs to work on a feature that can&#8217;t go into the trunk, create a branch. When you have a branch, it is critical to update (or merge, or pull, whatever terminology you prefer) into the branch from the trunk on a regular basis. Integration will be a nightmare if you don&#8217;t. When the code on the branch is mature <em>enough</em>, merge (or push) it back to the trunk. (Tip: it doesn&#8217;t need to be perfect, it just shouldn&#8217;t introduce regressions into the trunk.) If more non-bite-sized work is needed on the feature, create a new branch and repeat the process.</li>
<li><strong>Check in when you&#8217;re ready.</strong> But not sooner or later. This should be obvious, but some people don&#8217;t seem to get it. If you check in before you&#8217;re ready, you break the build (and your promise to your team members). This can stop your entire team dead in their tracks! If you wait too long, you&#8217;ve lost the opportunity to get rapid feedback on your work. This practice enables continuous integration. It relies on having work broken down into bite sized chunks (see #5).</li>
<li><strong>Use private versioning.</strong> Private versioning means that each developer has his own branch (or even multiple branches). With a VC tool like AccuRev, this is automatic: every tree has an associated private stream (branch) on the server. With distributed VC tools like git, this is also automatic: everything is private until you push/pull to the central repository or another developer. It can be simulated with other tools but requires a bit more effort. This allows individual developers to maintain several versions of their work before they are ready to share with the rest of the team. It also allows a developer to keep a sane version of code before merging in changes from the trunk. (If the merge becomes a disaster, he can discard the merge results and go back to the sane version without much effort.)</li>
<li><strong>Update/merge/pull regularly.</strong> This also seems obvious, but again not everybody gets it. I mentioned it above as part of branching, and it&#8217;s especially important if you&#8217;re using private branches. You must merge from the trunk to your private branch/workspace/sandbox regularly. If you have private versioning, this is low risk because it&#8217;s easy to revert a bad merge. (These two practices create a self-reinforcing virtuous cycle!)</li>
<li><strong>Train your users.</strong> I&#8217;ve worked in shops where it seems like only half of the team understands anything beyond &#8220;checkout, update, checkin&#8221;. <em>Everyone</em> must know how to perform daily duties like checkout, checkin, update and merge from trunk, merge from private branch to trunk, how to navigate history, perform diffs, etc. Everyone should know how to perform less-frequently-needed duties like odd sorts of merges &#8211; cherry picking, etc, though this is maybe less important.</li>
<li><strong>Use a common project structure and naming convention.</strong> Thanks to <a href="http://blog.looplabel.net/2008/07/28/best-practices-for-version-control/">Anders Sandvig</a> for this bit of wisdom. I wouldn&#8217;t have thought to include it in VC best practices but it makes sense to list it here. A common project structure makes it easier to add every project into the CI server. For example, I&#8217;ve used the CI server to enforce the rule that every project must provide a $BUILDROOT/build script that runs the entire build. (The server also enforced placing tests in $BUILDROOT/tests, list of images to be published in $BUILDROOT/MANIFEST, etc.) This also makes it easier to move staff from one project to another.</li>
<li><strong>Enable checkin notifications</strong>. This is typically seen as an email from a post-commit-hook (or whatever your tool calls it). The checkin notification can also launch CI build. Ideally, the notification will tie each checkin back to whatever issue/defect/task/project tracker you&#8217;re using.</li>
<li><strong>Write good checkin comments.</strong> This makes notifications worthwhile. Remember that VC is a communication tool as much as a time machine! I&#8217;ve had several experiences where reading someone else&#8217;s checkin comment has spurred a discussion that either causes them to rework their bug fix or it has caused me to change course on something I&#8217;ve got in progress.</li>
<li><strong>Perform atomic checkins.</strong> &#8211; When it&#8217;s time to check in, don&#8217;t do ten different checkins for the ten different files you modified! They all belong together as a logical unit. This makes merging easier. It prevents the CI server from running multiple build and test cycles needlessly (and from reporting  spurious breakages because it picked up half a change). This makes history easier to understand when others look at comments. This is part of training, and is reinforced if you expect all developers to merge regularly. (On the theory that merging is easier when checkins are atomic.)</li>
<li>[Advanced practice.] <strong>Use a holding area.</strong> &#8211; Instead of checking in to trunk, developers check in to a holding branch (call it &#8220;pre-integration&#8221; or something similar). You perform code review and run integration tests on that branch. When review has approved the changes and the tests pass, promote (merge) the change from the holding area to trunk. The rest of the team pulls (merges) from the trunk, which is guaranteed safe. I&#8217;ve also seen the use of a two-level holding area where the first level is for review and the second level is integration test. This is the default if you use private branches (#8) and perform code reviews out of the private branch before integrating (#16).</li>
<li><strong>Perform reviews on checked-in code.</strong> This is so much better than manually gathering changes and emailing patches around. (Though tools like git have optimizations specifically for eamiling patches around.) This is easy if you&#8217;re using private branches since you can request a review before integrating. Some <a href="http://blog.bstpierre.org/code-review-tools">code review tools</a> enable this.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/version-control-habits/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Removing Defects From Django Apps</title>
		<link>http://blog.bstpierre.org/removing-defects-from-django-apps</link>
		<comments>http://blog.bstpierre.org/removing-defects-from-django-apps#comments</comments>
		<pubDate>Fri, 02 Jan 2009 14:29:00 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[process]]></category>
		<category><![CDATA[codereview]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=15</guid>
		<description><![CDATA[I&#8217;m working on a set of Django apps right now. Here are some of the things I&#8217;m doing to filter out defects as I work: Design Review I do a handwritten (paper) design. I like to design offline — I find that this forces me to do two things. First, to slow down and get [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on a set of Django apps right now. Here are some of the things I&#8217;m doing to filter out defects as I work:</p>
<h4>Design Review</h4>
<p>I do a handwritten (paper) design. I like to design offline — I find that this forces me to do two things. First, to slow down and get it right. Second, to stay at about the right level of abstraction instead of drilling down into too much detail. When I&#8217;m done the paper design, I review it against a checklist that I build from mistakes found in downstream phases. My design reviews catch about 70% of the mistakes I make while designing. I&#8217;d like that to be higher, but it is definitely worth taking the time to do it. This isn&#8217;t specific to Django or Python, I do this for all projects.</p>
<h4>Written Test Plan</h4>
<p>After design review is done, I write (on paper, informally) a unit test plan based on the design. This is only possible when the design is at a low enough level that you can know what the general flow of control looks like through each method. I aim for full branch coverage in my unit tests. This doesn&#8217;t mean it will be &#8220;fully tested&#8221;, but at least I&#8217;ll have exercised most of the code. I usually find (and fix) a couple of defects while writing the test plan. This is also something I do for all projects.</p>
<h4>Code Review</h4>
<p>After I&#8217;m done coding, and <em>before</em> I run any of the code, I print it out and review it offline. The following bash alias is helpful (prints 2-up):</p>
<pre># usage: py2pdf OUTPUTFILE INPUTFILE(s)
py2pdf ()
{
    out=$1;
    if [ -f $1 ]; then
        echo $1 exists, aborting;
    else
        shift;
        echo $*;
        a2ps -A fill -E -2 -C -o - $* | ps2pdf - &gt; $out;
    fi
}</pre>
<p>It&#8217;s controversial, but I like the advice from Watts Humphrey in the PSP: review code before compiling (or in this case, before running any unit tests since there isn&#8217;t really a compile phase). It forces me to be much more thorough looking for defects since I know that python hasn&#8217;t filtered anything out yet.</p>
<p>To review the code, I use my checklist which is built in the same way as the design review checklist. I also use the test plan, walking through the code with each test case to see if there are any defects that testing will expose. It&#8217;s better to fix these now instead of waiting for the unit test to find them. Two reasons: First, it&#8217;s faster because you can see what the problem is. Second, you may notice something that the unit test won&#8217;t catch for whatever reason — maybe you don&#8217;t end up including the right data pattern to catch the defect. Code review is a generic defect removal practice.</p>
<h4>Unit Test &#8211; XHTML Validation</h4>
<p>Again, this seems to be controversial though I don&#8217;t really understand why. Some people don&#8217;t think valid XHTML is worth much. I validate because I want to make sure that my generated content isn&#8217;t horribly broken, and — just like compiler warnings — you either validate cleanly or you don&#8217;t validate at all. As soon as you start ignoring &#8220;a couple of silly errors&#8221; everything goes downhill.</p>
<p>I wrote an <a href="http://bstpierre.org/Projects/HtmlValidatorMiddleware/">XHTML validator middleware</a> for Django but I haven&#8217;t yet used it on this project. Why not? Well, I <em>was</em> trying to use Dojo as a javascript library, and it&#8217;s not possible (or at least not easy) to write valid XHTML while using Dojo widgets. So I had to write some special code in my test harness to strip out all of the Dojo garbage and then validate the result.</p>
<p>I&#8217;m using <a href="http://jquery.com/">jQuery</a> now, I&#8217;m much happier, and I suspect I&#8217;ll be able to validate using the middleware on my next iteration. (Which involves ripping out the Dojo false starts.)</p>
<p>Validation is generic for any web project. The middleware is specific to Django.</p>
<h4>Unit Test &#8211; Test Plan</h4>
<p>I implement the written test plan using PyUnit, the <a href="http://docs.djangoproject.com/en/dev/topics/testing/">Django enhancements based on PyUnit</a>, and <a href="http://seleniumhq.org/">Selenium</a> for browser-based testing.</p>
<p>My test plan usually generates a lot of test cases (a recent app had over 100 test cases for about 800 lines of Python, 700 of Javascript, and 200 XHTML). So I like to keep them in separate files in a &#8220;tests&#8221; directory in each app. One trick that I use is to implement a <tt>suite()</tt> function in my <tt>APP/tests/__init__.py</tt>. The suite function globs &#8220;APP_tc_*.py&#8221; and sorts them by time stamp, most recent first. This way if a test is failing I can make sure that it runs first when I fix the problem and rerun the suite. The other part of the trick is to add an optional argument to the globbing/sorting function that limits the number of test cases returned. So when I need to rerun a test a few times to fix a tricky problem, I don&#8217;t have to wait for the entire suite to run to get the results of the test-under-development. This is all highly specific to Django development.</p>
<h4>Unit Test &#8211; Pylint</h4>
<p>This is still experimental for me. Pylint generates a lot of noise. Most of what it reports is legitimate, but about 90% are minor (i.e. not-user-impacting) defects. I&#8217;ve had to spend a fair amount of time tuning the report parameters to stifle the noise. The most time consuming part so far has been filtering out results from the test code. I&#8217;d like to figure out a way to make pylint skip the test files but there doesn&#8217;t seem to be a setting for this. On the bright side, it nagged me into making some of my test code more maintainable. Obviously pylint is specific to python, I use other lint-like tools for other projects when the signal-to-noise ratio is high enough.</p>
<h4>Unit Test &#8211; jslint</h4>
<p>I&#8217;m a javascript novice, so <a href="http://www.jslint.com/">jslint</a> has been helpful in ferreting out problems that I would not have caught through testing. As I let the feedback from the tool and testing form better design and coding habits/patterns, the signal-to-noise ratio may drop so that this is less effective.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/removing-defects-from-django-apps/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Productivity: It Comes from Software Design Rather than Software Tools</title>
		<link>http://blog.bstpierre.org/productivity-it-comes-from-software-design-rather-than-software-tools</link>
		<comments>http://blog.bstpierre.org/productivity-it-comes-from-software-design-rather-than-software-tools#comments</comments>
		<pubDate>Wed, 31 Dec 2008 16:51:00 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[engineering]]></category>
		<category><![CDATA[process]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=14</guid>
		<description><![CDATA[I just read Scott Bellware&#8217;s Productivity: It Comes from Software Design Rather than Software Tools. These bullet points — the core of his argument — are excellent (quoted here): Design quality is the most important factor influencing productivity in software development The things that obstruct quality degrade productivity The reductions in productivity over time that [...]]]></description>
			<content:encoded><![CDATA[<p>I just read Scott Bellware&#8217;s <a href="http://blog.scottbellware.com/2008/12/productivity-it-comes-from-software.html">Productivity: It Comes from Software Design Rather than Software Tools</a>.</p>
<p>These bullet points — the core of his argument — are excellent (quoted here):</p>
<blockquote>
<ul>
<li>Design quality is the most important factor influencing productivity in software development</li>
<li>The things that obstruct quality degrade productivity</li>
<li>The reductions in productivity over time that are typical to tool-driven software development are greater than what can be solved by tools</li>
<li>The application of tools to these problems exacerbates the quality problem, creating a vicious cycle that accelerates exponentially</li>
<li>Quality software design is the product of principles and practices, not tools</li>
<li>The typical degradation in a software&#8217;s quality over time isn&#8217;t due to the nature of software, it&#8217;s due to the nature of the approaches we choose to develop and operate software</li>
</ul>
</blockquote>
<p>Full disclosure here: I am working on a set of software tools, and a big part of my consulting for software teams is helping them install tools to support their improvement initiatives.</p>
<p>I agree with Scott that good design is the root of all that&#8217;s virtuous in software. I guess I also agree that tools are often a distraction, though I think he&#8217;s drawing a direct line where the root causes go deeper.</p>
<p>Maybe it&#8217;s my embedded background, and the fact that I&#8217;ve worked on teams that were woefully under-equipped in terms of tools. (Or execs were sold a bill of goods and we got stuck with the resulting boat anchors and paperweights.) I just don&#8217;t see an over-emphasis on tools, maybe this happens in IT more.</p>
<p>What I do see are many opportunities for improvement.</p>
<ul>
<li>Designs can be better communicated. If designs can be communicated better amongst the team, they can be reviewed better, which will kill bad designs before they get coded — and the feedback will help developers improve their future designs. A tool for formatting and transmission could help here. But such a tool would only be helpful to a team that already has processes in place for creating and reviewing the design.</li>
<li>Requirements can be managed better. Practices like Scrum seem helpful, but there are still challenges. Again, a tool can help here but only when the team has an understanding of how the tool fits into an existing process.</li>
<li>Existing processes and tools are overly slanted towards managing <span style="font-style: italic;">code</span>.<br />
<a href="http://blog.bstpierre.org/five-reasons-to-slow-down">By the time any requirement or design has been reduced to code, it&#8217;s way too late to fix it.</a> Start working on improving quality earlier in the cycle, the effort will pay off in a big way.</li>
</ul>
<p>Putting software tools in the hands of unskilled developers is like letting me go after wood with power tools: it&#8217;s an expensive way to make a lot of sawdust. Better to build skills with manual processes and then introduce tools when manual chores become tedious.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/productivity-it-comes-from-software-design-rather-than-software-tools/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The cost of (not) testing software</title>
		<link>http://blog.bstpierre.org/the-cost-of-not-testing-software</link>
		<comments>http://blog.bstpierre.org/the-cost-of-not-testing-software#comments</comments>
		<pubDate>Wed, 24 Dec 2008 13:31:00 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[process]]></category>
		<category><![CDATA[reviews]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=11</guid>
		<description><![CDATA[Great post on the cost of (not) testing software. The take-home lesson is &#8220;find defects early&#8221;. The main thing missing from the discussion is that there are better techniques for finding defects than testing. Like design and code reviews, and especially more attention to requirements. Catch defects as early as possible and reduce costs even [...]]]></description>
			<content:encoded><![CDATA[<p>Great post on <a href="http://jessenoller.com/2008/09/17/the-cost-of-not-testing-software/">the cost of (not) testing software</a>. The take-home lesson is &#8220;find defects early&#8221;.</p>
<p>The main thing missing from the discussion is that there are better techniques for finding defects than testing. Like design and code reviews, and especially more attention to requirements. Catch defects as early as possible and reduce costs even further.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/the-cost-of-not-testing-software/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Five Reasons to Slow Down</title>
		<link>http://blog.bstpierre.org/five-reasons-to-slow-down</link>
		<comments>http://blog.bstpierre.org/five-reasons-to-slow-down#comments</comments>
		<pubDate>Mon, 15 Dec 2008 18:22:00 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[process]]></category>
		<category><![CDATA[reviews]]></category>
		<category><![CDATA[timelog]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=9</guid>
		<description><![CDATA[Here are five reasons you should wait before moving on to the next phase of your software development process: Get the requirements right. It&#8217;s so often repeated that it&#8217;s almost a cliché to say that requirements errors will cost 10x or more to fix during coding or testing. But it&#8217;s true, so I can risk [...]]]></description>
			<content:encoded><![CDATA[<p>Here are five reasons you should wait before moving on to the next phase of your software development process:</p>
<ol>
<li><strong>Get the requirements right.</strong> It&#8217;s so often repeated that it&#8217;s almost a cliché to say that requirements errors will cost 10x or more to fix during coding or testing. But it&#8217;s true, so I can risk repeating it here. Spend a little more time getting the requirements right, and you&#8217;ll <em>get every second back, with interest</em> during the testing phase. The risk here is overanalysis, but if you tend to be the impatient type &#8212; jumping into design or coding with very thin requirements &#8212; then you&#8217;re unlikely to suffer paralysis.</li>
<li><strong>Get the design right.</strong> It doesn&#8217;t have to be an elaborate 500 page document. One of the best designs for a complex system that I&#8217;ve ever seen was a state machine described in a two-page document with a big matrix on the first page. Remember, a written design is a <em>communication tool</em>. Just like the rest of your software, it can be <a href="http://c2.com/xp/DoTheSimplestThingThatCouldPossiblyWork.html">the simplest thing that will work</a>. Marker on a whiteboard works, if your team decides that is an effective way to communicate. An extra hour spent preparing and reviewing the design will save at least two hours in testing. Really. I&#8217;ve seen too many designs that were rushed (and clearly broken upon review) because of an unexplainable urgent desire to get a document into review so that coding can begin. The state machine I just mentioned went through probably 20 man-hours of reviews in maybe three passes, and we must have found at least 50 defects in it. Those defects took a few seconds each to fix (some may have taken a few minutes), but if there had been code and tests based<br />
on this broken design it would have taken hours to fix some of them.</li>
<li><strong>Get the code right.</strong> I used an Extreme Programming mantra above (&#8220;the simplest thing that will work&#8221;), but I think XP overall often leads to bad practices &#8212; primarily an overemphasis on testing. I agree that automated regression tests are a valuable tool. However, it is important to recognize that testing has limits. It takes an immense effort to achieve full branch coverage, and even this can&#8217;t be considered &#8220;complete&#8221; testing. Testing must be used in conjunction with other tools: code review and static analysis are two such tools for removing defects from code. And before you&#8217;re at the point where code is ready for review or even the compiler, take the time to consult a reference when you&#8217;re unsure how to use an API. I don&#8217;t know how many bugs I&#8217;ve fixed (including some of my own!) that were a few lines down from a <tt>/*TBD: how is this supposed to work?*/</tt> comment. Instead of putting in that comment, take the time to figure out how it is supposed to work.</li>
<li><strong>Get the tests right.</strong> Ever waste time on a bogus bug report? Testers telling you a feature is broken when they&#8217;re just doing the wrong thing? It&#8217;s not their fault if you failed to communicate how the feature is supposed to work. In the same way your test team should be insisting on some written communication from you about the feature set, you should insist on some written communication from them about what they&#8217;re going to test. Again, this &#8220;test plan&#8221; doesn&#8217;t have to conform to an ISO/IEEE standard that requires it be 1200 pages long and six inches thick. Like with the design, a whiteboard works just fine. Whatever communication method you use, if it helps head off problems then it is working. If you&#8217;re finding too many problems late in the game, then maybe you need to have something a little more formal &#8212; try posting short documents to an internal wiki.</li>
<li><strong>Are you keeping score?</strong> A <em>little</em> bit of measurement can do great things for you. I <a href="http://blog.bstpierre.org/2008/12/ten-reasons-to-use-time-tracking-tool.html">track time</a>, lines of code, and defects. I was reviewing one of my designs this morning and this data helped me decide: (a) how many defects I should expect to find in my design and (b) how long it should take me to find those defects. All because I have historical data that tells me how many defects I find per hour of design review, and how many defects I make per hour while designing. I also know how much testing time this is likely to save&#8230; so I don&#8217;t feel any particular rush to start coding from a buggy design. I&#8217;d rather get the design right first.</li>
</ol>
<p>As I mentioned above, the risk to getting into the habit of waiting is that you spend too much time analyzing the current phase and don&#8217;t just get on with it. But if you start from good requirements, it should be obvious when you&#8217;re done with design and coding. And if you&#8217;re keeping score, you&#8217;ll know how much time to devote to reviews to keep them efficient.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/five-reasons-to-slow-down/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jason Cohen on QA vs.QC</title>
		<link>http://blog.bstpierre.org/jason-cohen-on-qa-vsqc</link>
		<comments>http://blog.bstpierre.org/jason-cohen-on-qa-vsqc#comments</comments>
		<pubDate>Tue, 09 Dec 2008 14:08:00 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[process]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=6</guid>
		<description><![CDATA[Jason Cohen of Smart Bear Software has a brilliant blog. His post on QA vs. QC is something I&#8217;ve talked about in the past. I love his example of the Pringles manufacturing line discarding off-color chips &#8212; it&#8217;s a concrete, understandable way to define the difference between QA and QC. Some of my best project [...]]]></description>
			<content:encoded><![CDATA[<p>Jason Cohen of Smart Bear Software has a brilliant blog. <a href="http://blog.asmartbear.com/blog/qa-vs-qc.html">His post on QA vs. QC</a> is something I&#8217;ve talked about in the past. I love his example of the Pringles manufacturing line discarding off-color chips &#8212; it&#8217;s a concrete, understandable way to define the difference between QA and QC.</p>
<p>Some of my best project experiences have been those that have involved the testers starting at the requirements phase. These guys have a different attitude and have asked some great questions that prevented us from going down dead-ends.</p>
<p>Great testers find and isolate really hairy bugs. Truly great testers not only find these bugs, but will often find a pattern of bugs and can, for example, point to the portion of the spec that the code failed to implement. They take a bigger picture view of the product and its environment and how to improve the quality by both preventing defects and figuring out how to detect defects during the test phase.</p>
<p>As Jason says, we should let these guys have a little more influence on the development process. For example, they should be insisting on design and code reviews, even if they don&#8217;t participate. Because when the development team is in solely in charge of the development process, these steps sometimes get skipped &#8212; because the job is a rush, or because the feature is small and doesn&#8217;t need to be reviewed. (Even though rush jobs are most in need of reviews, and small features always seem to take longer because they receive less care and attention.)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/jason-cohen-on-qa-vsqc/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Five Simple Ways to Kill More Bugs Today</title>
		<link>http://blog.bstpierre.org/five-simple-ways-to-kill-more-bugs-today</link>
		<comments>http://blog.bstpierre.org/five-simple-ways-to-kill-more-bugs-today#comments</comments>
		<pubDate>Fri, 21 Nov 2008 19:42:00 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[process]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=3</guid>
		<description><![CDATA[Here are some simple things you can do &#8211; today &#8211; to find and prevent bugs in your code. These take very little effort to implement and do not cost any money. (And typically don&#8217;t require management approval.) Turn on warnings. This is a no brainer. Your compiler can tell you when you&#8217;re doing things [...]]]></description>
			<content:encoded><![CDATA[<p>Here are some simple things you can do &#8211; <span style="font-weight: bold;">today</span> &#8211; to find and prevent bugs in your code. These take very little effort to implement and do not cost any money. (And typically don&#8217;t require management approval.)</p>
<ol>
<li>Turn on warnings.</li>
<p>This is a no brainer. Your compiler can tell you when you&#8217;re doing things that are dangerous. I&#8217;ve found countless bugs from compiler warnings. Sometimes the warnings are annoying because the compiler barks about legitimate code, but once you&#8217;re in the habit of coding to avoid warnings it really isn&#8217;t that bad. Plus it saves a lot of time in the long run.</p>
<li>Make warnings break the build.</li>
<p>After you&#8217;ve turned on warnings, eradicate them from your code, and then set up your build so that it fails if there are any compiler warnings. If you use GCC, this is as simple as adding <tt>-Werror </tt>to your compile flags. With other systems, you may have to parse the build output to search for warnings.</p>
<p>If you skip this step, warnings can creep back into the build unnoticed.</p>
<li>Review your code.</li>
<p>Before you even compile a change, manually review it. Spend some time looking at it. A thorough review takes more time than you might think. Five or ten minutes per line of code is not unreasonable. If you are using a defect tracking system, look through the history of defects you have made in the past to know what kind of defects you tend to create. Put these in your checklist. Review your code against the checklist. Then, for every function call that you&#8217;ve added or changed, look at the definition for that function and verify that you&#8217;re passing the right number and type of arguments.</p>
<p>I&#8217;ve worked on a few systems that are not consistent about using 0-based or 1-based arguments, even in the same module, so part of my checklist is to verify whether each argument is 0-based or 1-based. This part of the review has saved me from several embarrassing bugs.</p>
<li>Get a review buddy.</li>
<p>Connect with one or more of your peers to review each others&#8217; code. Keep it informal &#8211; you won&#8217;t need to get management approval. Promise yourselves that you will promptly turn around requests for review. Tell your reviewer what kinds of mistakes you tend to make, and what kind of mistakes you already found in your own review. Over time your review partner will learn what your weaknesses are and can look for those types of defects. You should also seek and provide feedback on these patterns of mistakes to prevent them in the future.</p>
<p>It may be worthwhile to make a couple of different review partners. Different people will have a different focus, find different defect types, and it allows you to spread out the load. It also exposes you to different thinking styles as you read more code from a variety of people. Lastly, if one of your review partners leaves the company, you will already have an existing partnership that you can rely on.</p>
<li>Track all of your defects.
<ul>
<li>Date</li>
<li>Where found (file, class, and/or function/method)</li>
<li>How found (self, compile, peer, test, qa, field)</li>
<li>&#8220;Type&#8221; &#8211; some brief description to define the type or category of defect</li>
</ul>
</li>
<p>You are probably already using a bug/issue tracker like Bugzilla or Jira. These are great for tracking issues found in QA or in the field. But they don&#8217;t really track <em>defects</em>. One issue in QA may be caused by several defects in the design or code, or one defect may cause several issues in the field. There is no 1:1 correlation.</p>
<p>These systems also miss all of the defects that you catch before your code gets to system test or released to the field. Set up a spreadsheet to track every defect you find in your self reviews, peer reviews, compile, and unit test. (You can track this in a notebook in a pinch, but sifting through the data is more tedious.) Keep track of:</p>
<p>Every couple of weeks, or once a month, generate a graph of the data. Look for files/classes/functions that generate a lot of defects, these may be candidates for rewrite since they are obviously hard to maintain. Look for defect categories that cause you problems. Brainstorm ten strategies to reduce your worst defect category. Implement the top one or two. Thank your review partner for finding so many defects. (Or, if one of your partners isn&#8217;t finding much, you may decide to send more &#8220;business&#8221; to one of your<br />
other reviewers.)</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/five-simple-ways-to-kill-more-bugs-today/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

