<?xml version="1.0" encoding="ISO-8859-1"?>
<rss version="2.0">
  <channel>
    <title>
      James Shore
      
    </title>
    <link>http://jamesshore.com</link>
    <description>Successful Software</description>
    <language>en</language>
    <copyright>Copyright 2000-2006, James Shore</copyright>
    <generator>Blosxom v2.0</generator>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    
<item>
  <title>Testing Private Methods</title>
  <link>http://jamesshore.com/Blog/Testing-Private-Methods.html</link>
  <description>

    

    &lt;table width="100%" border="0" padding="0" spacing="0"&gt;
      &lt;tr&gt;
        &lt;td align="left"&gt;
          &lt;b&gt;19 Aug 2008&lt;/b&gt;
        &lt;/td&gt;
        &lt;td align="right"&gt;
          &lt;i&gt; &lt;a href="http://jamesshore.com/Blog/"&gt;James Shore/Blog&lt;/a&gt; &lt;/i&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  
    
    
      
&lt;p&gt;One of my Mentor Program participants just asked me about testing private methods.  Here's my response:&lt;/p&gt;

&lt;p&gt;Generally, you should be able to test private methods by calling a public method in such a way that it calls the private method.  Remember, when you're writing a private method, you're engaging in encapsulation and information hiding.  You're saying &quot;this method is an implementation detail, not an important part of the class's interface.&quot;  And tests are supposed to document the &lt;em&gt;public behavior&lt;/em&gt;, not the &lt;em&gt;internal implementation&lt;/em&gt;.  So testing a private method can be a sign of a problem.&lt;/p&gt;

