<?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>caines.ca/blog &#187; programming</title>
	<atom:link href="http://caines.ca/blog/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://caines.ca/blog</link>
	<description>Shell-Shocked Ramblings from the Trenches of Software Development</description>
	<lastBuildDate>Mon, 27 Feb 2012 21:07:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>The Sun is Setting on Rails-style MVC Frameworks</title>
		<link>http://caines.ca/blog/programming/the-sun-is-setting-on-rails-style-mvc-frameworks/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://caines.ca/blog/programming/the-sun-is-setting-on-rails-style-mvc-frameworks/#comments</comments>
		<pubDate>Tue, 21 Feb 2012 06:06:45 +0000</pubDate>
		<dc:creator>Gregg</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://caines.ca/blog/?p=318</guid>
		<description><![CDATA[Lately I've been thinking a lot about the impact of the move to a thick client architecture for web applications, and I'm becoming more and more certain that this means that Rails-style MVC frameworks on the server-side are going to end up being phased out in favour of leaner and meaner frameworks that better address [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I've been thinking a lot about the impact of the move to a thick client architecture for web applications, and I'm becoming more and more certain that this means that Rails-style MVC frameworks on the server-side are going to end up being phased out in favour of leaner and meaner frameworks that better address the new needs of thick-client architecture.</p>
<p>There are a few major reasons for this:</p>
<h4>The server is no place for view logic</h4>
<p>The devices available for running a web app are vastly different from when these web frameworks first sprung up.  The slide towards thicker / richer clients has been proceeding on pace with increases in processing power since the Web 2.0 days.  It's much <a href="http://c2.com/cgi/wiki?SingleResponsibilityPrinciple">simpler</a> to handle views and view logic in only one place, and that place is slowly moving away from the server side.  MVC has always been a strained pattern for a server-side, non-gui application and it is been a confusing and complicated trade-off to have the backend generating front-end logic.    Front-end frameworks like <a href="http://documentcloud.github.com/backbone/">backbone.js</a>, as well as advances in web technologies like <a href="https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history">HTML5's history.pushState</a> are now making server-free views a realistic quality of cutting-edge front-ends.   Rendering on the client-side also gives us the opportunity to create <a href="http://www.alistapart.com/articles/responsive-web-design/">responsive designs</a> based on device capability rather than having the server try to somehow figure out what the capabilities are without actually running on that device.</p>
<p>The kinks aren't all the way out yet, but I do think the trend is clear.</p>
<h4>Server-side Templating and .to_json are both underpowered and overpowered for the actual requirements of JSON APIs</h4>
<p>There's no need for templating on the serverside (or view helpers, or any view-related cruft) to generate simple JSON documents, but there are a tonne of problems left unsolved when we fail to see that generating a JSON API is more than just a serialization problem.</p>
<p>How should dates look?  (RFC3339 / ISO8601 of course!).  What should the JSON error document look like when you provide a 400 and want to tell the client why?  How should links to other resources in the API look?  How does a collection look?  How does pagination look?</p>
<p>These aren't just serialization concerns, and they have nothing to do with templating.</p>
<h4><a href="http://timelessrepo.com/haters-gonna-hateoas">HATEOAS</a> is not just an academic pursuit</h4>
<p>A thick client does not want to maintain a vast list of static strings representing all the crazy URLs that it will have to call in a non standard API.  As an API designer, you don't want them doing this anyway, because hard-coded URLs and URL structures make it a real pain for you to change your API.</p>
<p>The AtomPub protocol, if you ignore its XMLiness,  gets this right -- The thick client just knows the root URL (which serves up a simple service document) and is aware of a bunch of relationship types (the 'rel' attribute on 'link' and 'a' tags) that it can follow as necessary.  If a game client needs to access a list of players, it just goes to the root url, and follows the link with the rel property called 'players' (and probably remembers that link until the server says it has moved via 301 status code).  JSON has no concept of links or rel, but this is still easy to imagine and implement, and while it's a teeny bit of extra work up front, the standardization buys you the ability to start writing smarter HTTP/REST clients for your frontend that take care of much more for you automatically, so you can spend time on real business logic and actually do something more productive than fiddle with the javascript version of a routes.rb file.</p>
<p>(A really great API framework might generate some or all of these links on its own and automatically put them in the JSON documents.  It's pretty easy to imagine pagination links like next/back being generated automatically, or even links amoung resources in some cases, possibly based on some internally declared relationship.)</p>
<h4>Rails-style MVC frameworks have a horrible routing solution for RESTFul JSON APIs</h4>
<p>In a resource-oriented API, the router need not be concerned with the http methods that are or are not allowed for the resource.  That's the concern of the resource and the resource alone.  When the router tries to manage that, you get the unnecessary verbosity of a route for every method supported by the resource, and you get the app incorrectly throwing 404s instead of 405s when a method is not supported.  This probably means that 'controllers' need to go away in favor of 'resources', and routes can be vastly simplified, if not completely derived/inferred by the framework.  Because we keep thinking in this conventional MVC style though, we miss the possibility and potential of vastly more simple applications that actually do a lot more more for us.</p>
<h4>The Application Developer shouldn't have to Deal with these Details</h4>
<p>There's no  reason for us to all separately think about these problems and solve them in a million different ways every time we're confronted with them.  Aside from the years of wasted time this involves, we've also got a bunch of non-standard and sub-standard APIs to interact with, so all the client code needs to be custom as well and nothing is reusable.  This is why being RESTful is not just academic and this is why being concerned with the details is not pedantic.</p>
<p>As I said earlier, AtomPub gets a lot of this right.  A lighter-weight JSON equivalent would be a huge improvement to what people are doing today, because the conventions would mean that the framework can take care of most of these API details that we reimplement ad nauseum -- or worse, not at all.  It also means that frontends can start to abstract away more of the HTTP details as well.  This is <a href="http://documentcloud.github.com/backbone/#Sync">already starting to happen in the new frontend MVC frameworks</a> but in almost every case, the HTTP end of things still needs to be handled in a custom way for every API endpoint.  There is still way too much work left to the application developer, and we're silly to continue to do it over and over without coming up with a better abstraction.</p>
<p><a href="http://couchapp.org/page/what-is-couchapp">CouchApps</a> and <a href="https://github.com/basho/webmachine">WebMachine</a> are just starting to <em>touch</em> on this style of architecture.  Backend-as-a-service platforms like <a href="https://parse.com/">Parse</a> certainly understand how far this simple architecture can go, but ultimately there's a huge need for a framework that can create more complex RESTful APIs (in a language that's more general purpose and "blue collar" than Erlang).</p>
<p>Rails-style MVC frameworks are both too much, and not enough at the same time.  It really is time for a new framework to support this new architecture.</p>
]]></content:encoded>
			<wfw:commentRss>http://caines.ca/blog/programming/the-sun-is-setting-on-rails-style-mvc-frameworks/feed/</wfw:commentRss>
		<slash:comments>54</slash:comments>
		</item>
		<item>
		<title>Your Team Probably Doesn&#8217;t have the Same DVCS Requirements as Linus</title>
		<link>http://caines.ca/blog/programming/311/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://caines.ca/blog/programming/311/#comments</comments>
		<pubDate>Tue, 03 Jan 2012 16:51:41 +0000</pubDate>
		<dc:creator>Gregg</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://caines.ca/blog/?p=311</guid>
		<description><![CDATA[Version control branches come with costs.  I'm at the point now that I don't think it's possible to get away without spending a couple of days every month managing issues with version control and merging if you're using feature branches liberally as is common with DVCS (like git) users.  I've spent days myself [...]]]></description>
			<content:encoded><![CDATA[<p>Version control branches come with costs.  I'm at the point now that I don't think it's possible to get away without spending a couple of days every month managing issues with version control and merging if you're using feature branches liberally as is common with DVCS (like git) users.  I've spent days myself in the past months, so I felt compelled to write this because those were days I could've been actually doing something that adds value instead.</p>
<p>The purpose of branching is to delay integration of some code into the main code line (for various reasons).  There's a heavy cost that comes from this in that the less often you merge, the harder it is to merge.  I'm blown away by the effectiveness of automatic conflict resolution in git, but the bottom line is that if two developers are working in the same area of the codebase, <a href="http://martinfowler.com/bliki/SemanticConflict.html">semantic conflicts</a> will emerge that need the intervention of a human to resolve.  These can be complicated and tedious and involve multiple developers.  Yes, branching is easier with DVCS, but this actually exacerbates a fundamental merging problem that DVCS doesn't solve.</p>
<h4>"What if I keep my branches short-lived?"</h4>
<p>There are some <a href="http://dev-spout.blogspot.com/2011/07/feature-branches-are-not-evil-in-fact.html">better defenses for branching</a>, like "What if I keep my branches very short-lived?", and while it does mitigate most of the problems with merging, it also mitigates any advantage you think you might get from branching.  If you're only going to branch for a day, what's the point?</p>
<h4>"Then how can I pick and choose what gets added/released?"</h4>
<p>Merging early and often leads to simpler merges, but what about the case when you get partway through a feature and want to scrap it because you've come up with a better way?  There are a number of ways to mitigate this problem, but if your need to "unmerge" occurs more often than your need to merge, you've probably got larger organizational issues to deal with.  If those issues are purely technical, try more <a href="http://caines.ca/blog/programming/the-lost-art-of-prototyping/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed">prototyping</a> to uncover those issues earlier, and <a href="http://www.rallydev.com/engblog/2011/12/20/feature-toggles-branching-in-code/">feature-toggles</a> for better control over what gets released.  If those organizational issues are non-technical, like frequent changing requirements mid-feature-development then you simply need to get better (and probably smaller) <a href="http://www.agilemodeling.com/artifacts/userStory.htm#Introduction">user stories</a> before commencing.</p>
<h4>"What if I do daily merges from the mainline into my feature branch?"</h4>
<p>You'd think it shouldn't matter which way you merge if you merge often, but that's only fine if you're the only one branching.  As soon as someone else on the team comes along and starts up their own feature branch and follows your same best practice, the two of you are diverging from each other and creating merge-debt.</p>
<h4>Using a continuous integration server is NOT sufficient for actually practicing continuous integration.</h4>
<p>I've heard of some teams using a bot to auto-add all branches to the team's CI server, making sure that each branch gets put through the proper rigor of the CI server.  This is actually cargo-cult continuous integration though because those teams are not actually continually integrating at all.  Merging early and often is a prerequisite of continuous integration, by definition.  Instead, running multiple branches in CI supports maintaining those multiple distinct branches for even longer, so you're actually using the CI server to undermine the ideals of CI.  Even if you run a special build that tries to auto-merge all branches (yeah right!), but is not the mainline and is not intended for release, you lose the ability to regularly deliver work to some staging environment for manual regression testing.</p>
<h4>A small non-distributed team doesn't have the same problems as Linus</h4>
<p>If your team is in the same room and practices <a href="http://c2.com/cgi/wiki?CollectiveCodeOwnership">collective code ownership</a> (instead of having a central maintainer) you should just do in-person peer code reviews (or better yet, pair programming) instead of relying on pull requests.  It's wasteful to force every aspect of intra-team communication to go through the computers in the room.  I would even go so far as to say that if you're in the same room, you don't actually need a DVCS.</p>
<p>Most of the reasons behind feature branches seem to be a cure that's worse than the disease itself.  It's vastly simpler for us to commit to the mainline at all times, early and often, and deal with deactivating or removing particular pieces of code in other ways (like <a href="http://www.rallydev.com/engblog/2011/12/20/feature-toggles-branching-in-code/">feature-toggles</a>) as those problems arise (which does not in my experience tend to be very often compared to how often I am merging new stuff in that stays in).</p>
<p>I don't mean to be negative about DVCS either.  I actually use git exclusively now, I think github has been a huge boon to open source, and I love anything that makes Linus more effective at maintaining my favourite OS kernel.  It just really seems like feature-branches have never solved any real problem that I have, while they have caused a lot of pain.</p>
]]></content:encoded>
			<wfw:commentRss>http://caines.ca/blog/programming/311/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JSON is under-defined for REST</title>
		<link>http://caines.ca/blog/programming/json-is-under-defined-for-rest/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://caines.ca/blog/programming/json-is-under-defined-for-rest/#comments</comments>
		<pubDate>Sun, 25 Sep 2011 19:18:52 +0000</pubDate>
		<dc:creator>Gregg</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://caines.ca/blog/?p=304</guid>
		<description><![CDATA[I'm working on a toolkit that can hopefully remove some boilerplate from Rails apps that are trying to implement RESTful APIs (specifically in JSON right now), while simultaneously trying to write a production JSON-REST API.  As I start to dig into the details, it's clear to me that JSON is under-defined for the purposes of [...]]]></description>
			<content:encoded><![CDATA[<p>I'm working on a <a href="https://github.com/windsorapi/windsor">toolkit</a> that can hopefully remove some boilerplate from Rails apps that are trying to implement RESTful APIs (specifically in JSON right now), while simultaneously trying to write a production JSON-REST API.  As I start to dig into the details, it's clear to me that JSON is under-defined for the purposes of RESTful APIs.</p>
<p>Of course everyone wants to use JSON because of its simplicity, but that simplicity seems to be the cause of deficiencies in being truly RESTful.  I have to wonder how many other people are <em>really</em> trying to create RESTful JSON APIS when these deficiencies are largely unsolved, or solved only by ad-hoc means.</p>
<h3>Deficiency #1: JSON is not Hypermedia</h3>
<p>Nowhere in the <a href="http://www.ietf.org/rfc/rfc4627.txt">JSON spec</a> does it talk about how to represent relationships to other hypermedia documents with links.  Sure, we can add that, but we have to agree on how first, or we can't build generic clients.</p>
<p>Originally, I thought to go with a link format like this:</p>
<pre> { "self" : "/example", "next" : "/example?page2" }</pre>
<p>Pros:</p>
<ul>
<li>The names in the name-value pairs define the relationship ("rel" in XML link nodes).</li>
<li>It works nicely in a list.</li>
<li>It's very json-esque in that it's untyped, like all other values in json.</li>
</ul>
<p>Cons:</p>
<ul>
<li>It's very json-esque in that it's untyped.  This means that a client can't tell if it's a hyperlink or not without out-of-band knowledge.</li>
</ul>
<p>That con leads me to believe that this format is unsuitable for hypermedia.</p>
<p>The second idea I happened across was <a href="http://www.amundsen.com/blog/archives/1054">this one</a> :</p>
<pre>{"link" : { "href" : "/example", "rel" : "self"}}</pre>
<p>PROS:</p>
<ul>
<li>It clearly lets the client know that it's dealing with a link</li>
</ul>
<p>CONS:</p>
<ul>
<li>You can't have more than one of these at the same level of a hash because names are supposed to be unique.  Soooo... You end up having to wrap these in an array and name that array.  Wow, that's going to be unnecessarily painful to parse.</li>
</ul>
<p>The third idea I stumbled across and decided was right for me was the one described in the <a href="http://tools.ietf.org/html/draft-zyp-json-schema-03#section-6.1">json-schema draft </a>:</p>
<pre>   {
     "links": [
       {
         "rel": "self"
         "href": "{id}"
       },
       {
         "rel": "up"
         "href": "{upId}"
       },
       {
         "rel": "children"
         "href": "?upId={id}"
       }
     ]
   }</pre>
<p>PROs:</p>
<ul>
<li>Clearly indicates that we're dealing with hyperlinks</li>
<li>Allows you to list links with the flattest possible structure</li>
<li>Is in a draft for a real standard</li>
</ul>
<p>CONs:</p>
<ul>
<li>Your links must always be in a array.</li>
</ul>
<p>I can live with that con.</p>
<p><strong>EDIT (Jan 8th 2012):  I came up with a new way that I think is even better, which better takes clients into consideration.  Here it is:</strong></p>
<pre><strong>   {
     "links": {
       "self" : { "href": "{id}" },
       "up" : { "href": "{upId}" },
       "children" : { "href": "?upId={id}" }
     }
   }</strong></pre>
<p><strong>This way makes it easy for the client to pull out URLs (eg  doc.links.self.href ) instead of having to search an array, and basically has all the other pros listed in other examples by sacrificing some flatness and using the relationship as the key instead of as part of the link hash.</strong></p>
<h3>Deficiency #2:  JSON lacks meta features</h3>
<p>JSON hasn't got a standard way of specifying types (like links), or namespaces (for microformats, or embedding other JSON documents), and does anyone really use json schemas?  Those would be useful for specifying subsets of JSON that a client could be programmed to understand in advance... but there goes that simplicity of JSON.</p>
<p>Something makes me think that JSON will need to get vastly more complex if we're really going to use it as part of the semantic web and actually have intelligent automatons understand it.  The people that care about that are in the vast minority at the moment though, and I've actually got real work to do...</p>
]]></content:encoded>
			<wfw:commentRss>http://caines.ca/blog/programming/json-is-under-defined-for-rest/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Agile, the Good Parts</title>
		<link>http://caines.ca/blog/programming/agile-the-good-parts/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://caines.ca/blog/programming/agile-the-good-parts/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 07:38:05 +0000</pubDate>
		<dc:creator>Gregg</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://caines.ca/blog/?p=299</guid>
		<description><![CDATA[Let's just forget about story points, pigs, chickens, daily stand-ups, burndown charts, sprints and scrummasters for a second.  In my experience all of that weird jargon is really hurting Agile's adoption among the no-nonsense type of developer that doesn't have time for fluff and wants to know the real benefits of something before investing time in [...]]]></description>
			<content:encoded><![CDATA[<p><!-- p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Consolas} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Consolas; min-height: 14.0px} span.s1 {text-decoration: underline ; color: #063eef} -->Let's just forget about story points, pigs, chickens, daily stand-ups, burndown charts, sprints and scrummasters for a second.  In my experience all of that weird jargon is really hurting Agile's adoption among the no-nonsense type of developer that doesn't have time for fluff and wants to know the real benefits of something before investing time in learning about it (instead of a million other things they could be learning).</p>
<p>I've also seen that when anyone happens to cite a failed experience with Agile, the explanation from Agilists is invariably the cryptic "you weren't doing it right". This is a bit of an irritating response to anyone that's spent a significant amount of time following the ceremonies and speaking the lingo though.  Instead I'd like to submit that you have a much better chance of succeeding with Agile if you know the real reasons behind the madness.</p>
<p>There are a number of Agile values I've noticed in my years of practicing scrum and XP that I think stand on their own even if you're not doing Agile and just want to improve your development process in some small way.  I'm going to list them (and try to stay jargon-free) because I imagine that they would be useful individually, but they do have a sort of self-reinforcing quality to them where their effects will somehow be amplified if you use them together.  You should also feel free to break the rules where you feel they need to be broken, but I've very rarely found that to be necessary.  Usually when I've broken these rules, I've regretted it later, because what I thought was an exception didn't really end up being an exception.</p>
<h2>Create a team, not just a group of individuals.</h2>
<p>A project will move faster when it is being developed by a team that self-organizes around its goals rather than a group of individuals working separately.  Here are few rules of thumb to creating a team instead of just having a group of individuals:</p>
<ul>
<li>Don't assign tasks to individuals.  Let the team figure out who works on what, and let the team take responsibility for all tasks rather than individuals.   Everyone on the team needs to agree on what it means to be done and how, and everyone on the team needs to take responsibility for it.</li>
<li>Strive for cross-functional skillsets.   Let the team members teach each other so they can better help each other in the future rather than allowing one person to become the bottleneck for any particular kind of task.</li>
<li>Try not to change team size or membership very much.  A good team can be a fragile thing.</li>
<li>Throw out the notion of individual code ownership. The entire team owns the code.</li>
<li>Create more of a bullpen environment where the team members are all basically in the line of sight of one another and can just talk to one another about what they're working on.  This was tough, because it made us give up our individual offices, telecommuting, and deciding our own hours, but it was well worth it for the improvement to the quality of our work day.  Almost anytime a developer has to use some means of communication other than his voice to talk with a teammate, you have unnecessarily wasted time.</li>
<li>Put QA personnel on the team so that testing can be can be on-going and so the team can more easily take on QA and testing as a team-wide responsibility.</li>
<li>The whole team needs to agree on what kind of work is necessary for each task before it is to be considered "done".  (coding standards, documentation standards, how rigorously they test, etc, etc)</li>
</ul>
<p>The result of this was a highly capable team that could "swarm" to complete goals reliably and quickly.  We actually developed a sort of sports team mentality that made this way of working genuinely fun, and helped us push ourselves to be better all the time.  There are a lot of challenges to creating a great team that can inter-communicate openly and honestly, but it's an amazing thing to behold when it happens.</p>
<h2>Estimates need to come from developers.</h2>
<p>This is can be very hard for some organizations to swallow, but developers are the ones that are most qualified to do estimations, and as professionals, they should be working diligently to improve their estimation capability.  When a developer is responsible for estimation, that developer feels a sense of ownership about his work and will feel a vastly greater sense of responsibility to meet the estimate.  Developers that have never learned how to estimate will not be good at it at first, but there's no other way for them to get good at it than to have them do it.  There are a few major things that can vastly help estimation too:</p>
<ul>
<li>Always break work down into tiny chunks.  We generally broke work up into chunks that were less than 3 days of effort.  I've never seen a task that couldn't be broken down into subtasks that are this small or smaller, if the developers are so inclined.</li>
<li>The team should take a look at bad estimates in retrospect and figure out where they went wrong.</li>
<li>Recognize work that will be impossible to do due to lack of clarity from the business, or unmet dependencies and push to have those requirements met.</li>
<li>For highly speculative work, just commit to doing a proof-of-concept, or time-boxed research.</li>
<li>The more developers that are involved in the estimation process, the better.  You'll probably want to include QA/testers as well, because good ones have unique insights.</li>
</ul>
<h2>Context-switching should be avoided <em>mercilessly</em>.</h2>
<p>This means that each developer needs the discipline to make sure he only works on one task at a time, that the team works on as few tasks at one time, and that developers need sustained uninterruptable timeboxes where the priority of work is not allowed to change.</p>
<p>Most people (especially non-developers) have no idea how much of a huge time-suck that context switching is, and few realize how seldom it's actually worthwhile.  Also if the team is tackling as few tasks as possible at once, if any task can be finished by having more developers on it at once, then that's what the team should do rather than starting as many tasks as possible and working on them in parallel.  This might sound counter intuitive, but with the team ultra-focussed on as few tasks as possible at once, they can get the totality completed faster.</p>
<h2>Try to always improve.</h2>
<p>The team must commit to continually improving. At regular intervals, the team should look at how things are going and pick a few actionable things to make their work better/faster/easier.  You'd be surprised at the huge speed improvements that can come from this practice over time.  If the team has a shared calendar, set up a reoccurring meeting at a regular interval to have this meeting, and be laser-focussed on deciding what improvement you want to achieve and how exactly you'll try to achieve that.  We've always set aside 1 hour per week, but your mileage may vary.  Start every meeting by evaluating how successful the team was with the previous meeting's goals.</p>
<h2>If something is difficult or time-consuming, do it more often.</h2>
<p>This sounds crazy to the uninitiated but there are two reasons for this:</p>
<ol>
<li>Doing difficult things more often will drive out new creativity in making them less difficult.  Pro-tip: Automation is almost always the answer when the problem is testing (See <a href="http://www.agiledata.org/essays/tdd.html">TDD</a>, <a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development">BDD</a>, <a href="http://testobsessed.com/2008/12/08/acceptance-test-driven-development-atdd-an-overview/">ATDD</a>) or deployment.  (See <a href="http://continuousdelivery.com/">Continuous Delivery</a>)</li>
<li>Many types of tasks get more difficult the longer they are postponed and so are always easier if you do them more often instead of letting the risk of complexity pile up.  Integrating code into the main branch is one example  (See <a href="http://martinfowler.com/articles/continuousIntegration.html">Continuous Integration</a>).  Deploying is another (See <a href="http://continuousdelivery.com/">Continuous Delivery</a>).</li>
</ol>
<h2>Be merciless about achieving high quality</h2>
<p>Over the long haul, <a href="http://caines.ca/blog/testing/quality-control-is-the-constraint/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed">speed comes from quality</a>, so everyone on the team needs to make quality their job.  Everyone needs to test, and everyone needs to think about how to continually make testing easier without cutting corners.</p>
<ul>
<li>Have QA personnel on every team, and have them testing as the team works.</li>
<li>The whole team needs to agree on what level of quality is needed, and what quality metrics will be used to judge every check-in.</li>
<li>Perform a root-cause-analysis on each defect.  Try to figure out how to avoid that class of defect in the future.</li>
</ul>
<h2>Do everything in tiny increments.</h2>
<p>Tiny increments reduce the risk of compounding problems, and allow you to get feedback and correct your course more often.</p>
<ul>
<li>break-down your work into tiny tasks</li>
<li>plan just-in-time and just enough to do work.</li>
<li>test as you go, instead of in huge batches</li>
<li>merge code to the mainline early and often.</li>
<li>deploy early and often.</li>
<li>don't add anything to the system that you don't need until you need it (<a href="http://c2.com/xp/YouArentGonnaNeedIt.html">YAGNI</a>)</li>
</ul>
<h2>Get customer feedback early and often</h2>
<p>Get customer feedback early and often to converge on the best possible solution as fast as possible by constantly correcting course instead of blindly following some long-running plan or doing unnecessary work.  The customer's priorities and vision of the product <em>will</em> change as he sees results, so it's better to not find out about these changes after a lot of unnecessary work has been done.</p>
<ul>
<li>Do work in priority order as dictated by the customer.  This will allow them to see the aspects that they care about most as early as possible, and therefore help you converge on a unified vision of the product faster.</li>
<li>Work break-down is better done in vertical slices where the customer can get some amount of real value from each piece (or at least see some evidence of work) rather than having many non-user-facing tasks, where possible.  This allows for more potential for feedback.</li>
<li>The work shouldn't be considered done by anyone on the team until the customer, or a representative of the customer agrees that it's done.</li>
<li>Constantly improve estimation skills so that they are generally more reliable so the customer knows the cost of the work he has requested and can make realistic decisions based on that.</li>
</ul>
<p>Anyway, feel free to try what you want and throw out the rest!</p>
]]></content:encoded>
			<wfw:commentRss>http://caines.ca/blog/programming/agile-the-good-parts/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Are you writing code for a deadline or are you writing code for the future?</title>
		<link>http://caines.ca/blog/programming/are-you-writing-code-for-a-deadline-or-are-you-writing-code-for-the-future/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://caines.ca/blog/programming/are-you-writing-code-for-a-deadline-or-are-you-writing-code-for-the-future/#comments</comments>
		<pubDate>Sat, 10 Sep 2011 21:50:43 +0000</pubDate>
		<dc:creator>Gregg</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://caines.ca/blog/?p=296</guid>
		<description><![CDATA[One of my more perverse guilty pleasures in software development is deadlines.  Deadlines take the task of developing software, which is usually pretty complex, and add a another dimension to it, which sort of makes me feel like I'm in game-show mode.  I start to think about creative ways to cut corners, and I feel [...]]]></description>
			<content:encoded><![CDATA[<p><!-- p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px} -->One of my more perverse guilty pleasures in software development is deadlines.  Deadlines take the task of developing software, which is usually pretty complex, and add a another dimension to it, which sort of makes me feel like I'm in game-show mode.  I start to think about creative ways to cut corners, and I feel the rush of still being able to deliver against the odds.  If it's just me working on the project, I can let my <a href="http://en.wikipedia.org/wiki/Hero_Syndrome">hero syndrome</a> flex its muscles,  or if I'm on a team, it can feel a bit like a sport where you try to coordinate and deliver on the seemingly impossible.  It takes a different type of creativity to be able to figure out where to cut the corners so that everything still works, and I enjoy those new types of challenges as well as the rush that comes from conquering them.  I haven't actually done any hackathons yet, but I imagine I'd enjoy them.</p>
<p>Deadlines have a lot of real plusses:</p>
<ul>
<li>The business knows to expect *something* at that time that resembles the original request.  This makes the development process seem somewhat more reliable.</li>
<li>The programmer gets a sense of clarity about his task when "doneness" can be defined with just a date, and some resemblance to the sliding requirements.</li>
<li>The programmer gets a sense of urgency, and therefore feels motivated.</li>
<li>The programmer doesn't have to bother doing the hard work of learning to estimate properly, and doesn't have to feel personally responsible for poor estimates.</li>
</ul>
<p>I don't mean that with any kind of sarcasm either.  It may sound machiavellian to say things like "deadlines motivate programmers", but the fact of the matter is that they do (they're not the only way however -- I'll get to that later).  In fact, the programmer himself can be the biggest proponent of deadlines, if he has only worked in deadline-driven environments.  That type of programmer will in fact cling to deadlines, because for the aforementioned reasons (people really do want to feel motivated at work).  Without them, he ends up drifting through the day, and not knowing when to stop working on a given task.  He certainly has never learned to estimate properly, and is all-too-happy to never have to bother trying to push-back against management on unrealistic deadlines.</p>
<p>So there are real reasons why deadline-driven development is attractive to all people involved, and it should be no surprise that many software development shops just go from one deadline to the next in a fashion that can only be described as deadline-driven development.  There are certain realities that exist for these shops though, regardless of whether they're recognized:</p>
<ul>
<li>Most employees don't want to work beyond their agreed-upon 8 hrs very often.  A system that tries to run counter to this will have high employee turn-over, and therefore incur heavy employee on-boarding costs on a regular basis.</li>
<li><a href="http://c2.com/cgi/wiki?WardExplainsDebtMetaphor">Technical debt</a> will be incurred constantly.  This is a perilous practice that makes your development process slower over time until the team can no longer develop seemingly basic features in any sort of reasonable time.  It's dangerous because it's very hard to even notice that it is happening until it's too late.</li>
</ul>
<p>These results create a feedback loop that only serves to amplify the problem:  Employee turnover and on-boarding costs both increase as technical debt increases.  Developers that are new to the codebase tend to create more technical debt as well.  Because of this, the deadline-driven approach to software development can quickly spiral into dead-end codebases that are so mired in technical debt and complexity that no one wants to work on them, and they can't be given new features easily.</p>
<p>Obviously <a href="http://caines.ca/blog/testing/quality-control-is-the-constraint/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed">I always go on and on about quality</a> and how it's the limiting factor in being as fast as possible, but there are some necessary trade-offs sometimes when you're developing software in the business world.</p>
<p>For example, when I used to do freelance contract work, I would get a lot of contracts to create one-off microsites for companies that wanted to run online promotional contests.  These microsites would need to go live on a not-too-far-away date where they would run for a few weeks before being closed down and deleted.  I was still concerned about quality, because word-of-mouth is how I got contracts, but technical debt wasn't any concern at all; I knew the software would just be deleted after a month, and I could do manually tested copy/paste spaghetti code to my heart's content if it meant I'd be done faster. *</p>
<p>Also: If I was running a start-up, for instance, I would probably incur more technical debt than if I was working on software that was profitable and had hundreds of users.  It makes more sense in the start-up scenario, because in that scenario, everything is a prototype -- you're not sure if the idea itself is even worthwhile.  You don't need to fight technical debt to ensure a fast future, because you need to be fast NOW, and you might not even have a future.  (Don't get me wrong though… I'd still do a heck of a lot of TDD  and aim for high coverage so I don't have to repeatedly test things manually, but then again I've got a lot of experience with automated testing, and I can write tests quickly enough now that it's an obvious time-saving over manual testing.)</p>
<p>So there are certainly some times to willingly take on technical debt.  There's <a href="http://forums.construx.com/blogs/stevemcc/archive/2007/11/01/technical-debt-2.aspx">a great blog post by Steve McConnell</a> on this.</p>
<p>The cold hard facts of the matter though are that if a start-up ends up being successful while taking on technical debt, that technical debt <em>will</em> cost them over time, regardless of whether they realize it or not, or whether they decide to do something about it or not.   It should be obvious that on a long-lived codebase, a team is faster over-all when it minimizes technical debt at every step, rather than letting quality be the dimension that slides as a deadline approaches.  <strong>Deadline-driven development is basically a way of borrowing against the future speed of development to meet a certain date.</strong> It is tempting because it almost always works over the short-term, but over the long term all the codebases I've seen that are continually developed this way grind the team to a virtual halt at some point.</p>
<p><strong>The corollary to this is that over the long term, a team should theoretically be able to develop faster without deadlines.</strong> That will almost certainly seem like insanity to anyone that's only done deadline-driven development, but in my experience it's true; I've worked on such a team, and while it was extremely fast, it was also an easily sustainable pace where everyone was happy with the results.</p>
<p>What does it take to get there?</p>
<ul>
<li>Everyone needs to realize that deadlines almost always incur technical debt and that technical debt is a way of borrowing against future development speed.</li>
<li>Developers need to learn a new definition of done so that their work has a clear point of completion and so that it includes making sure technical debt is not accidentally incurred.</li>
<li>Developers need to learn how to estimate reliably against this new definition of done.</li>
<li>Developers need to find a new source of urgency to stay motivated.  (In reality though, meeting their own estimates is usually challenge enough!)</li>
<li>Everyone needs to acknowledge that estimates come from the developers.</li>
<li>Everyone needs to figure out how to keep management up to date on the real progress.</li>
<li>For the most part, management needs to be content with monitoring the speed of progress rather than trying to dictate it.</li>
</ul>
<p>I'm not trying to say these are easily attainable goals, but I do know that once you've attained them, the team moves very fast.  I basically liken deadline-driven development to a rolling wheel that often stops or goes in reverse briefly compared to a wheel in a more quality-driven approach that may move forward more slowly, but never stops or rolls backward.  In my experience the slower moving wheel that never rolls back has a faster net speed and is more reliable and manageable for the business.</p>
<p>* There's a flip-side to that story too though… After 4 or 5 of those microsites I started to see a pattern in the requirements and started to build up some higher-quality libraries I could use to implement a new site easily to the extent that a site that would take me 3 days would later take me 3 hours.).  You can be sure that I spent a lot of time making that library super <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself ">DRY</a> and well (unit) tested because that was code <em>that had a future</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://caines.ca/blog/programming/are-you-writing-code-for-a-deadline-or-are-you-writing-code-for-the-future/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deciding What Not to Test</title>
		<link>http://caines.ca/blog/programming/deciding-what-not-to-test/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://caines.ca/blog/programming/deciding-what-not-to-test/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 06:34:11 +0000</pubDate>
		<dc:creator>Gregg</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://caines.ca/blog/?p=286</guid>
		<description><![CDATA[Deciding What Not to Test
I see a lot of people finding their automated tests to be tedious and time-consuming to write and wondering what parts are okay to not test.   A QA manager once asked me a question along the same lines… "How much coverage do you really need?"  I basically answered "What percent [...]]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Deciding What Not to Test</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">I see a lot of people finding their automated tests to be tedious and time-consuming to write and wondering what parts are okay to not test.   A QA manager once asked me a question along the same lines… "How much coverage do you really need?"  I basically answered "What percent do you not care about verifying?"</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">There are arguments that go the other way:</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">"Some code is so trivial, that it need not be tested."  Sorry -- I just don't buy it.  One character off in a source file can bring an entire app to its knees.  Any developer that's been coding for any length of time knows this.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">"Some code is so low value, that it need not be tested."  Then why are you writing it?  Seriously… if it doesn't matter if it works or not, just delete it.  There's no company that wants you to spend time writing code that no one finds any value in.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">"There are diminishing returns as you approach complete coverage, and the effort to do so increases".  I don't buy this one either.  Many people buy into testing the happy paths through the code, but feel they can save time by not testing the error scenarios.  The truth of the matter though is that people are generally pretty lazy about error scenarios in their code, and there are tonnes of bugs that lie in there as a result.  I usually find the happy path scenarios are well thought out</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">and very few bugs occur there, but the really tricky bits lie in how the code behaves under exceptional and error scenarios.  That can get complicated, and getting it wrong is almost always the same as not handling errors at all.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">If you decide that you want to write tests for everything (instead of manually testing everything before each check in), you still have the problem that testing this extremely can be tedious and time-consuming.  The answer is not to test less, but to test smarter.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(1) Don't test the same thing twice.  If you've tested something to the best of your ability, consider that behaviour tested and don't retest those details in some other kind of test (like an integration test that uses it).  For example, in Rails it's common to find people testing that the built-in validators on their model work, when those validators have been tested to death by the rails core team.  Just test that the proper validators *exist* in your model, and consider that model testing</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">done.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(2) Be completely intolerant of boilerplate application code.  If you find yourself writing the same stuff over and over, even if it's not pure copy/paste, figure out a way to put that in a library, or a super class or some other form of abstraction.  Then test the hell out of that abstraction, so that every time you use it, you're using something that you don't need to test again.  If you can see repetitive patterns in your application code, even if it's not pure cut and paste, you will have unnecessary repetitive patterns in your test code as well.  Keeping your application code DRY is a great way to make sure your</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">test code is DRY as well.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(3) Be completely intolerant of repetitive test code.  Learn about how to build more powerful abstractions in your tests as well.  You can...</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">- build better matchers (like hamcrest in java or shoulda in ruby)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">- build more powerful assertions, and other helper methods that can be reused</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">- use a framework with more configurable 'contexts' than just the usual n-unit 'setup' function</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">- use more powerful libraries for setting up test data (like Ruby's FactoryGirl)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">- use the most powerful mocking/stubbing framework you can find for your platform</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Test code needs to be DRY too, or it will get painful very quickly.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(4) Mock only when you need to.  Some people have a tendency to try to mock everything a class uses, but that takes a lot of time, and it makes the tests more fragile.  You also introduce the possibility that the mock doesn't properly mimic the dependency it's supposed to, practically guaranteeing false-positive tests.  You have two other choices:</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">- stubs.  Just as good as a mock for faking out a tough dependency, but it usually takes less setup and it won't whine about how many times you call it.  Because of that, tests that use stubs are generally less brittle than tests that use mocks when application code changes happen.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">- no fake at all.  There's huge value in testing your units together, and as long as it's still very fast and you can isolate defects quickly when a test fails, you have the option of not faking anything at all.  You're often going to want to fake network connections, file i/o, and database access, but there usually isn't much need for faking anything else.</div>
<p>I see a lot of people finding their automated tests to be tedious and time-consuming to write and wondering what parts are okay to not test.   A QA manager once asked me a question along the same lines… "How much coverage do you really need?"  I basically answered "What percent do you not care about verifying?"</p>
<p>There are arguments that go the other way:</p>
<blockquote>
<div><strong>"Some code is so trivial, that it need not be tested."</strong></div>
</blockquote>
<p>Sorry -- I just don't buy it.  One character off in a source file can bring an entire app to its knees.  Any developer that's been coding for any length of time knows this.</p>
<blockquote>
<div><strong>"Some code is so low value, that it need not be tested."</strong></div>
</blockquote>
<p>Then why are you writing it?  Seriously… if it doesn't matter if it works or not, just delete it.  There's no company that wants you to spend time writing code that no one finds any value in.</p>
<blockquote>
<div><strong>"There are diminishing returns as you approach complete coverage, and the effort to do so increases"</strong>.</div>
</blockquote>
<p>I don't buy this one either.  Many people buy into testing the happy paths through the code, but feel they can save time by not testing the error scenarios.  The truth of the matter though is that people are generally pretty lazy about error scenarios in their application code, and there are tonnes of bugs that lie in there as a result.  I usually find the happy path scenarios are well thought out and very few bugs occur there, but the really tricky bits lie in how the code behaves under exceptional and error scenarios.  That can get complicated, and getting it wrong is almost always the same as not handling errors at all.</p>
<p>If you decide that you want to write tests for everything (instead of manually testing everything before each check in), you still have the problem that testing this extremely can be tedious and time-consuming.</p>
<h3><strong>The answer is not to test less, but to test smarter:</strong></h3>
<ol>
<li><strong>Don't test the same thing twice.</strong> If you've tested something to the best of your ability, consider that behaviour tested and don't retest those details in some other kind of test (like an integration test that uses it).  For example, in Rails it's common to find people testing that the built-in validators on their model work, when those validators have been tested to death by the rails core team.  Just test that the proper validators *exist* in your model, and consider that part of the model testing done.</li>
<li><strong>Be completely intolerant of boilerplate application code.</strong> If you find yourself writing the same stuff over and over, even if it's not pure copy/paste, figure out a way to put that in a library, or a super class or some other form of abstraction.  Then test the hell out of that abstraction, so that every time you use it, you're using something that you don't need to test again.  If you can see repetitive patterns in your application code, even if it's not pure cut and paste, you will have unnecessary repetitive patterns in your test code as well.  Keeping your application code DRY is a great way to make sure your test code is DRY as well.</li>
<li><strong>Be completely intolerant of repetitive test code.</strong> Learn about how to build more powerful abstractions in your tests as well.  You can...</li>
<div>
<ul>
<li>
<ul>
<li>build better matchers (like hamcrest in java or shoulda in ruby)</li>
<li>build more powerful assertions, and other helper methods that can be reused</li>
<li>use a framework with more configurable 'contexts' than just the usual n-unit 'setup' function</li>
<li>use more powerful libraries for setting up test data (like Ruby's FactoryGirl)</li>
<li>use the most powerful mocking/stubbing framework you can find for your platform</li>
</ul>
</li>
</ul>
</div>
<p style="padding-left: 30px; ">Test code needs to be DRY too, or it will get painful very quickly.</p>
<li><strong>Mock only when you need to.</strong> Some people have a tendency to try to mock everything a class uses, but that takes a lot of time, and it makes the tests more fragile.  You also introduce the possibility that the mock doesn't properly mimic the dependency it's supposed to, practically guaranteeing false-positive tests.  You have two other choices:</li>
</ol>
<div>
<ul>
<li>
<ul>
<li><strong>stubs.</strong> A stub is just as good as a mock for faking out a tough dependency, but it usually takes less setup and it won't whine about how many times you call it.  Because of that, tests that use stubs are generally less brittle than tests that use mocks when application code changes happen.</li>
<li><strong>no fake at all.</strong> There's huge value in testing your units together, and as long as it's still very fast and you can isolate defects quickly when a test fails, you have the option of not faking anything at all.  You're often going to want to fake network connections, file i/o, and database access, but there usually isn't much need for faking anything else.</li>
</ul>
</li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://caines.ca/blog/programming/deciding-what-not-to-test/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>10 Steps to Being a More Professional Programmer.</title>
		<link>http://caines.ca/blog/programming/10-steps-to-being-a-more-professional-programmer/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://caines.ca/blog/programming/10-steps-to-being-a-more-professional-programmer/#comments</comments>
		<pubDate>Mon, 05 Sep 2011 17:04:00 +0000</pubDate>
		<dc:creator>Gregg</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://caines.ca/blog/?p=282</guid>
		<description><![CDATA[
After having been a  freelance developer for about 9 years, I wouldn't recommend it to  anyone, but there were a few things I learned in that time that I try to  take to my subsequent jobs.


Learn what "done" means. When you say something's  done, it means no more time needs to [...]]]></description>
			<content:encoded><![CDATA[<div lang="x-western">
<p style="margin: 0px; font: 12px Helvetica;">After having been a  freelance developer for about 9 years, I wouldn't recommend it to  anyone, but there were a few things I learned in that time that I try to  take to my subsequent jobs.</p>
<p style="margin: 0px; font: 12px Helvetica; min-height: 14px;">
<ul>
<li><strong>Learn what "done" means.</strong> When you say something's  done, it means no more time needs to be spent on it in order for a  customer to use it.  People will expect that when you say "done" you're  using the same definition as the one in the English dictionary, and not  just the works-on-my-machine imaginary definition.</li>
<li><strong>Be able to justify your technological decisions.</strong> The business's primary  purpose is making money, NOT making software so even technological  decisions ultimately need to have financial justifications.  "Because  it's cool" can't be used to justify any technology decision, and  generally makes people stop listening to you.</li>
<li><strong>Make your work process visible, reliable, and honest.</strong> The business would  almost always prefer that you spend the necessary time to make your  process visible and reliable (reliable estimation, task breakdown, etc),  than complete sooner.  Don't be that developer that tries to avoid all reporting for a week in the name of saving time, because everyone knows you really just don't like reporting.</li>
<li><strong>Put effort into all areas of responsibility, not just programming.</strong> There are many concerns  that a developer must be responsible for other than programming  (requirements, specs, testing, deployment, maintenance).  Yes, testing  is a large part of the developer's job.  Yes, deployment is a large part  of the developer's job.</li>
<li><strong>Get over the fact that you have to plan and go to meetings.</strong> Working with a company requires more rigor, process and communication overhead than working by  yourself (meetings, planning, etc).  You should always strive for the  lightest possible process that works, but there is always process, even  when some would like to pretend that there isn't.  The general rule is that as the number of people increases, so will the number of meetings and the amount of planning that are necessary to coordinate them.</li>
<li><strong>Don't whine about someone else's code.</strong> Everyone already knows  that you think that that code that someone else wrote is garbage,  because nearly every developer says that about nearly every piece of  code he/she did not write.  If it's a real impediment, be  specific and constructive.  Offer real solutions other than jumping straight to "rewrite".    A call for a greenfield rewrite is almost always the knee-jerk reaction  of the lazy-minded.</li>
<li><strong>Don't say that something  can't be done when it can just to influence engineering or product  direction (even when it's really hard).</strong> You lose credibility for future  consultation quickly that way.</li>
<li><strong>Constantly improve your estimation skills.</strong> Spend the time to break your work down into small enough chunks that they can be reliably estimated.  In the process of working on those chunks, if you learn that your estimate is slipping, report up early and often.  Look back on your failed estimates and figure out what went wrong.  People will only believe  your "I can clone google in a weekend" estimates for so long before  they decide you don't know how to estimate.</li>
<li><strong>Don't go to your manager/client with problems unless you're bringing solutions as well (and preferably more than one).</strong> You were hired to be the problem solver.</li>
<li><strong>Keep an eye on your results because over the long haul, results are the only thing that matter.</strong> Even if every task you're on fails for some reason that you explain is out of your control, you'll likely be dismissed.  If the reasons really are out of your control, you should really leave first anyway.</li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://caines.ca/blog/programming/10-steps-to-being-a-more-professional-programmer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quality is the Constraint</title>
		<link>http://caines.ca/blog/testing/quality-control-is-the-constraint/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://caines.ca/blog/testing/quality-control-is-the-constraint/#comments</comments>
		<pubDate>Sun, 05 Dec 2010 18:15:43 +0000</pubDate>
		<dc:creator>Gregg</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://caines.ca/blog/?p=271</guid>
		<description><![CDATA[One fine day in the trenches, a junior engineer was tasked with optimizing a particular web service call that was way too slow (sometimes slower than 20 seconds!).  I had just figured out how to use a performance profiler for that particular platform, so I thought I'd offer to show him how to use it. [...]]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">One fine day in the trenches, a junior engineer was tasked with optimizing a particular web service call that was way too slow (sometimes slower than 20 seconds!).  I had just figured out how to use a performance profiler for that particular platform, so I thought I'd offer to show him how to use it.  His response was that he was on a tight deadline and didn't have time to learn to use the profiler, and that he was just going to tune the database calls to make them perform better.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Later in the year when the problem still wasn't solved, I had a chance to take it on myself.  The profiler showed me that this service call was itself making around 20 web service calls to a second system that could obviously add up to 20 seconds, if that other web service took 1 second for each of its responses (and the logs showed that sometimes it did).  It turned out that almost all of those web service calls were redundant and completely unnecessary.  Simply removing them (which took about 1 day of effort) shaved 19 seconds off this web service call's duration in production in some cases.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">The total execution time spent on database calls was 5 milliseconds.  A 50% improvement there would probably take a week's worth of effort, and really only get you 2 or 3 milliseconds of performance improvement.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">The moral of the story is that there's a pretty simple process for optimizing a system:</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(1) Identify and isolate the component that is tying up the most time in the system  (let's call it the bottleneck)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(2) Optimize that component to make it less wasteful</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(3) Repeat</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Skipping step 1 isn't a shortcut.  It's absolutely critical to know that you're optimizing the bottleneck, and not some other random component.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">This is pretty obvious stuff for most experienced developers of course.  And while they seem to know to apply this to the systems that they work on, it's more rare that they notice it outside of the code and see it in the process of software engineering in general.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">The software development /process/ is a system as well, made up of components.  Requirements come in at one end, and deliverables go out the other end.  As people who are involved in that process, we naturally want it to be more and more efficient.  We are constantly trying to figure out how to optimize that system so we can deliver better software in less time.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">So step 1:  Identify and isolate the component that is tying up the most time in the system.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Not every team develops software the same way, so this component of the process *could* be different team by team.  In practice though, I've always seen teams spending the most time doing these sorts of things:</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">* Refactoring poorly written code so that features can be added</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">* Learning/relearning existing code that has long since swapped out of all developers' "mind pages" (for extension or bug-squashing).</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">* Debugging</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">* Performing Manual User Acceptance Testing (by both developers and testers)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">* issue tracking (administration of that tool and issue in it)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">* discovery and documentation of steps to reproduce</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">* triage (what bugs to squash first?)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">* communication between customers, support, QA and developers</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">* customer support</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">* customer dissatisfaction leading to churn and reputation problems (affecting the entire organization)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">All of these time consumers are affected directly or indirectly by our ability to control quality.  In my experience, the majority of the software development process isn't hung up in requirements analyis, design, or implementation.  It's hung up in all these Quality Control related issues.  Quality Control is the constraint that keeps us from creating the right software faster.  Steve McConnell confirms it in a more scientific way than I ever could:</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">The rest of us would do well to learn from a discovery made by IBM in the 1970s: Products with the lowest defect counts also have the shortest schedules (Jones 1991). Many organizations currently develop software with defect levels that give them longer schedules than necessary. After surveying about 4000 software projects, Capers Jones reported that poor quality was one of the most common reasons for schedule overruns (1994). He also reported that poor quality is implicated in close to half of all canceled projects. A Software Engineering Institute survey found that more than 60 percent of organizations assessed suffered from inadequate quality assurance (Kitson and Masters 1993). On the curve in Figure 1, those organizations are to the left of the 95-percent-removal line.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(http://www.stevemcconnell.com/articles/art04.htm -- The whole article is extremely illuminating)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">What this means is that if we want to move quickly, we need to take a good hard look at how we manage quality.  Of course this is counter-intuitive, and its actually hard to swallow, because ensuring quality can be mundane and tedious if you're not doing it right.  But as developers we'd be silly to ignore the real bottleneck in the process, and optimizing for that.  Micro-optimizations elsewhere in the process will yield very little benefit compared to improving measures that ensure quality.  As developers, we love to argue about and discuss these micro-optimizations all day long:</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">* what text editor you use ( http://en.wikipedia.org/wiki/Editor_war )</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">* how important input speed is (http://steve-yegge.blogspot.com/2008/09/programmings-dirtiest-little-secret.html and http://imprompt.us/2009/code-fast/ ).</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">* IDEs vs. editors ( http://stackoverflow.com/questions/136056/ide-or-text-editor)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">It sure seems silly though to be pursuing micro-optimizations, at the expense of tackling the real #1 time-suck:  Quality.</div>
<p>One fine day in the trenches, a junior engineer was tasked with optimizing a particular web service call that was way too slow (sometimes slower than 20 seconds!).  I had just figured out how to use a performance profiler for that particular platform, so I thought I'd offer to show him how to use it.  His response was that he was on a tight deadline and didn't have time to learn to use the profiler, and that he was just going to tune the database calls to make them perform better.</p>
<p>Later in the year when the problem still wasn't solved, I had a chance to take it on myself.  The profiler showed me that this service call was itself making around 20 web service calls to a second system that could obviously add up to 20 seconds, if that other web service took 1 second for each of its responses (and the logs showed that sometimes it did).  It turned out that almost all of those web service calls were redundant and completely unnecessary.  Simply removing them (which took about 1 day of effort) shaved 19 seconds off this web service call's duration in production in some cases.</p>
<p>The total execution time spent on database calls was 5 milliseconds.  A 50% improvement there would probably take a week's worth of effort, and really only get you 2 or 3 milliseconds of performance improvement.</p>
<p>The moral of the story is that there's a pretty simple process for optimizing a system:</p>
<div>
<ol>
<li>Identify and isolate the component that is tying up the most time in the system  (let's call it the bottleneck)</li>
<li>Optimize that component to make it less wasteful</li>
<li>Repeat</li>
</ol>
</div>
<p>Skipping step 1 isn't a shortcut.  It's absolutely critical to know that you're optimizing the bottleneck, and not some other random component.</p>
<p>This is pretty obvious stuff for most experienced developers of course.  And while they seem to know to apply this to the systems that they work on, it's more rare that they notice it outside of the code and see it in the process of software engineering in general.</p>
<p>The software development <strong>process</strong> is a system as well, made up of components.  Requirements come in at one end, and deliverables go out the other end.  As people who are involved in that process, we naturally want it to be more and more efficient.  We are constantly trying to figure out how to optimize that system so we can deliver better software in less time.</p>
<p>So step 1:  Identify and isolate the component that is tying up the most time in the system.</p>
<div>Not every team develops software the same way, so this component of the process <em>could</em> be different team by team.  In practice though, I've always seen teams spending the most time doing these sorts of things:</div>
<div>
<ul>
<li>Refactoring poorly written code so that features can be added</li>
<li>Learning/relearning existing code that has long since swapped out of all developers' "mind pages" (for extension or bug-squashing).</li>
<li>Debugging</li>
<li>Performing Manual User Acceptance Testing (by both developers and testers)</li>
<li>issue tracking (administration of that tool and issue in it)</li>
<li>discovery and documentation of steps to reproduce</li>
<li>triage (what bugs to squash first?)</li>
<li>communication between customers, support, QA and developers</li>
<li>customer support</li>
<li>customer dissatisfaction leading to churn and reputation problems (affecting the entire organization)</li>
</ul>
</div>
<p>All of these time consumers are affected directly or indirectly by our ability to control quality.  In my experience, the majority of the software development process isn't hung up in requirements analyis, design, or implementation.  It's hung up in all these Quality Control related issues.  Quality Control is the constraint that keeps us from creating the right software faster.  Steve McConnell confirms it in a more scientific way than I ever could:</p>
<p style="padding-left: 30px;">The rest of us would do well to learn from a discovery made by IBM in the 1970s: Products with the lowest defect counts also have the shortest schedules (Jones 1991). Many organizations currently develop software with defect levels that give them longer schedules than necessary. After surveying about 4000 software projects, Capers Jones reported that poor quality was one of the most common reasons for schedule overruns (1994). He also reported that poor quality is implicated in close to half of all canceled projects. A Software Engineering Institute survey found that more than 60 percent of organizations assessed suffered from inadequate quality assurance (Kitson and Masters 1993). On the curve in Figure 1, those organizations are to the left of the 95-percent-removal line.</p>
<p style="padding-left: 30px;">(<a href="http://www.stevemcconnell.com/articles/art04.htm"><span style="color: #000000;">http://www.stevemcconnell.com/articles/art04.htm</span></a> -- The whole article is extremely illuminating)</p>
<p>What this means is that if we really want to move quickly, we need to take a good hard look at how we manage quality.  Of course this is counter-intuitive, and its actually hard to swallow, because ensuring quality can be mundane and tedious if you're not doing it right.  But as developers we'd be silly to ignore the real bottleneck in the process, and optimizing for that.  Micro-optimizations elsewhere in the process will yield very little benefit compared to improving measures that ensure quality.</p>
<p>As developers, we love to argue about and discuss these micro-optimizations all day long:</p>
<div>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Editor_war">what text editor you use</a></li>
<li><a href="http://steve-yegge.blogspot.com/2008/09/programmings-dirtiest-little-secret.html">how important input speed is</a></li>
<li><a href="http://stackoverflow.com/questions/136056/ide-or-text-editor">IDEs vs. editors</a></li>
</ul>
</div>
<p>It sure seems silly though to be pursuing micro-optimizations, at the expense of tackling the real #1 time-suck:  Quality.</p>
]]></content:encoded>
			<wfw:commentRss>http://caines.ca/blog/testing/quality-control-is-the-constraint/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fight starter #66: The Exercise Suite</title>
		<link>http://caines.ca/blog/programming/fight-starter-66-the-exercise-suite/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://caines.ca/blog/programming/fight-starter-66-the-exercise-suite/#comments</comments>
		<pubDate>Tue, 30 Mar 2010 06:02:09 +0000</pubDate>
		<dc:creator>Gregg</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://caines.ca/blog/?p=266</guid>
		<description><![CDATA[Fight starter #66: The Exercise Suite
It's no fun to write about stuff that everyone agrees on, so I'm going to write about something that almost everyone seems to disagree with me
about:
100% code coverage is almost always possible. It's a valuable target, and it's a worthwhile goal in and of itself.
The primary argument that gets dragged [...]]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Fight starter #66: The Exercise Suite</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">It's no fun to write about stuff that everyone agrees on, so I'm going to write about something that almost everyone seems to disagree with me</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">about:</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">100% code coverage is almost always possible. It's a valuable target, and it's a worthwhile goal in and of itself.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">The primary argument that gets dragged out repeatedly is that 100% code coverage doesn't indicate anything about the quality of your tests</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">whatsoever.  It's certainly possible to get code 100% covered without writing a single assert, or by writing incorrect or incomplete tests.  If you</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">don't actually assert everything you care about properly, code coverage doesn't seem to be very valuable at all.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">While this is true, unless you have dishonest developers, that code coverage percent does indicate an attempt at quality tests.  And really, an</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">honest attempt is all we can ever ask for.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">I'm willing to hypothesize though, for the sake of argument that somehow the class under test somehow is 100% covered by wrong tests, incomplete</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">tests, or tests with no asserts whatsoever.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">I'm going to still contend that that coverage metric is a quality indicator.  The important thing to notice is that it means you've somehow managed</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">to exercise 100% of your codebase.  Let's call this hypothetical suite an "Exercise Suite" instead. This is actually a huge accomplishment that</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">means a few things:</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(1) You don't have dead code in your class-under-test.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">If you can't exercise every branch in a given class, you've got dead code.  Dead code should always be removed to keep from cluttering up future</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">maintenance efforts.  (Think you might need it again?  That's what version control systems are for -- You can always go back and get it again.)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(2) Your codebase can be loaded into a test harness.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">This is actually one of the hardest parts about testing codebases written in procedural languages, or languages that allow scripts, or "includes".</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">The contents of a given file can't be brought under test reliably and repeatably unless it is possible to load it into the test harness without it</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">actually doing anything until it's exercised by the tests.  If you've ever tried to get a legacy PHP project under test, you'll know what I'm</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">talking about here.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(3) You've figured out how to avoid/mitigate side effects.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Code that accesses a database, the filesystem, a web service, hardware, etc is very hard to exercise quickly and without side effects.  If your</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">exercise suite has managed to get 100% coverage, while still running fast, reliably and repeatably, you've scored a major victory.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(4)  You can detect a myriad of run-time errors.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">"Failures" are generally what you have when a test fails.  You care about "errors" too though: Errors are all the things that can go wrong at</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">run-time that are obvious just by executing the code with certain inputs.  Exercise alone can uncover a number of these.  We routinely catch null</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">pointer exceptions in our test suite (attempts to access properties that aren't correctly initialized yet), not through failed tests, but instead</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">simply through exercise.  The test runner catches many of them, and always shoves those directly in our face to be solved.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">I think my unpopular opinion comes from two things about me that puts me in a bit of a minority as far as developers go:</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(1)  I've spent a bunch of time actually doing TDD, and I expect unit-tests to look like they were written before the code even if they weren't.  If</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">you're writing tests before code, as TDD prescribes, you're generally not going to end up with uncovered code.  At any point in the process, the</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">only asymmetry that's likely is that there are tests that are trying to test code that doesn't yet exist.  To have uncovered code in TDD generally</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">means you've done something wrong.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(2)  I'm extremely accustomed to working with dynamically-typed languages, so I've learned to rely on unit-tests for almost every aspect of</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">verification.  I use them to debug.  I use them for syntax-validation.  I use them to ensure I'm interacting with other objects in ways that they</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">expect (ie, "Did I get that parameter order right in that method call?").  There is no static type-system, so I don't have any quality safe-guard</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">other than the tests I write.  In that scenario, uncovered code is a risk I don't want to take -- it could even contain syntax errors!</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">In short, the hypothetical Exercise Suite has a lot of value in and of itself.</div>
<p>It's no fun to write about stuff that everyone agrees on, so I'm going to write about something that almost everyone seems to disagree with me about:</p>
<p><strong> 100% code coverage is almost always possible. It's a valuable target, and it's a worthwhile goal in and of itself.</strong></p>
<p>The primary argument that gets dragged out repeatedly is that 100% code coverage doesn't indicate anything about the quality of your tests whatsoever.  It's certainly possible to get code 100% covered without writing a single assert, or by writing incorrect or incomplete tests.  If you don't actually assert everything you care about properly, code coverage doesn't seem to be very valuable at all.</p>
<p>While there is a lot of truth to this, unless you have dishonest developers, that code coverage percent does indicate an attempt at quality tests.  And really, an honest attempt is all we can ever ask for.</p>
<p>I'm willing to hypothesize though, for the sake of argument that somehow the class under test somehow is 100% covered by wrong tests, incomplete tests, or tests with no asserts whatsoever.  Let's call it an Exercise Suite instead, because that's all it does; it <em>exercises</em> the code.</p>
<p>I'm going to still contend that that coverage metric is a quality indicator.  The important thing to notice is that it means you've somehow managed to exercise 100% of your codebase.  This is actually a huge accomplishment that means a few things:</p>
<h5>(1) You don't have dead code in your class-under-test.</h5>
<p>If you can't exercise every branch in a given class, you've got dead code.  Dead code should always be removed to keep from cluttering up future maintenance efforts.  (Think you might need it again?  That's what version control systems are for -- You can always go back and get it again.)</p>
<h5>(2) Your codebase can be loaded into a test harness.</h5>
<p>This is actually one of the hardest parts about testing codebases written in procedural languages, or languages that allow scripts, or "includes".  The contents of a given file can't be brought under test reliably and repeatably unless it is possible to load it into the test harness without it actually doing anything until it's exercised by the tests.  If you've ever tried to get a legacy PHP project under test, you'll know what I'm talking about here.</p>
<h5>(3) You've figured out how to avoid/mitigate side effects.</h5>
<p>Code that accesses a database, the filesystem, a web service, hardware, etc is very hard to exercise quickly and without side effects.  If your exercise suite has managed to get 100% coverage, while still running fast, reliably and repeatably, you've scored a major victory.</p>
<h5>(4)  You can detect a myriad of run-time errors.</h5>
<p>"Failures" are generally what you have when a test fails.  You care about "errors" too though: Errors are all the things that can go wrong at run-time that are obvious just by executing the code with certain inputs.  Exercise alone can uncover a number of these.  We routinely catch null pointer exceptions in our test suite (attempts to access properties that aren't correctly initialized yet), not through failed tests, but instead simply through exercise.  The test runner catches many of them, and always shoves those directly in our face to be solved.</p>
<p>I think my unpopular opinion comes from two things about me that puts me in a bit of a minority as far as developers go:</p>
<p><strong>(1)  I've spent a bunch of time actually doing TDD, and I expect unit-tests to look like they were written before the code even if they weren't. </strong> If you're writing tests before code, as TDD prescribes, you're generally not going to end up with uncovered code.  At any point in the process, the only asymmetry that's likely is that there are tests that are trying to test code that doesn't yet exist.  To have uncovered code in TDD generally means you've done something wrong.</p>
<p><strong>(2)  I'm extremely accustomed to working with dynamically-typed languages, so I've learned to rely on unit-tests for almost every aspect of verification.</strong> I use them to debug.  I use them for syntax-validation.  I use them to ensure I'm interacting with other objects in ways that they expect (ie, "Did I get that parameter order right in that method call?").  There is no static type-system, so I don't have any quality safe-guard other than the tests I write.  In that scenario, uncovered code is a risk I don't want to take -- it could even contain syntax errors!</p>
<p>In short, the hypothetical Exercise Suite has a lot of value in and of itself.</p>
]]></content:encoded>
			<wfw:commentRss>http://caines.ca/blog/programming/fight-starter-66-the-exercise-suite/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Top 6 Common Excuses to Avoiding Unit-Testing</title>
		<link>http://caines.ca/blog/programming/the-top-5-common-excuses-to-avoiding-unit-testing/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://caines.ca/blog/programming/the-top-5-common-excuses-to-avoiding-unit-testing/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 13:27:01 +0000</pubDate>
		<dc:creator>Gregg</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://caines.ca/blog/?p=252</guid>
		<description><![CDATA[5 Common Excuses for Avoiding Unit-Testing
I just finished reading an article on the The Maintainability of Unit Tests (http://java.dzone.com/articles/maintainability-unit-tests) and a lot of what was being said there is contrary to my experiences with unit-testing, so I wanted to suggest a few counterpoints.
Basically there's a discussion of how unit-testing can hinder productivity when you have [...]]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">5 Common Excuses for Avoiding Unit-Testing</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">I just finished reading an article on the The Maintainability of Unit Tests (http://java.dzone.com/articles/maintainability-unit-tests) and a lot of what was being said there is contrary to my experiences with unit-testing, so I wanted to suggest a few counterpoints.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">Basically there's a discussion of how unit-testing can hinder productivity when you have to make major changes to code under test, and more than a few commenters have questioned a goal of 100% coverage.  I'd like to go through those points one-by-one, as well as through some additional points I hear quite often.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">= External functional tests would allow more maintenance flexibility under the covers while still finding regressions.  =</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">Here's a quote I love to drag around: “In the industry, people often go back and forth about whether particular tests are unit tests. Is a test really a unit test if it uses another production class? I go back to the two qualities: Does the test run fast? Can it help us localize errors quickly?” (Michael Feathers,  Working Effectively with Legacy Code)</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">So, unit-tests are simply tests that run fast and help you quickly pinpoint where an error originates from.  External functional tests are neither fast nor useful at telling you where the problem occurred.  The end result is that you can't run your external functional test suite as you work in small iterations improving your codebase.  You can't run it after every compile and before every check-in, because it takes too long!  And when a functional test suite finds a bug, it can certainly tell you a bug exists, but it's completely useless and showing you where that bug occurred.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">* Major changes to a heavily unit-tested portion of code can lead to tedious test changes that take up as much as 85% of the effort.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">For new code:  Instead of doing Test-first development, or test-driven design, our team often postpones writing tests until (1) the requirements have been completely fleshed-out and (2) the approach is known to be a good one.  I think that's perfectly fine -- we're prototyping (http://caines.ca/blog/programming/the-lost-art-of-prototyping/).  Ideally a prototype would be largely discarded when it's done and TDD would begin for the production-quality code (It would probably be pretty wasteful to not copy/paste large chunks from the prototype code though).  It's critically important that you don't try to prototype your way to production-quality code, so it's best to stop prototyping as soon as the unclearness of the task becomes clear.  After the point that the requirements and the approach are clear, any programming that you do without tests will just be the kind of cowboy-coding you were hoping to avoid.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">For code already in production:  Any major change should be executed as a series of minor changes.  Every minor change should be preceded by introducing a failing test.  If you follow those two rules, you predictably and systematically meet your goals while guaranteeing that you don't introduce regressions.  It's worth it to take the time to write the kind of code that doesn't need to be revisited over and and over in the future, because it was done properly the first time while you had the best understanding of it.  Count yourself lucky that you had all of these existing tests that probably just require minor tweaks.  Take note of how little manual testing you had to do, and how few regressions you introduced.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">* It's impossible and fruitless to unit-test view components / UI controls.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">It's certainly not impossible.  In our actionscript / flex code, we routinely get 100% coverage on UI controls.  UI controls inevitably have logic and state, and it's not really something we try to avoid.  A checkbox for instance has a state (checked or not) and it has presentation logic to decide whether to show the little black "X" or not.  To move that logic and state somewhere else would be silly and to throw up our hands and say "We can't unit-test UI controls!" would be untrue.  It's true that there are important (visual) functions of that control that still fall outside the realm of unit-testability, but that doesn't mean you can't get that code 100% covered by tests.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">* Some code is so trivial that there's no point testing it.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">One example given to illustrate this point was a DTO with 20+ properties on it.  What's the point of testing that those properties can be written and read?  It's so trivial that it can't be wrong!</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">Actually that's not true.  For example: properties always have initial values, and it's easy for a piece of code to rely on a specific default initial value that could be changed by future maintenance.  That's a breakage that static analysis (the compiler) isn't going to know about.  Sure this kind of bug is unlikely to occur in any particular commit, but over time it becomes more and more likely, and your unit tests will always be there to prevent it.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">It doesn't matter how trivial a piece of code is: humans can always find ways to get a bug into it.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">It's also still very easy to get 100% coverage on that class without writing tests for it at all.  It can be tested indirectly by getting all classes that use it 100% under test.  If you can't get it 100% under test by getting its consumers under test, then it likely has unnecessary features or dead code.  Clean that unnecessary maintenance overhead out and you'll get that 100%.  Is it still a unit-test if you don't have that class directly covered?  Don't worry about that -- ask yourself if that class is covered directly well enough for you to find defects in it quickly.  If it's still not, then we're likely not talking about a trivial piece of code (like a DTO) at all.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">* There's a law of diminishing returns as you write more and more minor tests to get 100% coverage.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">In practice, we actually see the reverse.  The devil does appear to be in the details:  those things that we thought were minor understandably didn't get much thought during implementation either, and we often don't find bugs in our code (if we're doing post-implementation unit-testing) until we actually get down to those minor details.  We're routinely surprised at the issues that we find in the last 20% of our coverage pursuit.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">* Unit-testing is not a guarantee of correctness, so we shouldn't get too extreme about it.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">I don't want to get too far into explaining the problems with this, but let me just propose the following:</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">"Ropes can sometimes break and snap, so mountain climbers shouldn't be too strict about using them."</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">It's absolutely true that unit-testing (even with 100% coverage) does not guarantee correctness.  Anyone who's ever done any significant unit-testing has to wonder at some point "Who tests the test?".  A unit-test is simply a double-check.  If you have bad tests, passing them doesn't mean anything.  Unit-testing is not a silver bullet that will solve all your quality problems: it's just an *extremely* valuable tool.</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">In my experience some of the nastiest issues lie in the parts that you think are too obvious to need testing.  Unit-testing has been a huge boost to the level of quality of our output, so I see absolutely no reason to not aim for 100%.</div>
<p>I just finished reading an article on the <a href="http://java.dzone.com/articles/maintainability-unit-tests">The Maintainability of Unit Tests</a> and a lot of what was being said there is contrary to my experiences with unit-testing, so I wanted to suggest a few counterpoints.</p>
<p>Basically there's a discussion of how unit-testing can hinder productivity when you have to make major changes to code under test, and more than a few commenters have questioned a goal of 100% coverage.  I'd like to go through those points one-by-one, as well as through some additional points I hear quite often.</p>
<h4>"External functional tests would allow more maintenance flexibility under the covers while still finding regressions."</h4>
<p><span style="font-weight: normal; font-size: 13px;"><br />
Here's a quote I love to drag around:<br />
</span></p>
<blockquote><p>“In the industry, people often go back and forth about whether particular tests are unit tests. Is a test really a unit test if it uses another production class? I go back to the two qualities: Does the test run fast? Can it help us localize errors quickly?” (Michael Feathers,  <a href="http://www.amazon.ca/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052"><span style="color: #000000;">Working Effectively with Legacy Code</span></a> -- a really great book in my opinion!)</p></blockquote>
<p>So, unit-tests are simply tests that run fast and help you quickly pinpoint where an error originates from.</p>
<p>External functional tests, on the other hand, are neither fast nor useful at telling you where the problem occurred.  The end result is that you can't run your external functional test suite as you work in small iterations improving your codebase.  You can't run it after every compile and before every check-in, because it takes too long!  And when a functional test suite finds a bug, it can certainly tell you a bug exists, but it's completely useless and showing you where that bug occurred.</p>
<h4>"Major changes to a heavily unit-tested portion of code can lead to tedious test changes that take up as much as 85% of the effort"</h4>
<p>There are two different scenarios where I've seen this statement applied:</p>
<h5><strong>For new code </strong></h5>
<p>Instead of doing Test-first development, or test-driven design, our team often postpones writing tests until (1) the requirements have been completely fleshed-out and (2) the approach is known to be a good one.  I think that's perfectly fine -- we're <a href="http://caines.ca/blog/programming/the-lost-art-of-prototyping/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed">prototyping</a>.</p>
<p>Ideally a prototype would be largely discarded when it's done and TDD would begin for the production-quality code (It would probably be pretty wasteful to not copy/paste large chunks from the prototype code though).  It's critically important that you don't try to prototype your way to production-quality code, so it's best to stop prototyping as soon as the unclearness of the task becomes clear.  After the point that the requirements and the approach are clear, any programming that you do without tests will just be the kind of cowboy-coding you were hoping to avoid.</p>
<h5>For code already in production</h5>
<p>Any major change should be executed as a series of minor changes.  Every minor change should be preceded by introducing a failing test.  If you follow those two rules, you predictably and systematically meet your goals while guaranteeing that you don't introduce regressions.</p>
<p>It's worth it to take the time to write the kind of code that doesn't need to be revisited over and over in the future, because it was done properly the first time while you had the best understanding of it.</p>
<p>Count yourself lucky that you had all of these existing tests that probably just require minor tweaks.  Take note of how little manual testing you had to do, and how few regressions you introduced.</p>
<h4>"It's impossible and fruitless to unit-test view components / UI controls."</h4>
<p>It's certainly not impossible.  In our actionscript / flex code, we routinely get 100% coverage on UI controls.  UI controls inevitably have logic and state, and it's not really something we try to avoid.  A checkbox for instance has a state (checked or not) and it has presentation logic to decide whether to show the little black "X" or not.  To move that logic and state somewhere else would be silly and to throw up our hands and say "We can't unit-test UI controls!" would be untrue.  It's true that there are important (visual) functions of that control that still fall outside the realm of unit-testability, but that doesn't mean you can't get that code 100% covered by tests.</p>
<h4>"Some code is so trivial that there's no point testing it."</h4>
<p>One example given to illustrate this point was a DTO with 20+ properties on it.  What's the point of testing that those properties can be written and read?  It's so trivial that it can't be wrong!</p>
<p>Actually that's not true.  For example: properties always have initial values, and it's easy for a piece of code to rely on a specific default initial value that could be changed by future maintenance.  That's a breakage that static analysis (the compiler) isn't going to know about.  Sure this kind of bug is unlikely to occur in any particular commit, but over time it becomes more and more likely, and your unit tests will always be there to prevent it.</p>
<p>It doesn't matter how trivial a piece of code is: humans can always find ways to get a bug into it.</p>
<p>It's also still very easy to get 100% coverage on that class without writing tests for it at all.  It can be tested indirectly by getting all classes that use it 100% under test.  If you can't get it 100% under test by getting its consumers under test, then it likely has unnecessary features or dead code.  Clean that unnecessary maintenance overhead out and you'll get that 100%.  Is it still a unit-test if you don't have that class directly covered?  Don't worry about that -- ask yourself if that class is covered directly well enough for you to find defects in it quickly.  If it's still not, then we're likely not talking about a trivial piece of code (like a DTO) at all.</p>
<h4>"There's a law of diminishing returns as you write more and more minor tests to get 100% coverage."</h4>
<p>In practice, we actually see the reverse.  The devil does appear to be in the details:  those things that we thought were minor understandably didn't get much thought during implementation either.  We often don't find bugs in our code (if we're doing post-implementation unit-testing of legacy code) until we actually get down to those minor details.  We're routinely surprised at the issues that we find in the last 20% of our coverage pursuit.</p>
<h4>"Unit-testing is not a guarantee of correctness, so we shouldn't get too extreme about it."</h4>
<p>I don't want to get too far into explaining the problems with this, but let me just propose the following:</p>
<p>"Ropes can sometimes break and snap, so mountain climbers shouldn't be too strict about using them."</p>
<p>It's absolutely true that unit-testing (even with 100% coverage) does not guarantee correctness.  Anyone who's ever done any significant unit-testing has to wonder at some point "Who tests the test?".  A unit-test is simply a double-check.  If you have bad tests, passing them doesn't mean anything.  Unit-testing is not a silver bullet that will solve all your quality problems: it's just an extremely valuable tool.</p>
]]></content:encoded>
			<wfw:commentRss>http://caines.ca/blog/programming/the-top-5-common-excuses-to-avoiding-unit-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

