<?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; codereview</title>
	<atom:link href="http://blog.bstpierre.org/tag/codereview/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.bstpierre.org</link>
	<description>Software Development, version 3.0</description>
	<lastBuildDate>Wed, 26 May 2010 16:08:50 +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>One Simple Step for Avoiding Shallow Reviews</title>
		<link>http://blog.bstpierre.org/one-simple-step-for-avoiding-shallow-reviews</link>
		<comments>http://blog.bstpierre.org/one-simple-step-for-avoiding-shallow-reviews#comments</comments>
		<pubDate>Wed, 25 Nov 2009 13:55:55 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[reviews]]></category>
		<category><![CDATA[codereview]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[software-engineering]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=209</guid>
		<description><![CDATA[It's your job as a reviewer to find as many defects as possible. If you're not finding defects, you're wasting time.


Related posts:<ol><li><a href='http://blog.bstpierre.org/who-else-wants-better-short-term-memory' rel='bookmark' title='Permanent Link: Who Else Wants Better Short Term Memory?'>Who Else Wants Better Short Term Memory?</a> <small> In &#8220;Talent is Overrated&#8221;, Geoff...</small></li><li><a href='http://blog.bstpierre.org/3-easy-ways-to-stick-to-a-coding-standard' rel='bookmark' title='Permanent Link: 3 Easy Ways to Stick to a Coding Standard'>3 Easy Ways to Stick to a Coding Standard</a> <small> When you&#8217;re writing python, you...</small></li><li><a href='http://blog.bstpierre.org/must-have-tools-software-teams' rel='bookmark' title='Permanent Link: 9 &#8220;Must-Have&#8221; Tools for Software Teams'>9 &#8220;Must-Have&#8221; Tools for Software Teams</a> <small> The items below are useful...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve all been guilty of giving a shallow review: &#8220;Looks ok.&#8221;</p>
<p>Given typical defect densities, any non-trivial design or code is going to contain some errors. Even seemingly trivial maintenance fixes are likely to be defective.</p>
<p><strong>It&#8217;s your job as a reviewer to find as many of these defects as possible. </strong>If you&#8217;re not finding defects, you&#8217;re wasting your time on reviews.</p>
<p>That &#8220;one simple step&#8221;? Remind yourself that there are almost certainly defects in the work product you&#8217;re reviewing, and then find them. It&#8217;s all about attitude.</p>


<p>Related posts:<ol><li><a href='http://blog.bstpierre.org/who-else-wants-better-short-term-memory' rel='bookmark' title='Permanent Link: Who Else Wants Better Short Term Memory?'>Who Else Wants Better Short Term Memory?</a> <small> In &#8220;Talent is Overrated&#8221;, Geoff...</small></li><li><a href='http://blog.bstpierre.org/3-easy-ways-to-stick-to-a-coding-standard' rel='bookmark' title='Permanent Link: 3 Easy Ways to Stick to a Coding Standard'>3 Easy Ways to Stick to a Coding Standard</a> <small> When you&#8217;re writing python, you...</small></li><li><a href='http://blog.bstpierre.org/must-have-tools-software-teams' rel='bookmark' title='Permanent Link: 9 &#8220;Must-Have&#8221; Tools for Software Teams'>9 &#8220;Must-Have&#8221; Tools for Software Teams</a> <small> The items below are useful...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/one-simple-step-for-avoiding-shallow-reviews/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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 have [...]


Related posts:<ol><li><a href='http://blog.bstpierre.org/3-easy-ways-to-stick-to-a-coding-standard' rel='bookmark' title='Permanent Link: 3 Easy Ways to Stick to a Coding Standard'>3 Easy Ways to Stick to a Coding Standard</a> <small> When you&#8217;re writing python, you...</small></li><li><a href='http://blog.bstpierre.org/one-simple-step-for-avoiding-shallow-reviews' rel='bookmark' title='Permanent Link: One Simple Step for Avoiding Shallow Reviews'>One Simple Step for Avoiding Shallow Reviews</a> <small>It's your job as a reviewer...</small></li><li><a href='http://blog.bstpierre.org/open-an-ssh-tunnel-in-four-seconds-or-less' rel='bookmark' title='Permanent Link: Open an SSH Tunnel in Four Seconds or Less'>Open an SSH Tunnel in Four Seconds or Less</a> <small>As I mentioned in a previous...</small></li></ol>]]></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>


<p>Related posts:<ol><li><a href='http://blog.bstpierre.org/3-easy-ways-to-stick-to-a-coding-standard' rel='bookmark' title='Permanent Link: 3 Easy Ways to Stick to a Coding Standard'>3 Easy Ways to Stick to a Coding Standard</a> <small> When you&#8217;re writing python, you...</small></li><li><a href='http://blog.bstpierre.org/one-simple-step-for-avoiding-shallow-reviews' rel='bookmark' title='Permanent Link: One Simple Step for Avoiding Shallow Reviews'>One Simple Step for Avoiding Shallow Reviews</a> <small>It's your job as a reviewer...</small></li><li><a href='http://blog.bstpierre.org/open-an-ssh-tunnel-in-four-seconds-or-less' rel='bookmark' title='Permanent Link: Open an SSH Tunnel in Four Seconds or Less'>Open an SSH Tunnel in Four Seconds or Less</a> <small>As I mentioned in a previous...</small></li></ol></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>3 Easy Ways to Stick to a Coding Standard</title>
		<link>http://blog.bstpierre.org/3-easy-ways-to-stick-to-a-coding-standard</link>
		<comments>http://blog.bstpierre.org/3-easy-ways-to-stick-to-a-coding-standard#comments</comments>
		<pubDate>Tue, 25 Aug 2009 18:40:58 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[codereview]]></category>
		<category><![CDATA[software-engineering]]></category>
		<category><![CDATA[tool]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=192</guid>
		<description><![CDATA[When you&#8217;re writing python, you don&#8217;t need a lot of debate over the minutiae of most coding standards. PEP 8 does that for you. Even better, there are some tools that make it really easy to stick to the standard.
Why do this? Well, for one thing it makes code reviews easier when everyone follows the [...]


Related posts:<ol><li><a href='http://blog.bstpierre.org/who-else-wants-better-short-term-memory' rel='bookmark' title='Permanent Link: Who Else Wants Better Short Term Memory?'>Who Else Wants Better Short Term Memory?</a> <small> In &#8220;Talent is Overrated&#8221;, Geoff...</small></li><li><a href='http://blog.bstpierre.org/using-pythons-ctypes-to-make-system-calls' rel='bookmark' title='Permanent Link: Using Python&#8217;s ctypes to Call Into C Libraries'>Using Python&#8217;s ctypes to Call Into C Libraries</a> <small>The ctypes module makes loading and...</small></li><li><a href='http://blog.bstpierre.org/data-vs-code' rel='bookmark' title='Permanent Link: Data vs Code'>Data vs Code</a> <small> I&#8217;ll take an array over...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>When you&#8217;re writing python, you don&#8217;t need a lot of debate over the minutiae of most coding standards. <a href="http://www.python.org/dev/peps/pep-0008/">PEP 8</a> does that for you. Even better, there are some tools that make it really easy to stick to the standard.</p>
<p>Why do this? Well, for one thing it makes code reviews easier when everyone follows the same conventions. It also makes maintenance easier.</p>
<ol>
<li><a href="http://github.com/cburroughs/pep8.py/tree/master">pep8.py</a> is a style checker that enforces the rules of PEP 8. The &#8220;official home&#8221; (?) <a href="http://svn.browsershots.org/trunk/devtools/pep8/pep8.py">at browsershots.org </a>was dead as I was writing this. (Thanks GitHub!) Run pep8.py on your code and it will tell you where you&#8217;ve drifted from the standard.</li>
<li><a href="http://www.logilab.org/857">pylint</a> is lint for python. It provides more functionality than pep8.py, but is not a strict superset. (pep8.py is pickier about whitespace issues.) Pylint is also configurable to enforce various naming rules. Like most lints, the SNR is pretty low, but you can turn off most of the noise and get a reasonable signal for the things you want to check.</li>
<li>Subversion (as well as most other tools) can be configured to run a script every time you check in code. Run one or both of the above tools in the pre-commit hook and bad code will be rejected. (I&#8217;d be wary of doing this with pylint unless you&#8217;ve got the categories of &#8220;noisy&#8221; warnings turned off.) I don&#8217;t have anything cookbook for this yet, but I&#8217;m working on it&#8230;</li>
</ol>


<p>Related posts:<ol><li><a href='http://blog.bstpierre.org/who-else-wants-better-short-term-memory' rel='bookmark' title='Permanent Link: Who Else Wants Better Short Term Memory?'>Who Else Wants Better Short Term Memory?</a> <small> In &#8220;Talent is Overrated&#8221;, Geoff...</small></li><li><a href='http://blog.bstpierre.org/using-pythons-ctypes-to-make-system-calls' rel='bookmark' title='Permanent Link: Using Python&#8217;s ctypes to Call Into C Libraries'>Using Python&#8217;s ctypes to Call Into C Libraries</a> <small>The ctypes module makes loading and...</small></li><li><a href='http://blog.bstpierre.org/data-vs-code' rel='bookmark' title='Permanent Link: Data vs Code'>Data vs Code</a> <small> I&#8217;ll take an array over...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/3-easy-ways-to-stick-to-a-coding-standard/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Five Things That Do Not Belong In A Review Checklist</title>
		<link>http://blog.bstpierre.org/five-things-that-do-not-belong-in-a-review-checklist</link>
		<comments>http://blog.bstpierre.org/five-things-that-do-not-belong-in-a-review-checklist#comments</comments>
		<pubDate>Tue, 27 Jan 2009 22:09:32 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[reviews]]></category>
		<category><![CDATA[codereview]]></category>
		<category><![CDATA[process]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=104</guid>
		<description><![CDATA[This is the second half of an article I posted about using a checklist to prevent security errors. There, I said that you have 15 checklist items max, and you shouldn&#8217;t waste any of those questions on silly things like &#8220;Does the code follow the coding standard?&#8221;.
Jason Cohen pointed to an article of his in [...]


Related posts:<ol><li><a href='http://blog.bstpierre.org/one-simple-step-for-avoiding-shallow-reviews' rel='bookmark' title='Permanent Link: One Simple Step for Avoiding Shallow Reviews'>One Simple Step for Avoiding Shallow Reviews</a> <small>It's your job as a reviewer...</small></li><li><a href='http://blog.bstpierre.org/who-else-wants-better-short-term-memory' rel='bookmark' title='Permanent Link: Who Else Wants Better Short Term Memory?'>Who Else Wants Better Short Term Memory?</a> <small> In &#8220;Talent is Overrated&#8221;, Geoff...</small></li><li><a href='http://blog.bstpierre.org/pid-file-race' rel='bookmark' title='Permanent Link: An Interesting pid File Race'>An Interesting pid File Race</a> <small> ISC&#8217;s dhcpd uses this code...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>This is the second half of an article I posted about <a href="http://blog.bstpierre.org/how-to-use-a-checklist-to-prevent-security-errors">using a checklist to prevent security errors</a>. There, I said that you have 15 checklist items max, and you shouldn&#8217;t waste any of those questions on silly things like &#8220;Does the code follow the coding standard?&#8221;.</p>
<p><a href="http://blog.asmartbear.com/">Jason Cohen</a> pointed to an <a href="http://embedded.com/columns/guest/208803162">article of his</a> in which he said <strong>&#8220;List no items that can be automated.&#8221;</strong> (His emphasis, but I second the motion.)</p>
<p>In the context of the SANS paper, let&#8217;s look at five items that should be automated so that no human has to find the defects:
<ol>
<li><a href="http://cwe.mitre.org/data/definitions/665.html">CWE-665</a>: Improper Initialization. As the write-up for CWE-665 suggests, you could use a programming language that forces you to explicitly initialize all variables before use. Or, if you&#8217;re stuck with something like C, make sure you turn on the warnings in your compiler, or use a static analysis tool (e.g. lint) to verify that all variables are initialized before being used. Tools like Coverity can be very sophisticated in their static analysis.</li>
<li><a href="http://cwe.mitre.org/data/definitions/119.html">CWE-119</a>: Failure to Constrain Operations within the Bounds of a Memory Buffer. Same goes for this one. First, use a programming language that doesn&#8217;t require attention to every tiny little detail of string handling. Failing that, apply static analysis. It&#8217;s also worth performing runtime analysis (e.g. electric fence, Purify) with appropriate test cases to verify that you&#8217;ve avoided buffer overflows.</li>
<li><a href="http://cwe.mitre.org/data/definitions/404.html">CWE-404</a>: Improper Resource Shutdown or Release. Even garbage collected languages can have problems with resource release. First, some GC systems have problems with circular references. Second, GC systems are typically worried about releasing memory. You also have to worry about database handles, file handles, and sockets. Configure your static analysis tool to track resources like these so that you don&#8217;t have to do it manually.</li>
<li>The write-up for CWE-404 also mentions in passing that you should &#8220;wash your garbage before you dispose of it&#8221;. This is useful for two reasons: first, an attacker won&#8217;t have access to the contents of previously used memory, and second, it often makes debugging memory problems easier if you write a known value into freed memory. (I modified malloc() at my last job to write 0xcacacaca into freed memory so that we would know right away when someone stepped on a turd, um, I mean used freed memory.) Configure your libraries to shred objects before you free them and you won&#8217;t have to worry about it on a line-by-line basis in the code you review.</li>
<li><a href="http://cwe.mitre.org/data/definitions/362.html">CWE-362</a>: Race Condition. I&#8217;m typically worried less about security than the nightmare of isolating and debugging race conditions. I haven&#8217;t seen any tools that detect race conditions well, but Coverity does a decent job of telling you when you&#8217;ve mishandled a race condition in a couple of cases: first, it warns you when you fail to release a lock, and second, it warns you when you access a resource that is statistically accessed from within a lock. So you still have to beware of race conditions (at the design level is the bset place to find these), but there is an option for finding tedious errors in the mechanics of dealing with races.</li>
</ol>
<p>And now I&#8217;m going to throw out everything above.&nbsp; Remember that the tools are built to detect common errors. If it is really important that you find a certain class of bug, put it on your checklist. In fact, if it&#8217;s super critical, make it a checklist of length one. For example, I&#8217;ve gone over codebases with the single-minded focus of finding race conditions. When you perform a review like this, it&#8217;s amazing how many defects you might find in areas that you never suspected.</p>


<p>Related posts:<ol><li><a href='http://blog.bstpierre.org/one-simple-step-for-avoiding-shallow-reviews' rel='bookmark' title='Permanent Link: One Simple Step for Avoiding Shallow Reviews'>One Simple Step for Avoiding Shallow Reviews</a> <small>It's your job as a reviewer...</small></li><li><a href='http://blog.bstpierre.org/who-else-wants-better-short-term-memory' rel='bookmark' title='Permanent Link: Who Else Wants Better Short Term Memory?'>Who Else Wants Better Short Term Memory?</a> <small> In &#8220;Talent is Overrated&#8221;, Geoff...</small></li><li><a href='http://blog.bstpierre.org/pid-file-race' rel='bookmark' title='Permanent Link: An Interesting pid File Race'>An Interesting pid File Race</a> <small> ISC&#8217;s dhcpd uses this code...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/five-things-that-do-not-belong-in-a-review-checklist/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To Use A Checklist to Prevent Security Errors</title>
		<link>http://blog.bstpierre.org/how-to-use-a-checklist-to-prevent-security-errors</link>
		<comments>http://blog.bstpierre.org/how-to-use-a-checklist-to-prevent-security-errors#comments</comments>
		<pubDate>Fri, 23 Jan 2009 17:23:10 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[reviews]]></category>
		<category><![CDATA[codereview]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=98</guid>
		<description><![CDATA[The 2009 CWE/SANS Top 25 Most Dangerous Programming Errors has been out for a while now. Maybe you&#8217;ve already eliminated all of these errors from your code. In case you haven&#8217;t, this post will help you develop a checklist that you can use to eliminate these errors starting at the architecture level and moving through [...]


Related posts:<ol><li><a href='http://blog.bstpierre.org/one-simple-step-for-avoiding-shallow-reviews' rel='bookmark' title='Permanent Link: One Simple Step for Avoiding Shallow Reviews'>One Simple Step for Avoiding Shallow Reviews</a> <small>It's your job as a reviewer...</small></li><li><a href='http://blog.bstpierre.org/must-have-tools-software-teams' rel='bookmark' title='Permanent Link: 9 &#8220;Must-Have&#8221; Tools for Software Teams'>9 &#8220;Must-Have&#8221; Tools for Software Teams</a> <small> The items below are useful...</small></li><li><a href='http://blog.bstpierre.org/using-pythons-ctypes-to-make-system-calls' rel='bookmark' title='Permanent Link: Using Python&#8217;s ctypes to Call Into C Libraries'>Using Python&#8217;s ctypes to Call Into C Libraries</a> <small>The ctypes module makes loading and...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>The <a title="2009 CWE/SANS Top 25 Most Dangerous Programming Errors" href="http://www.sans.org/top25errors/">2009 CWE/SANS Top 25 Most Dangerous Programming Errors</a> has been out for a while now. Maybe you&#8217;ve already eliminated all of these errors from your code. In case you haven&#8217;t, this post will help you develop a checklist that you can use to eliminate these errors starting at the architecture level and moving through design, code, and testing. Before we get to the security aspect, first let&#8217;s take a quick detour through the mechanics of a review checklist.</p>
<h3>Why A Review Checklist is Essential</h3>
<p>Most (all?) experts recommend the use of a checklist for performing design and code reviews. It&#8217;s more effective to ask a set of questions about the item being reviewed than to simply stare at a bunch of code looking for problems. The checklist focuses your attention on aspects that are most important.</p>
<p>If you want to perform a broader review, develop two or three checklists with different foci and give the lists to separate reviewers. The defect lists from each reviewer will have less overlap than if you gave everyone the same list.</p>
<h3>What Your Review Checklist Should Look Like</h3>
<p>The following advice is partly based on advice from <a href="http://www.amazon.com/Software-Inspection-Tom-Gilb/dp/0201631814/">&#8220;Software Inspection&#8221; by Gilb and Graham</a>. A good checklist is a list of questions. For practical purposes, I&#8217;m strongly in favor of a checklist that does not exceed one side of a printed page — at normal font size. For me this means a checklist of about 15 items, 20 as an absolute maximum. Remember, we&#8217;re <em>focusing</em>, which means looking harder for just a few types of items. If you&#8217;re using online checklists, I&#8217;d extend this to mean that it should fit on the screen without scrolling. Either way, I don&#8217;t think you should have more than 20 questions or so at the max. Fewer is probably better, more is too overwhelming.</p>
<p>Checklist items are yes/no questions. They should all be phrased such that a &#8220;no&#8221; answer means something is broken.</p>
<p>When reviewing, proceed through the entire item under review (the entire code listing or design) with each question. Don&#8217;t work linearly, this is a horrible way to review code. I prefer to review on paper, simply because I can make little notes and marks all over the paper as I go through it. For the first question, you might work mostly front-to-back. Then the second question might send you backwards through the code. After a couple of passes over the code you have some familiarity with it, so the third question might send you straight to a location that has potential problems.</p>
<h3>How To Choose Questions for the Review Checklist</h3>
<p>Since the whole point of the checklist (and reviews in general) is to find defects, the questions should focus on finding the highest value defects. Why waste valuable checklist real estate on a question like &#8220;Does the code conform to formatting conventions?&#8221; Duh. If your team has a formatting convention, and you look at a piece of code that doesn&#8217;t conform, it&#8217;s going to jump off the page and bite you in the nose. You don&#8217;t need a checklist question for this!</p>
<p>Back to the specific problem at hand: security errors. SANS has done a great job of sifting through tons of security errors and boiling them down to the top 25. We could probably develop a 100 question review checklist from their Top 25 list, but it would be too big to be usable. So let&#8217;s <em>focus</em> on the most important for our application.</p>
<p>For this exercise, our application is a blog like Wordpress but much simpler: no plugins, no comments, single author. This is not a hosted application like Blogger, so we are less concerned about vulnerabilities like cross-site scripting, SQL injection, and OS command injection. We do need to make sure that only the author is allowed to post, so let&#8217;s look at the &#8220;Porous Defenses&#8221; category.</p>
<ul>
<li>CWE-285: Improper Access Control (Authorization)</li>
<li>CWE-327: Use of a Broken or Risky Cryptographic Algorithm</li>
<li>CWE-259: Hard-Coded Password</li>
<li>CWE-732: Insecure Permission Assignment for Critical Resource</li>
<li>CWE-330: Use of Insufficiently Random Values</li>
<li>CWE-250: Execution with Unnecessary Privileges</li>
<li>CWE-602: Client-Side Enforcement of Server-Side Security</li>
</ul>
<p>The entry for CWE-285: Improper Access Control lists the following for prevention and mitigation:</p>
<blockquote><p>For web applications, make sure that the access control mechanism is enforced correctly at the server side on every page. Users should not be able to access any information that they are not authorized for by simply requesting direct access to that page. One way to do this is to ensure that all pages containing sensitive information are not cached, and that all such pages restrict access to requests that are accompanied by an active and authenticated session token associated with a user who has the required permissions to access that page.</p></blockquote>
<p>Here are some straightforward checklist questions we can extract from that description:</p>
<ol>
<li>Does every administrative page enforce access control on the server side?</li>
<li>Are unauthenticated (anonymous) users prevented from accessing administrative pages?</li>
<li>Is caching disabled for administrative pages?</li>
<li>Does every administrative page validate the session token properly?</li>
</ol>
<p>Now you can go walk through your design and/or code to verify that you can say &#8220;yes&#8221; to each of these questions.</p>
<p>If you found this post helpful, <a href="http://blog.bstpierre.org/feed/rss2">subscribe to The Daily Build</a> to get updates as they are posted. Thanks!</p>


<p>Related posts:<ol><li><a href='http://blog.bstpierre.org/one-simple-step-for-avoiding-shallow-reviews' rel='bookmark' title='Permanent Link: One Simple Step for Avoiding Shallow Reviews'>One Simple Step for Avoiding Shallow Reviews</a> <small>It's your job as a reviewer...</small></li><li><a href='http://blog.bstpierre.org/must-have-tools-software-teams' rel='bookmark' title='Permanent Link: 9 &#8220;Must-Have&#8221; Tools for Software Teams'>9 &#8220;Must-Have&#8221; Tools for Software Teams</a> <small> The items below are useful...</small></li><li><a href='http://blog.bstpierre.org/using-pythons-ctypes-to-make-system-calls' rel='bookmark' title='Permanent Link: Using Python&#8217;s ctypes to Call Into C Libraries'>Using Python&#8217;s ctypes to Call Into C Libraries</a> <small>The ctypes module makes loading and...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/how-to-use-a-checklist-to-prevent-security-errors/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 control is one of the foundation [...]


Related posts:<ol><li><a href='http://blog.bstpierre.org/3-easy-ways-to-stick-to-a-coding-standard' rel='bookmark' title='Permanent Link: 3 Easy Ways to Stick to a Coding Standard'>3 Easy Ways to Stick to a Coding Standard</a> <small> When you&#8217;re writing python, you...</small></li><li><a href='http://blog.bstpierre.org/insist-on-tests' rel='bookmark' title='Permanent Link: Insist on Automatic Tests'>Insist on Automatic Tests</a> <small> At some point your team...</small></li><li><a href='http://blog.bstpierre.org/must-have-tools-software-teams' rel='bookmark' title='Permanent Link: 9 &#8220;Must-Have&#8221; Tools for Software Teams'>9 &#8220;Must-Have&#8221; Tools for Software Teams</a> <small> The items below are useful...</small></li></ol>]]></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>&#8217;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>


<p>Related posts:<ol><li><a href='http://blog.bstpierre.org/3-easy-ways-to-stick-to-a-coding-standard' rel='bookmark' title='Permanent Link: 3 Easy Ways to Stick to a Coding Standard'>3 Easy Ways to Stick to a Coding Standard</a> <small> When you&#8217;re writing python, you...</small></li><li><a href='http://blog.bstpierre.org/insist-on-tests' rel='bookmark' title='Permanent Link: Insist on Automatic Tests'>Insist on Automatic Tests</a> <small> At some point your team...</small></li><li><a href='http://blog.bstpierre.org/must-have-tools-software-teams' rel='bookmark' title='Permanent Link: 9 &#8220;Must-Have&#8221; Tools for Software Teams'>9 &#8220;Must-Have&#8221; Tools for Software Teams</a> <small> The items below are useful...</small></li></ol></p>]]></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 it right. [...]


Related posts:<ol><li><a href='http://blog.bstpierre.org/one-simple-step-for-avoiding-shallow-reviews' rel='bookmark' title='Permanent Link: One Simple Step for Avoiding Shallow Reviews'>One Simple Step for Avoiding Shallow Reviews</a> <small>It's your job as a reviewer...</small></li><li><a href='http://blog.bstpierre.org/3-easy-ways-to-stick-to-a-coding-standard' rel='bookmark' title='Permanent Link: 3 Easy Ways to Stick to a Coding Standard'>3 Easy Ways to Stick to a Coding Standard</a> <small> When you&#8217;re writing python, you...</small></li><li><a href='http://blog.bstpierre.org/who-else-wants-better-short-term-memory' rel='bookmark' title='Permanent Link: Who Else Wants Better Short Term Memory?'>Who Else Wants Better Short Term Memory?</a> <small> In &#8220;Talent is Overrated&#8221;, Geoff...</small></li></ol>]]></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>


<p>Related posts:<ol><li><a href='http://blog.bstpierre.org/one-simple-step-for-avoiding-shallow-reviews' rel='bookmark' title='Permanent Link: One Simple Step for Avoiding Shallow Reviews'>One Simple Step for Avoiding Shallow Reviews</a> <small>It's your job as a reviewer...</small></li><li><a href='http://blog.bstpierre.org/3-easy-ways-to-stick-to-a-coding-standard' rel='bookmark' title='Permanent Link: 3 Easy Ways to Stick to a Coding Standard'>3 Easy Ways to Stick to a Coding Standard</a> <small> When you&#8217;re writing python, you...</small></li><li><a href='http://blog.bstpierre.org/who-else-wants-better-short-term-memory' rel='bookmark' title='Permanent Link: Who Else Wants Better Short Term Memory?'>Who Else Wants Better Short Term Memory?</a> <small> In &#8220;Talent is Overrated&#8221;, Geoff...</small></li></ol></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>Code Review Tools</title>
		<link>http://blog.bstpierre.org/code-review-tools</link>
		<comments>http://blog.bstpierre.org/code-review-tools#comments</comments>
		<pubDate>Wed, 31 Dec 2008 18:07:00 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[reviews]]></category>
		<category><![CDATA[codereview]]></category>
		<category><![CDATA[tool]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=13</guid>
		<description><![CDATA[Yesterday I posted twenty reasons to do code reviews, and I promised a list of code review tools. Here they are, in no particular order. I have not used all of them, so I can&#8217;t comment on their relative merits. If there are some I missed, please leave a comment and I&#8217;ll update this list.

Codestriker [...]


Related posts:<ol><li><a href='http://blog.bstpierre.org/must-have-tools-software-teams' rel='bookmark' title='Permanent Link: 9 &#8220;Must-Have&#8221; Tools for Software Teams'>9 &#8220;Must-Have&#8221; Tools for Software Teams</a> <small> The items below are useful...</small></li><li><a href='http://blog.bstpierre.org/data-vs-code' rel='bookmark' title='Permanent Link: Data vs Code'>Data vs Code</a> <small> I&#8217;ll take an array over...</small></li><li><a href='http://blog.bstpierre.org/if-the-comments-are-ugly-the-code-is-ugly' rel='bookmark' title='Permanent Link: If the comments are ugly, the code is ugly'>If the comments are ugly, the code is ugly</a> <small> If the comments are ugly,...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Yesterday I posted <a href="http://blog.bstpierre.org/twenty-reasons-to-do-code-reviews">twenty reasons to do code reviews</a>, and I promised a list of code review tools. Here they are, in no particular order. I have not used all of them, so I can&#8217;t comment on their relative merits. If there are some I missed, please leave a comment and I&#8217;ll update this list.</p>
<ul>
<li><a href="http://codestriker.sf.net/">Codestriker</a> Open source, web based, written in perl I think.</li>
<li><a href="http://smartbear.com/codecollab.php">Code Collaborator</a> Commercial.</li>
<li><a href="http://www.review-board.org/">Review Board</a> Open source, web based, appears to be python/Django.</li>
<li><a href="http://code.google.com/appengine/articles/rietveld.html">Rietveld</a> Open source from Google. Guido van Rossum&#8217;s 2nd pass at a code review tool. You get three guesses on the implementation language&#8230;</li>
<li><a href="http://www.atlassian.com/software/crucible/">Crucible</a> Commercial from Atlassian.</li>
</ul>
<p>Bottom line: don&#8217;t try to do this by hand, you&#8217;ll be wasting a bunch of time packaging patches and tracking defects when a tool can do it automagically for you.</p>


<p>Related posts:<ol><li><a href='http://blog.bstpierre.org/must-have-tools-software-teams' rel='bookmark' title='Permanent Link: 9 &#8220;Must-Have&#8221; Tools for Software Teams'>9 &#8220;Must-Have&#8221; Tools for Software Teams</a> <small> The items below are useful...</small></li><li><a href='http://blog.bstpierre.org/data-vs-code' rel='bookmark' title='Permanent Link: Data vs Code'>Data vs Code</a> <small> I&#8217;ll take an array over...</small></li><li><a href='http://blog.bstpierre.org/if-the-comments-are-ugly-the-code-is-ugly' rel='bookmark' title='Permanent Link: If the comments are ugly, the code is ugly'>If the comments are ugly, the code is ugly</a> <small> If the comments are ugly,...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/code-review-tools/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Twenty Reasons To Do Code Reviews</title>
		<link>http://blog.bstpierre.org/twenty-reasons-to-do-code-reviews</link>
		<comments>http://blog.bstpierre.org/twenty-reasons-to-do-code-reviews#comments</comments>
		<pubDate>Tue, 30 Dec 2008 18:06:00 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[reviews]]></category>
		<category><![CDATA[codereview]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=12</guid>
		<description><![CDATA[Update [2008-12-31]: I posted the list of code review tools as promised below.
I tweeted this article on Five Reasons to Do Code Reviews from CIO.com last week,and realized that there are much more than the five reasons they give. So I came up with 20 more over the rest of the day. This is a [...]


Related posts:<ol><li><a href='http://blog.bstpierre.org/one-simple-step-for-avoiding-shallow-reviews' rel='bookmark' title='Permanent Link: One Simple Step for Avoiding Shallow Reviews'>One Simple Step for Avoiding Shallow Reviews</a> <small>It's your job as a reviewer...</small></li><li><a href='http://blog.bstpierre.org/data-vs-code' rel='bookmark' title='Permanent Link: Data vs Code'>Data vs Code</a> <small> I&#8217;ll take an array over...</small></li><li><a href='http://blog.bstpierre.org/must-have-tools-software-teams' rel='bookmark' title='Permanent Link: 9 &#8220;Must-Have&#8221; Tools for Software Teams'>9 &#8220;Must-Have&#8221; Tools for Software Teams</a> <small> The items below are useful...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><span style="font-weight: bold;">Update [2008-12-31]: </span>I posted the list of <a href="/code-review-tools">code review tools</a> as promised below.</p>
<p>I <a href="http://twitter.com/bstpierre/status/1076228386">tweeted</a> <a href="http://www.cio.com/article/472377/_Reasons_for_Software_Developers_to_Do_Code_Reviews_Even_If_You_Think_They_re_a_Waste_of_Time_">this article on Five Reasons to Do Code Reviews</a> from CIO.com last week,and realized that there are much more than the five reasons they give. So I came up with 20 more over the rest of the day. This is a collection of those tweets, with a little more detail given here.</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076435522">Code review reason 1</a>: Feedback comes back fast enough to give you whiplash.</strong> Since code review is done after coding and before integration or system tests, developers don&#8217;t have to wait as long to get feedback on code quality. By providing specific, timely feedback, developers can adjust their coding practices to avoid common mistakes.</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076448295">Code review reason 2</a>: Find more bugs than testing alone.</strong> This is obvious: Testing finds bugs. Code review finds different bugs. When combined they find more bugs than you would otherwise remove before shipping to customers.</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076643709">Code review reason 3</a>: A million monkeys sometimes produce valid syntax, even if it doesn&#8217;t make any sense. Compilers can&#8217;t catch this. </strong>Sometimes you&#8217;ll make a syntax error that produces valid syntax so the compiler can&#8217;t catch it. The classic here is in C, = (assignment) versus == (boolean equality operator); in this case most compilers can issue a warning but there are other examples. A code review will catch this error quickly, but finding this during testing can be hard to track down.</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076645011">Code review reason 4</a>: Find and kill bugs where they live, instead of finding turds and having to track them back to the nest.</strong> When you get defect reports from a code review, you have in-hand the exact line number and problem description. When you get reports from system test or (horrors!) a customer, you get — at best — a reproducible set of steps to trigger the bug. It&#8217;s then up to you to work backwards to the actual defect in the code, which is often time consuming, especially since the code may have been written weeks or months earlier. (See reason #1.)</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076699581">Code review reason 5</a>: Indoctrinate the n00bs.</strong> Code reviews are an effective training tool. First, new software engineers who participate in code reviews get to look at code produced by other engineers and thus get a feel for the coding standard and documentation style. Second, inexperienced engineers will get feedback on their code before they have a chance to infect the system with inferior code. (Because we all know that the code we wrote 10 years ago probably sucks — unless we were fortunate enough to have it reviewed by more senior engineers. If you haven&#8217;t already been coding for several years, keep in mind that everything you&#8217;re writing today probably sucks but you won&#8217;t be able to acknowledge that for another few years; see reason #6.)</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076706526">Code review reason 6</a>: Uses developer egos to boost quality of code from the beginning.</strong> The theory here is that because developers know their code is going to be publicly scrutinized by a group of peers, they will take extra care in coding to avoid the embarrassment caused by having others find all kinds of bugs in their code.</p>
<p>Guest contributor <strong><a href="http://twitter.com/kyletolle">@kyletolle</a>: <a href="http://twitter.com/kyletolle/status/1076701951">Code review reason [7]</a>: Explaining code makes sure they understand it well. Will fix the &#8220;Uhh, b/c I always do it that way&#8221; remarks.</strong> After you have to answer this question a few times during a review, you&#8217;ll probably ask the question of yourself while coding. (See reason #6.)</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076724807">Code review reason 8</a>: Makes testing go faster. Heck, it makes the entire development cycle go faster.</strong> There are multiple root causes for this. First, since code review finds and fixes defects at the site of the defect (see reason #4), less time is spent fixing these defect. Second, fewer bugs are found by testers so they spend less time writing up issues and the engineering team spends less time tracking and managing issues. Third, testers don&#8217;t have to re-run regression tests so many times because fewer release candidates will be needed.. Last, it is less likely that testers will be blocked waiting for fixes to bugs.</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076737034">Code review reason 9</a>: Fewer angry phone calls means happier tech support staff.</strong> Proof: Fewer bugs in shipping code (see reason #2). Customers not disrupted by bugs as often. They don&#8217;t get angry as often. So when they call, it&#8217;s with songs of praise. QED. (Ok, maybe that singing part isn&#8217;t true, but you get the picture.) To prove this from another angle: if you&#8217;re spending less time fixing bugs, you can spend more time implementing features that customers are requesting.</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076763127">Code review reason 10</a>: (Anti-reason) You&#8217;ll pay more sales commissions because you&#8217;ll be selling more product&#8230;wait, that&#8217;s a good thing!</strong> When customers sing your praises because your product is so reliable, it&#8217;s easier both to sell to new customers and to sell more product to your existing customers. Sure, your sales commissions might go up, but I&#8217;ve never really heard anyone complain about this too loudly.</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076785579">Code review reason 11</a>: There are tools that reduce the annoyance factor of old school review processes.</strong> After I tweeted this, <a href="http://twitter.com/kyletolle/status/1076797657">@kyletolle </a>asked for some recommendations. I will follow up this post with several tools that I&#8217;ve found. Stay tuned. (Look at my timeline starting <a href="http://twitter.com/bstpierre/status/1076816304">here</a> for now).</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076899696">Code review reason 12</a>: There&#8217;s zero risk. Even not-super-effective reviews beat testing.</strong> If I spent a little time I could probably dig up some published research to back this up. But my personal data says my personal code reviews are about four times as effective as unit testing. So even if I perform a half-hearted review, I&#8217;m still going to be more effective than testing. (See reasons #2 and #4, also keep in mind reason #5 which doesn&#8217;t have an immediate measurable effect.) There might be data out there that says code reviews are a waste of time. Flying reindeer might also exist.</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076933029">Code review reason 13</a>: (Anti-reason) Testers bored from not finding as many bugs&#8230; Oh yeah! They could focus on stress/perf tests.</strong> This would be a good problem to have&#8230;</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076933691">Code review reason 14</a>: Reviewing code is good practice for reviewing code. You&#8217;ll get better.</strong> Your team&#8217;s review effectiveness will improve over time. This means that the long term risk of failure is even lower than the short term risk (see reason #12 for why the risk of failure is zero or very close to zero).</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076934530">Code review reason 15</a>: It&#8217;s a great way to build a really useful code review checklist.</strong> This is kind of stretching, a useful code review checklist doesn&#8217;t really matter to the customer. (I should probably come up with a couple of bonus reasons to account for the &#8220;artificial fillers&#8221;&#8230; Hey, I tweeted this during the 3pm slump before my afternoon cup of tea.)</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076975312">Code review reason 16</a>: Out on a speculative limb: better staff retention because developers spend less time fixing annoying bugs. </strong>I&#8217;m not sure about anyone else, but I&#8217;ve stayed at a job that was otherwise not-so-great because of the quality of the team I was on and the people around me. Being part of a well-oiled machine feels good. It&#8217;s motivating to go to work everyday knowing that you&#8217;re going to produce a high quality product and your coworkers are there to back you up.</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076978947">Code review reason 17</a>: Reduces schedule risk because product quality is higher as it enters downstream phases.</strong> Your testers won&#8217;t get blocked as much (see reason #8) and testing won&#8217;t drag out. Since you get feedback relatively early in the schedule (see reason #1) you have a good idea of how long testing will take.</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076979963">Code review reason 18</a>: Feedback (especially from peers) at the source level means you will stop making the same mistakes over and over. </strong>(See reason #6.) This also stems from the fact that each engineer will have data in-hand about the types of defects he makes and he can come up with ways to prevent this defect from happening to begin with. And this is really when the magic occurs: when you can start thinking about preventing entire classes of defects.</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076980274">Code review reason 19</a>: Improves the quality of documentation / comments as well as executable code.</strong> (See reason #7.) Developers will include better comments to avoid having to answer too many questions from reviewers. If reviewers are looking for inconsistencies between comments and code, this is extra motivation to make sure that code documentation is up to date. Lastly, I suspect that overly complex code will become scarce since this will be scrutinized and questioned more than simple code passages.</p>
<p><strong><a href="http://twitter.com/bstpierre/status/1076980819">Code review reason 20</a>: Customers won&#8217;t find as many bugs in their soup.</strong> This is maybe redundant to reason #9, but helping customers is why we exist, right? So I&#8217;ll allow this one to stand and — like I said above — I&#8217;ll work on a couple of bonus reasons to add to this list.</p>


<p>Related posts:<ol><li><a href='http://blog.bstpierre.org/one-simple-step-for-avoiding-shallow-reviews' rel='bookmark' title='Permanent Link: One Simple Step for Avoiding Shallow Reviews'>One Simple Step for Avoiding Shallow Reviews</a> <small>It's your job as a reviewer...</small></li><li><a href='http://blog.bstpierre.org/data-vs-code' rel='bookmark' title='Permanent Link: Data vs Code'>Data vs Code</a> <small> I&#8217;ll take an array over...</small></li><li><a href='http://blog.bstpierre.org/must-have-tools-software-teams' rel='bookmark' title='Permanent Link: 9 &#8220;Must-Have&#8221; Tools for Software Teams'>9 &#8220;Must-Have&#8221; Tools for Software Teams</a> <small> The items below are useful...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/twenty-reasons-to-do-code-reviews/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