&lt;p&gt;Sometimes you really need to test a private method.  The quick-and-easy solution is to make the method public, and I'll admit that I've done so on occasion.  (Often, I'll mark it &quot;for testing only!&quot;)  But that makes your class's interface more confusing and reduces its self-documentation.  It's harder to understand a class's responsibilities if there's no way to tell public behavior from implementation detail.&lt;/p&gt;

&lt;p&gt;If you need to make private methods public, it may be a sign that your class has become too big and complex.  Often these sorts of classes need to be split into multiple, smaller classes with more clearly defined responsibilities.  Once you do that, private methods often become public, because now they're part of the interface that defines the class's behavior, not just an implementation detail.&lt;/p&gt;

    
    
    &lt;p&gt;&lt;a href="http://jamesshore.com/Blog/Testing-Private-Methods.html#comments"&gt;Comments&lt;a&gt;&lt;p&gt;
  </description>
  <category>/Blog</category>
  <guid isPermaLink="true">http://jamesshore.com/Blog/Testing-Private-Methods.html</guid>
</item>
<item>
  <title>29% Discount at Amazon</title>
  <link>http://jamesshore.com/Blog/29-Percent-Discount-at-Amazon.html</link>
  <description>

    

    &lt;table width="100%" border="0" padding="0" spacing="0"&gt;
      &lt;tr&gt;
        &lt;td align="left"&gt;
          &lt;b&gt;18 Aug 2008&lt;/b&gt;
        &lt;/td&gt;
        &lt;td align="right"&gt;
          &lt;i&gt; &lt;a href="http://jamesshore.com/Blog/"&gt;James Shore/Blog&lt;/a&gt; &lt;/i&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  
    
    
      
&lt;p&gt;Amazon has bumped their discount for &lt;cite&gt;&lt;a href=&quot;http://jamesshore.com/Agile-Book/&quot;&gt;The Art of Agile Development&lt;/a&gt;&lt;/cite&gt; from 14% to 29%, which is a pretty good deal.  If you've been thinking about picking up a few extra copies for your team, &lt;a href=&quot;http://www.amazon.com/dp/0596527675&quot;&gt;now's a good time&lt;/a&gt;.&lt;/p&gt;

&lt;p class=&quot;aside&quot;&gt;(Why the sudden change?  I have no idea.  The Amazonians are a mysterious tribe, impossible for mere mortals to understand, and not to be trifled with.  The last anthropologist to venture into that trackless jungle emerged six months later, eyes bulging and brain addled, with nothing to say but a mindless repeated cry: &quot;Tapioca!  Tapioca!&quot;  Six servings later, he fell into a vegatative state, and nothing could be done except wipe off the pudding and place him in the care of Dr. Finkle's Sanitarium and Public Exposition (Some Exhibits Not Suitable for Small Children or the Faint of Heart).  There he remains today.)&lt;/p&gt;

    
    
    &lt;p&gt;&lt;a href="http://jamesshore.com/Blog/29-Percent-Discount-at-Amazon.html#comments"&gt;Comments&lt;a&gt;&lt;p&gt;
  </description>
  <category>/Blog</category>
  <guid isPermaLink="true">http://jamesshore.com/Blog/29-Percent-Discount-at-Amazon.html</guid>
</item>
<item>
  <title>The Art of Agile Development: Continuous Integration</title>
  <link>http://jamesshore.com/Agile-Book/continuous_integration.html</link>
  <description>

    

    &lt;table width="100%" border="0" padding="0" spacing="0"&gt;
      &lt;tr&gt;
        &lt;td align="left"&gt;
          &lt;b&gt;13 Aug 2008&lt;/b&gt;
        &lt;/td&gt;
        &lt;td align="right"&gt;
          &lt;i&gt; &lt;a href="http://jamesshore.com/Agile-Book/"&gt;James Shore/Agile-Book&lt;/a&gt; &lt;/i&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  
    
    
      
&lt;h3&gt;in 99 words&lt;/h3&gt;

&lt;blockquote class=&quot;ninetynine_words&quot;&gt;

&lt;p&gt;Keep code integrated and build release infrastructure with the rest of the application.  The ultimate goal is to be able to deploy all but the last few hours of work at any time.&lt;/p&gt;

&lt;p&gt;To do so, integrate every few hours and keep your build, test, and other release infrastructure up to date.  Each integration should get as close to a real release as possible.&lt;/p&gt;

&lt;p&gt;Prefer synchronous integration, in which you wait for the integration to succeed, to asynchronous integration, in which a tool tests the integration for you.  Synchronous integration requires fast builds, but ensures that they never break.&lt;/p&gt;

&lt;/blockquote&gt;

&lt;!--

&lt;h3&gt;as haiku&lt;/h3&gt;

&lt;blockquote class=&quot;haiku&quot;&gt;
	&lt;p&gt;&lt;/p&gt;
	
&lt;/blockquote&gt;

--&gt;

&lt;h3&gt;Inside The Book&lt;/h3&gt;

&lt;ul&gt;
	&lt;li&gt;Continuous Integration&lt;/li&gt;
	&lt;li&gt;Why It Works&lt;/li&gt;
	&lt;li&gt;How to Practice Continuous Integration&lt;/li&gt;
	&lt;li&gt;Never Break the Build&lt;/li&gt;
	&lt;li&gt;The Continuous Integration Script
		&lt;ul&gt;
			&lt;li&gt;To update from the repository&lt;/li&gt;
			&lt;li&gt;To integrate&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;Sidebar: Continuous Integration Servers&lt;/li&gt;
	&lt;li&gt;Introducing Continuous Integration&lt;/li&gt;
	&lt;li&gt;Dealing with Slow Builds&lt;/li&gt;
	&lt;li&gt;Multistage Integration Builds&lt;/li&gt;	
	&lt;li&gt;Questions
		&lt;ul&gt;
			&lt;li&gt;I know we're supposed to integrate at least every four hours, but what if our current story or task takes longer than that?&lt;/li&gt;
			&lt;li&gt;What should we do while we're waiting for the integration build to complete?&lt;/li&gt;
			&lt;li&gt;Isn't asynchronous integration more efficient than synchronous integration?&lt;/li&gt;
			&lt;li&gt;Are you saying the asynchronous integration will never work?&lt;/li&gt;
			&lt;li&gt;Our version control system doesn't allow us to roll back quickly.  What do we do?&lt;/li&gt;
			&lt;li&gt;We rolled back our check-in, but the build is still failing on the integration machine.  What do we do now?&lt;/li&gt;
			&lt;li&gt;Why do we need an integration machine?  Can't we just integrate locally and check in?&lt;/li&gt;
			&lt;li&gt;I seem to always run into problems when I integrate.  What am I doing wrong?&lt;/li&gt;
			&lt;li&gt;I'm constantly fixing the build when other people break it.  How can I get them to take continuous integration seriously?&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;Results&lt;/li&gt;
	&lt;li&gt;Contraindications&lt;/li&gt;
	&lt;li&gt;Alternatives&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Brain Dump: Forces Affecting Continuous Integration&lt;/h3&gt;

&lt;p&gt;Ultimately, continuous integration is about a very simple business idea:&lt;/p&gt;

&lt;blockquote&gt;
	&lt;p&gt;Mr. Customer, you can release your software at any time and receive value from it reflecting your investment to date.&lt;/p&gt;
	
	&lt;p class=&quot;sig&quot;&gt;paraphrased from &lt;cite&gt;Planning Extreme Programming&lt;/cite&gt;, by Jeffries and Fowler&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From that core idea, we get the two rules of continuous integration:&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;The code in the version control repository always builds, passes its tests, and is ready to release.&lt;/li&gt;
	&lt;li&gt;The code in the repository represents all of our work up to a few hours ago.&lt;/li&gt;
&lt;/ol&gt;
	
&lt;p&gt;It's not about integration servers, or automated builds, or any of that stuff.  That's all incidental... &lt;em&gt;technique&lt;/em&gt;, not &lt;em&gt;essence&lt;/em&gt;.  The essence is simple.  Release the software at any time.  Recoup your investment.&lt;/p&gt;

&lt;p&gt;With that core idea firmly in mind, let's explore some of the forces that affect continuous integration.  I have to warn you: this list is long, aimed at advanced readers, and not particularly well written.  It's sort of a rambling brain dump.&lt;/p&gt;

&lt;h4&gt;Business Priorities&lt;/h4&gt;

&lt;p&gt;Ideally, the code in the repository is always ready to release.  But even though we can make it technically capable of release (nearly bug-free, builds, passes tests), it's not always going to be ready to release from a business perspective.&lt;/p&gt;

&lt;p&gt;There's two scales here.  First, you have iteration cycles.  During the iteration, the team's allowed to have the software in pieces.  It still needs to be technically capable of release, but features can be half-done and bugs can be unfixed.  Everything is supposed to be wrapped up by the end of the iteration--stories &lt;a href=&quot;http://jamesshore.com/Agile-Book/done_done.html&quot;&gt;&quot;done done&quot;&lt;/a&gt; or removed, bugs fixed, and so forth.&lt;/p&gt;

&lt;p&gt;Second, you have release cycles.  Although all stories are supposed to be &quot;done done&quot; at the end of each iteration, those stories may not represent complete minimum marketable features (MMFs).  So the software may not hang together well, or it may not have the polish necessary to succeed in the market, and so forth.  That stuff is supposed to be wrapped up by the end of the release.&lt;/p&gt;

&lt;p&gt;Really great teams don't have these problems.  Their repository really is ready to release at any time.  I think part of the reason is that they tend to be mature teams with a lot of experience... and they have a mature codebase, too, which allows them to add small features rather than big ones.  It's a lot easier to release daily when you're improving existing features rather than creating a brand new piece of software from scratch.&lt;/p&gt;

&lt;p&gt;That said, it is possible to practice real continuous integration even with a brand-new project.  It requires that the continuous integration mindset extend to product planning as well as programming.  In the past, I've described it as building a mansion by first building a doghouse... then stre-e-e-tching it out into a lean-to... then stre-e-e-tching it into a shed... then adding an out-house... and so on.  That works really well in the Web 2.0 era, but wouldn't work so well for a company like Apple that likes to release polished, seamless obelisks.&lt;/p&gt;

&lt;p&gt;Of all of the ways that continuous integration can be compromised, this is the one that I'm most comfortable with.  Sometimes, it just doesn't make sense to release a piece of software because it isn't functionally ready.  As long as release cycles are kept short and the team keeps producing live demos, I'm okay with that, for the most part.&lt;/p&gt;

&lt;h4&gt;Number of Concurrent Code Streams&lt;/h4&gt;

&lt;p&gt;By &quot;concurrent code streams,&quot; I mean the number of development efforts you have going on at any given time.  For example, if you have a classic XP environment with ten programmers, and they're all working, you'll have five code streams.  The programmers will be working in pairs at five different workstations.  If you aren't pairing, you'll have ten code streams.&lt;/p&gt;

&lt;p&gt;Each of those code streams is, in fact, a short-lived branch of the code.  In a distributed version control system, that fact is made explicit.  In traditional version control systems, the branches are called &quot;sandboxes,&quot; but they're still a sort of branch.  When we integrate, what we're actually doing is merging the branch back in with the mainline.&lt;/p&gt;

&lt;p&gt;The number of code streams is a force on continuous integration because the more code streams you have, the more likely you are to have non-trivial integrations.  (A trivial integration is one where nobody else has checked anything in, hence nothing to integrate with.)  In other words, more code streams means more integration effort and more potential for integration problems.&lt;/p&gt;

&lt;p&gt;The number of concurrent code streams interacts with...&lt;/p&gt;

&lt;h4&gt;Frequency of Integration&lt;/h4&gt;

&lt;p&gt;The more frequently you integrate, the more likely you are to have a trivial integration, which is a good thing.  Think of it this way.  Imagine you and Bob the Schlub from down the hall are the only programmers.  Bob integrates every two weeks and you integrate ten times a day.  When you integrate, 99 out of 100 times, Bob won't have checked in and you'll only be integrating with yourself.  (Kinky.)&lt;/p&gt;

&lt;p&gt;Frequent integrations also makes the amount of code you have to merge smaller, too, which reduces the likelihood of conflict and makes your integrations easier.  So, all in all, frequent integrations are a Good Thing.&lt;/p&gt;

&lt;p&gt;It's not all beer and pork rinds.  Frequent integrations interact with the number of code streams and...&lt;/p&gt;

&lt;h4&gt;Speed of Build&lt;/h4&gt;

&lt;p&gt;By &quot;speed of build,&quot; here, I really mean &quot;the amount of time it takes to build the software and run all of the tests.&quot;&lt;/p&gt;

&lt;p&gt;A slow build leads to all kinds of evils.  One of the things it does is to interact with the number of concurrent code streams to control the frequency of your integrations.  It works like this: if you have ten concurrent code streams and people check in every hour, then you will average ten check-ins per hour.  That means that your build has to take (60 minutes divided by ten equals) six minutes, max.  If your build takes longer than six minutes, then your integrations will pile up.&lt;/p&gt;

&lt;p&gt;In actuality, people don't check in perfectly like that.  It's actually an application of queueing theory, although I can't check that right now.  If I remember correctly that means we need about 30% slack in order to allow the queue to flow smoothly, assuming frequent small check-ins.  So in this scenario, our maximum build time is actually closer to four minutes.&lt;/p&gt;

&lt;p&gt;You can see how this interacts with all kinds of XP practices.  Pair programming cuts the number of concurrent code streams in half, for free.  The ten-minute build keeps builds small.  XP teams tend to integrate every two to four hours, and XP recommends teams that are no larger than 10-12 programmers.&lt;/p&gt;

&lt;p&gt;It works out perfectly: 12 programmers pairing and integrating every two hours is six concurrent code streams.  Do the math (120 min / 6 streams * 70% utilization) and you get a maximum build length of 14 minutes.  Cool.&lt;/p&gt;

&lt;p&gt;Most teams I work with have very slow builds (it's &lt;a href=&quot;http://jamesshore.com/Agile-Book/ten_minute_build.html&quot;&gt;because of their tests&lt;/a&gt;), so they compensate by using...&lt;/p&gt;

&lt;h4&gt;Multi-Stage Builds&lt;/h4&gt;

&lt;p&gt;A multi-stage build was one of the original workarounds presented for slow builds.  (Continuous integration servers were another.)  It breaks my heart, because rather than fixing their build problems, teams invest in these workarounds.  Sigh... &quot;easy&quot; wins out over &quot;good&quot; once again.&lt;/p&gt;

&lt;p&gt;That's not to say a multi-stage build is always bad.  Like many easy solutions, though, it's over-used.  The idea is quite simple: if your tests are slow, split your build into two parts: the &quot;fast&quot; build which runs whenever you integrate, and the &quot;slow&quot; build which runs daily, weekly, or manually just prior to release.&lt;/p&gt;

&lt;p&gt;Sometimes the slow build is a manual regression test carried out by armies of disgrunted testers.  (You'd be disgruntled, too, if you had to do manual script-based regression testing every day.)  This takes days or even weeks.  One company I worked with took days just to set up the test environment.&lt;/p&gt;

&lt;p&gt;A multi-stage build provides fast feedback, but it isn't actually continuous integration.  Remember the core idea: we want to be able to release software that reflects our investment.  The software isn't ready to release until it's passed all of the tests in the slow build, so from a CI perspective, the frequency of integration is actually determined by the frequency of the &lt;em&gt;least frequent&lt;/em&gt; build.&lt;/p&gt;

&lt;p&gt;If you can't release until you've had an army of disgruntled testers run through an array of manual test scripts, then you aren't practicing continuous integration.  You're integrating frequently, sure, but you aren't verifying that the integration succeeded.  You're only doing half of it.&lt;/p&gt;

&lt;p&gt;Slow builds force another common choice...&lt;/p&gt;

&lt;h4&gt;Synchronous vs. Asynchronous Integration&lt;/h4&gt;

&lt;p&gt;Even if a team works around their slow builds by using multi-stage builds, their &quot;fast&quot; build is often quite slow.  Again, thirty minutes is common.  This build is run after every check-in, which means that the team has to use asynchronous integration.&lt;/p&gt;

&lt;p&gt;I talked about synchronous and asynchronous integration in the book, so I'll just summarize: asynchronous integration delays build feedback until after the person or pair has started another task.  As a result, build failures force a context switch and interrupt flow.  In practice, team members tend to delay fixing these build failures.&lt;/p&gt;

&lt;p&gt;Asynchronous integration requires an automated CI tool, and it so happens that most of these tools do not require that the build pass before code is checked into the mainline.  As a result, build errors propagate to the entire team and lead to delays and cascading failures.&lt;/p&gt;

&lt;p&gt;In a team practicing CI well, the team's build should &lt;em&gt;never&lt;/em&gt; break.  An individual person might have trouble checking in, but those build failures should never affect the rest of the team.  Never!  (Well, once every month or two, maybe, due to cross-machine incompatibilities.)  It's trivially easy to do with synchronous integration, and much more difficult with asynchronous integration.&lt;/p&gt;

&lt;h4&gt;Number of Collectively-Owned Codebases&lt;/h4&gt;

&lt;p&gt;Up until now, when I've been talking about a &quot;team,&quot; I've been referring to a group of programmers that are working on the same codebase and using &lt;a href=&quot;http://jamesshore.com/Agile-Book/collective_code_ownership.html&quot;&gt;Collective Code Ownership&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There's another option, of course, and that's code ownership models.  On agile teams, these are most prevalent when you have large groups working on a single product.  For example, you might have five teams collaborating on a single codebase, with each team responsible for a particular part of the code.  This is a common approach, but it's not required.  Some groups choose to use collective ownership, even with larger groups.&lt;/p&gt;

&lt;p&gt;In theory, this sort of code ownership model has clearly defined responsibilities and interfaces, allowing each team to work in their own area without worrying about integrating with the rest of the product.  The reality is a bit less genteel.  APIs never behave quite as expected, so continuous integration is still a good idea.&lt;/p&gt;

&lt;p&gt;Continuous integration in this environment runs into the problems that occur with large numbers of concurrent code streams.  However, it's possible to give each team its own branch for local integrations.  The branches are integrated with the mainline on a regular basis--every two hours, for example.&lt;/p&gt;

&lt;p&gt;By doing this, and assuming that code ownership prevents many of the team's changes from affecting others, each team acts as a single code stream.  This reduces the number of concurrent changes from overwhelming the integration queue.&lt;/p&gt;

&lt;p&gt;Code ownership has its downside.  It requires that modules, integrations points, and APIs be clearly defined, which requires a level of up-front design.  Teams will be organized around the design, which will make it very difficult to change... and some of that design will, inevitably, be wrong.  This calcification of design is why some organizations prefer to have collectively-owned code, even with large teams.&lt;/p&gt;

&lt;h4&gt;End Transmission&lt;/h4&gt;

&lt;p&gt;So... some of the forces affecting continuous integration:&lt;/p&gt;

&lt;table class=&quot;list&quot;&gt;
	&lt;tr&gt;&lt;th&gt;Easier&lt;/th&gt;&lt;th&gt;Harder&lt;/th&gt;&lt;/tr&gt;
	&lt;tr&gt;&lt;td&gt;mature feature set&lt;/td&gt;&lt;td&gt;new product&lt;/td&gt;&lt;/tr&gt;
	&lt;tr&gt;&lt;td&gt;small number of concurrent code streams&lt;/td&gt;&lt;td&gt;large number of concurrent code streams&lt;/td&gt;&lt;/tr&gt;
	&lt;tr&gt;&lt;td&gt;frequent integration&lt;/td&gt;&lt;td&gt;infrequent integration&lt;/td&gt;&lt;/tr&gt;
	&lt;tr&gt;&lt;td&gt;fast build&lt;/td&gt;&lt;td&gt;slow build&lt;/td&gt;&lt;/tr&gt;
	&lt;tr&gt;&lt;td&gt;synchronous integration&lt;/td&gt;&lt;td&gt;asynchronous integration&lt;/td&gt;&lt;/tr&gt;
	&lt;tr&gt;&lt;td&gt;one team&lt;/td&gt;&lt;td&gt;many teams&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;And, as I've discussed, each of these forces affects the others in various ways.&lt;/p&gt;

&lt;p&gt;In the end, though, continuous integration is about one simple idea: we should be able to release our software at any time and get value proportional to our investment.  That's the forest.  Don't let this meander through the trees (or the shiny baubles that are CI tools) distract you from that underlying goal.&lt;/p&gt;

    
    
    &lt;p&gt;&lt;a href="http://jamesshore.com/Agile-Book/continuous_integration.html#comments"&gt;Comments&lt;a&gt;&lt;p&gt;
  </description>
  <category>/Agile-Book</category>
  <guid isPermaLink="true">http://jamesshore.com/Agile-Book/continuous_integration.html</guid>
</item>
<item>
  <title>November 20th in Portland, Oregon: Life Inside an Iteration (Panel)</title>
  <link>http://jamesshore.com/Calendar/2008-11-20.html</link>
  <description>

    

    &lt;table width="100%" border="0" padding="0" spacing="0"&gt;
      &lt;tr&gt;
        &lt;td align="left"&gt;
          &lt;b&gt;08 Aug 2008&lt;/b&gt;
        &lt;/td&gt;
        &lt;td align="right"&gt;
          &lt;i&gt; &lt;a href="http://jamesshore.com/Calendar/"&gt;James Shore/Calendar&lt;/a&gt; &lt;/i&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  
    
    
      
&lt;p&gt;I'll be participating in the Software Association of Oregon's panel discussion, &quot;Life Inside an Iteration,&quot; on November 20th.  We'll be discussing the nuts and bolts of what it's like to participate in an Agile iteration from a variety of perspectives.  I'll post more once I see the SAO's program notes.&lt;/p&gt;

    
    
    &lt;p&gt;&lt;a href="http://jamesshore.com/Calendar/2008-11-20.html#comments"&gt;Comments&lt;a&gt;&lt;p&gt;
  </description>
  <category>/Calendar</category>
  <guid isPermaLink="true">http://jamesshore.com/Calendar/2008-11-20.html</guid>
</item>
<item>
  <title>November 4th, 5th, or 6th at Agile Vancouver: Agile Planning in Action (Tutorial)</title>
  <link>http://jamesshore.com/Calendar/2008-11-04.html</link>
  <description>

    

    &lt;table width="100%" border="0" padding="0" spacing="0"&gt;
      &lt;tr&gt;
        &lt;td align="left"&gt;
          &lt;b&gt;08 Aug 2008&lt;/b&gt;
        &lt;/td&gt;
        &lt;td align="right"&gt;
          &lt;i&gt; &lt;a href="http://jamesshore.com/Calendar/"&gt;James Shore/Calendar&lt;/a&gt; &lt;/i&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  
    
    
      
&lt;p&gt;I'll be reprising my popular Agile 2008 tutorial, &quot;Agile Planning in Action,&quot; at the &quot;Much Ado About Agile&quot; conference in Vancouver, BC.  I'll post the specific date and more information once I see the conference program.&lt;/p&gt;

    
    
    &lt;p&gt;&lt;a href="http://jamesshore.com/Calendar/2008-11-04.html#comments"&gt;Comments&lt;a&gt;&lt;p&gt;
  </description>
  <category>/Calendar</category>
  <guid isPermaLink="true">http://jamesshore.com/Calendar/2008-11-04.html</guid>
</item>
<item>
  <title>October 29-31 in Portland, Oregon: The Art of Agile Delivery (Training)</title>
  <link>http://jamesshore.com/Calendar/2008-10-29.html</link>
  <description>

    

    &lt;table width="100%" border="0" padding="0" spacing="0"&gt;
      &lt;tr&gt;
        &lt;td align="left"&gt;
          &lt;b&gt;08 Aug 2008&lt;/b&gt;
        &lt;/td&gt;
        &lt;td align="right"&gt;
          &lt;i&gt; &lt;a href="http://jamesshore.com/Calendar/"&gt;James Shore/Calendar&lt;/a&gt; &lt;/i&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  
    
    
      
&lt;p&gt;Save the date: Diana Larsen and I will be presenting a public training course on &lt;strong&gt;Agile execution and delivery&lt;/strong&gt; October 29th through the 31st in Portland, Oregon.  This will be a cross-functional class: we'll have sessions for the whole team as well as specialty-specific sessions on subjects such as test-driven development, incremental requirements, and customer testing.&lt;/p&gt;

&lt;p&gt;Watch this space for information and signup details by the end of August... or &lt;a href=&quot;http://jamesshore.com/Consulting/Contact.html&quot;&gt;email me&lt;/a&gt; to be added to the notification list.&lt;/p&gt;

    
    
    &lt;p&gt;&lt;a href="http://jamesshore.com/Calendar/2008-10-29.html#comments"&gt;Comments&lt;a&gt;&lt;p&gt;
  </description>
  <category>/Calendar</category>
  <guid isPermaLink="true">http://jamesshore.com/Calendar/2008-10-29.html</guid>
</item>
<item>
  <title>October 27-28 in Portland, Oregon: The Art of Agile Planning (Training)</title>
  <link>http://jamesshore.com/Calendar/2008-10-27.html</link>
  <description>

    

    &lt;table width="100%" border="0" padding="0" spacing="0"&gt;
      &lt;tr&gt;
        &lt;td align="left"&gt;
          &lt;b&gt;08 Aug 2008&lt;/b&gt;
        &lt;/td&gt;
        &lt;td align="right"&gt;
          &lt;i&gt; &lt;a href="http://jamesshore.com/Calendar/"&gt;James Shore/Calendar&lt;/a&gt; &lt;/i&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  
    
    
      
&lt;p&gt;Save the date: Diana Larsen and I will be presenting a public training course on &lt;strong&gt;Agile planning&lt;/strong&gt; on October 27th and 28th in Portland, Oregon.  Watch this space for information and signup details by the end of August... or &lt;a href=&quot;http://jamesshore.com/Consulting/Contact.html&quot;&gt;email me&lt;/a&gt; to be added to the notification list.&lt;/p&gt;

    
    
    &lt;p&gt;&lt;a href="http://jamesshore.com/Calendar/2008-10-27.html#comments"&gt;Comments&lt;a&gt;&lt;p&gt;
  </description>
  <category>/Calendar</category>
  <guid isPermaLink="true">http://jamesshore.com/Calendar/2008-10-27.html</guid>
</item>
<item>
  <title>October 15th at PNSQC: Collaborative Quality (Panel)</title>
  <link>http://jamesshore.com/Calendar/2008-10-15.html</link>
  <description>

    

    &lt;table width="100%" border="0" padding="0" spacing="0"&gt;
      &lt;tr&gt;
        &lt;td align="left"&gt;
          &lt;b&gt;08 Aug 2008&lt;/b&gt;
        &lt;/td&gt;
        &lt;td align="right"&gt;
          &lt;i&gt; &lt;a href="http://jamesshore.com/Calendar/"&gt;James Shore/Calendar&lt;/a&gt; &lt;/i&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  
    
    
      
&lt;p&gt;I will part of a panel be at the Pacific Northwest Software Quality Conference (PNSQC) on October 15th.  The subject of the panel is &quot;Collaborative Quality: Does It Help?&quot;  (Um... yes?)  It's a lunchtime panel, tentatively scheduled for 12:30pm.  I'll post more information here when I see PNSQC's program notes.&lt;/p&gt;

    
    
    &lt;p&gt;&lt;a href="http://jamesshore.com/Calendar/2008-10-15.html#comments"&gt;Comments&lt;a&gt;&lt;p&gt;
  </description>
  <category>/Calendar</category>
  <guid isPermaLink="true">http://jamesshore.com/Calendar/2008-10-15.html</guid>
</item>
<item>
  <title>September 19th in Portland, Oregon: Come Hang With the Agilists (Lunch)</title>
  <link>http://jamesshore.com/Calendar/2008-09-19.html</link>
  <description>

    

    &lt;table width="100%" border="0" padding="0" spacing="0"&gt;
      &lt;tr&gt;
        &lt;td align="left"&gt;
          &lt;b&gt;08 Aug 2008&lt;/b&gt;
        &lt;/td&gt;
        &lt;td align="right"&gt;
          &lt;i&gt; &lt;a href="http://jamesshore.com/Calendar/"&gt;James Shore/Calendar&lt;/a&gt; &lt;/i&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  
    
    
      
&lt;p&gt;The local Portland Agile community gets together every third Friday to eat, drink, and make merry.  Oh, and sometimes we talk about agile stuff, too.  Come join us!  I don't always attend, but I come to as many sessions as my schedule permits.  You can find us at the Broadway McMenamins (on the corner of NE Broadway and 15th) on the third Friday of every month at 1:00pm.&lt;/p&gt;

    
    
    &lt;p&gt;&lt;a href="http://jamesshore.com/Calendar/2008-09-19.html#comments"&gt;Comments&lt;a&gt;&lt;p&gt;
  </description>
  <category>/Calendar</category>
  <guid isPermaLink="true">http://jamesshore.com/Calendar/2008-09-19.html</guid>
</item>
<item>
  <title>The Art of Agile Development: Ten-Minute Build</title>
  <link>http://jamesshore.com/Agile-Book/ten_minute_build.html</link>
  <description>

    

    &lt;table width="100%" border="0" padding="0" spacing="0"&gt;
      &lt;tr&gt;
        &lt;td align="left"&gt;
          &lt;b&gt;30 Jul 2008&lt;/b&gt;
        &lt;/td&gt;
        &lt;td align="right"&gt;
          &lt;i&gt; &lt;a href="http://jamesshore.com/Agile-Book/"&gt;James Shore/Agile-Book&lt;/a&gt; &lt;/i&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  
    
    
      
&lt;h3&gt;in 99 words&lt;/h3&gt;

&lt;blockquote class=&quot;ninetynine_words&quot;&gt;

&lt;p&gt;Build, test, and deploy your entire product at any time with the push of a button.&lt;/p&gt;

&lt;p&gt;Your build should be comprehensive but not complex.  Make it compile source code, run tests, configure registry settings, initialize database schemas, set up web servers, launch processes, build installers, and deploy.  Your IDE won't do all this, so learn to use a dedicated build tool.  Make sure your build works when disconnected from the network, too.&lt;/p&gt;

&lt;p&gt;Builds should be fast.  If not, look at your tests.  End-to-end integration tests are the typical culprit.  Replace them with faster, more maintainable unit tests.&lt;/p&gt;

&lt;/blockquote&gt;

&lt;!--

&lt;h3&gt;as haiku&lt;/h3&gt;

&lt;blockquote class=&quot;haiku&quot;&gt;
	&lt;p&gt;&lt;/p&gt;
	
&lt;/blockquote&gt;

--&gt;

&lt;h3&gt;Inside The Book&lt;/h3&gt;

&lt;ul&gt;
	&lt;li&gt;Ten-Minute Build&lt;/li&gt;
	&lt;li&gt;Automate Your Build&lt;/li&gt;
	&lt;li&gt;How to Automate&lt;/li&gt;
	&lt;li&gt;When to Automate&lt;/li&gt;
	&lt;li&gt;Automating Legacy Projects&lt;/li&gt;
	&lt;li&gt;Ten Minutes or Less&lt;/li&gt;
	&lt;li&gt;Questions
		&lt;ul&gt;
			&lt;li&gt;Who's responsible for maintaining the build script?&lt;/li&gt;
			&lt;li&gt;We have a configuration management (CM) department that's responsible for maintaining our builds.  We aren't allowed to modify the script ourselves.  What do we do?&lt;/li&gt;
			&lt;li&gt;How do we find time to improve our build?&lt;/li&gt;
			&lt;li&gt;Should we really keep all of our tools and libraries in version control?&lt;/li&gt;
			&lt;li&gt;Does the build have to be under 10 minutes?  We're at 11.&lt;/li&gt;
			&lt;li&gt;We use an IDE with an integrated build system.  How can we automate our build process?&lt;/li&gt;
			&lt;li&gt;We have different target and development environments.  How do we make this build work?&lt;/li&gt;
			&lt;li&gt;How can we build our entire product when we rely on third-party software and hardware?&lt;/li&gt;
			&lt;li&gt;How often should we build from scratch?&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;Results&lt;/li&gt;
	&lt;li&gt;Contraindications&lt;/li&gt;
	&lt;li&gt;Alternatives&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Commentary: Living in the Punch Card Era&lt;/h3&gt;

&lt;p&gt;I'm obsessed with fast builds.  There's a good reason for this: fast builds means quicker feedback.  Quicker feedback means fewer bugs.  If the feedback gets fast enough (less than ten seconds), and if you have comprehensive regression tests, then your entire approach to coding changes.  You stop worrying about whether your changes work or not and just program.  Thoughts flow from brain to program without stopping to worry about bugs.  It's an amazing way to work... and I'm willing to bet you've never experienced it because your build is too slow.  (Heck, half of you have given up on me as an idiot at this point.  It's okay.  I'm used to it.)&lt;/p&gt;

&lt;p&gt;Allow me to illustrate.  Once upon a time, people had to worry about syntax errors.  You know, when you accidentally mistype something, or leave out a semicolon?  They obsessed over them, tediously desk-checking their work, to make sure that their programs had no errors, before they even &lt;em&gt;thought&lt;/em&gt; about putting it in the computer!&lt;/p&gt;

&lt;p&gt;&quot;Ridiculous!&quot;, you scoff?  No, just old.  This happened in the punch-card era of computing, in the 60's and 70's.   It could take 24 hours to get your stack of punch cards input into the computer, compiled, and run.  Compiler errors meant your job was rejected and you had to find the error, fix it, resubmit, and wait another 24 hours.  Painful, yes.  Thus with the desk-checking.&lt;/p&gt;

&lt;p&gt;You don't desk-check, do you.  Nope... you type in your program, and if you make a typo (happens all the time, doesn't it?), then a little red squiggly appears in your IDE and you fix it!  No brainer.  In fact, it's so ingrained, you probably don't even notice half the syntax errors you make.&lt;/p&gt;

&lt;p&gt;A fast build with good tests is like &lt;em&gt;that&lt;/em&gt;.  Except that the errors you find and fix are semantic errors--bugs--not syntax errors.&lt;/p&gt;

&lt;p&gt;Good builds are game-changing.&lt;/p&gt;

&lt;p&gt;So, how do you do it?&lt;/p&gt;

&lt;p&gt;It's not hard, but it's not obvious, either.  The obvious part is that you have to automate your build.  Your IDE's build almost certainly won't cut it.  It's also pretty obvious that you have to have a comprehensive regression test suite.  (This is easy if you're creating a new system and you use &lt;a href=&quot;http://jamesshore.com/Agile-Book/test_driven_development.html&quot;&gt;test-driven development&lt;/a&gt;  from the start.  It's &lt;a href=&quot;http://www.amazon.com/Working-Effectively-Legacy-Robert-Martin/dp/0131177052&quot;&gt;less easy&lt;/a&gt; when you're working with existing code.)&lt;/p&gt;

&lt;p&gt;The part that's not obvious is that you don't just need a regression test suite, you need an &lt;em&gt;awesome&lt;/em&gt; regression test suite.  By &quot;awesome,&quot; I mean that it has to be &lt;em&gt;fast&lt;/em&gt;.  You're going to have thousands of tests and you want this puppy to finish in less than ten minutes, and the majority of the tests need to finish in less than ten seconds.  That means you have to be able to run hundreds of tests per second.&lt;/p&gt;

&lt;p&gt;You can see why this is unobvious.  Most people create tests that set up data in the database, stimulate some part of the application, then check that the database changed correctly.  It's slow.  For complex systems with many tiers, it's hella slow.  It's also brittle and prone to breakage, and creating test environments is usually a real pain in the keister.&lt;/p&gt;

&lt;p&gt;If you're doing the database thing, you're probably running less than ten tests per second.  For some of you, your tests are taking tens of seconds each, and they're breaking all the time.&lt;/p&gt;

&lt;p&gt;Yup, fast builds: not obvious.&lt;/p&gt;

&lt;p&gt;Here's the key.  You have to let go of the integration tests.  Figure out how to replace end-to-end integration tests with unit tests.  You don't have to get rid of all of them, but the better you get, the &lt;a href=&quot;http://jamesshore.com/Blog/Does-It-Work-Are-We-Done.html&quot;&gt;fewer you need&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Part of the challenge here is that fast tests require a different design mindset.  If you're creating end-to-end tests rather than unit tests and focused integration tests (the good form of integration test: they're like unit tests, but they cross a process boundary), you can get away with all kinds of &lt;a href=&quot;http://jamesshore.com/Articles/Quality-With-a-Name.html&quot;&gt;sloppy, tightly-coupled design&lt;/a&gt;.  If you primarily write unit tests (and focused integration tests), you have to decouple, create strong responsibilities, and have ways to instantiate objects independently of each other.&lt;/p&gt;

&lt;p&gt;Rise to the challenge.  Fast builds with awesome tests will change your life.  For programmers, they're the best thing you can do for your codebase, your productivity, and your enjoyment of work.&lt;/p&gt;

&lt;p&gt;Go ahead.  It's time to stop living in the punch-card era.&lt;/p&gt;

    
    
    &lt;p&gt;&lt;a href="http://jamesshore.com/Agile-Book/ten_minute_build.html#comments"&gt;Comments&lt;a&gt;&lt;p&gt;
  </description>
  <category>/Agile-Book</category>
  <guid isPermaLink="true">http://jamesshore.com/Agile-Book/ten_minute_build.html</guid>
</item>
  </channel>
</rss>