tag:blogger.com,1999:blog-16973888419861043022024-02-27T01:09:51.631-06:00Agile in a Flash<a href="http://agileotter.blogspot.com">Tim Ottinger</a> & <a href="http://langrsoft.com">Jeff Langr</a> present the blog behind the versatile <br> <a href="http://www.pragprog.com/titles/olag/agile-in-a-flash">Pragmatic Programmers</a> reference cards.Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.comBlogger148125tag:blogger.com,1999:blog-1697388841986104302.post-34163671495459791832020-01-15T09:49:00.000-06:002020-01-15T13:24:57.409-06:00Feel Like You've PARTIED With Mobbing<h4><i>A new AIAF post by Tim Ottinger / Jeff Langr.</i></h4>
Mob programming sounds like a chaotic way of developing software: Get everyone into a room with a computer, let them have at it, and hope for the best.<br />
<p>Perhaps you’ve read enough about mobbing to know that there is one computer, that one person at a time operates that computer’s keyboard and mouse, and that everyone else looks at the screen and makes suggestions. You know that there are two primary roles--the person operating the keyboard (the driver) and the people deciding what to do next (the navigators). You know that you shouldn’t have the same person driving all the time.</p>
<p>Often teams do great with no more than that brief paragraph of guidance. Congratulations! We can assume you now know the key mechanics of mobbing.</p>
<p>However, some mob programming sessions run into problems, and some don’t produce as much value as you’d like in return for the many person-hours you’ve invested. To generate as much value as possible when mobbing, follow our core set of guidelines. You might even feel like you’ve PARTIED:</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisII5DGWKM3bollgE4WJjvuDtoIjP-IdWkUGkIJFgZAOMMs3pVfCgEjH9lixY1Ab4cev1viTtqZE8yfUKNKbDbmK0-N3QwkchzLdXHIeaXmQHl3INjQaCZBrL6-t0BeYXaPua98khL0MP_/s1600/mob.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="954" data-original-width="1600" height="190" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisII5DGWKM3bollgE4WJjvuDtoIjP-IdWkUGkIJFgZAOMMs3pVfCgEjH9lixY1Ab4cev1viTtqZE8yfUKNKbDbmK0-N3QwkchzLdXHIeaXmQHl3INjQaCZBrL6-t0BeYXaPua98khL0MP_/s320/mob.jpg" width="320" /></a></div>
<h3>P: Pay down promise debt</h3>
<p>Programming requires a lot of attention to detail. It can be a struggle to keep the big picture in mind while dealing with software architecture, various libraries, detailed requirements, and language minutiae.</p>
<p>As you and your mob make small changes in various places in the code to implement a feature, you can’t help but notice neighboring code that’s less than ideal. Maybe it exhibits a code smell or a potential defect. Maybe you suspect a security issue and need to check it out more fully.</p>
<p>How should you handle such a “distraction,” one of countless that will arise during a typical mobbing session?</p>
<ul>
<li>If you ignore it, you may release code that is poorly designed, reads poorly, or that has defects.</li>
<li>If you work on it now, you may lose context in the work you’re trying to accomplish.</li>
<li>If you try to remember it, you may forget because you’re so focused on the job at hand.</li>
</ul>
<p>So you make a note of the concern as a piece of promise debt. Your promise debt list means you won’t have to worry about forgetting. You can avoid the distraction for now, and tackle it next time you come up for air or when you finish the current task.</p>
<p>We call this “promise debt” for a reason: The list consists of obligations you’ll want to pay off by the end of the mob session. Don’t pretend you’re done if you haven’t addressed all the concerns on the list one way or another.</p>
<p>By paying off promise debt, you honor the time your team invested in making the list, and you demonstrate respect for the code everyone works on. Your honor shows your dedication and discipline in managing the codebase. The attention helps you uncover weaknesses in the current design before they become defects.</p>
<h3>A: Argue in code</h3>
<p>When people talk about code in abstract terms, they often take on conflicting stances. “If we focus too much on readability,” one says, “we will sacrifice performance!” Another says, “if we make small objects, it will restrict our ability to use the values contained in them too much!”</p>
<p>As long as the topic is abstract and general, it is hard to come to any real understanding of what is “universally best,” since making trade-offs is context-specific. This is a core problem with abstract ideas in practical places: Our problems won’t be resolved in the abstract.</p>
<p>By creating an example in the code instead, and expressing it with a specific design and implementation, you shift the discussion from abstract to concrete. You focus on this code, in this case. Once the concept materializes into a real, readable thing on your monitors, you can make context-aware decisions. It’s a lot easier to reason about code you can see.</p>
<p>It’s okay to argue (well, “deliberate” is what we like to call it) for a few minutes. But you must agree upon specific cases if you want to make any real progress. The best specific case for you to work on is the one you’re currently on the hook to deliver. </p>
<p>Allow no more than 5-10 minutes to deliberate in the abstract. Then go to the code for an answer. This prevents a lot of conversation from being wasted, keeps us focused on our work, and drives us to make agreements quickly. </p>
<h3>R: Rotate regularly and rapidly</h3>
<p>The most common rookie mistake is not switching drivers often enough. When we walk in on teams trying mobbing on their own, we often see the anti-pattern of the stagnant driver: One developer, typically the team lead, commands the driver chair for an hour and more. Why? Because they’re the most senior person on the team, and seemingly things will go faster if they do all the work. Meanwhile everyone else sits back and supposedly soaks up the learning.</p>
<p>We’ll be blunt: Stagnant drivers usually turn mobbing into a snoozefest. We tend to refer to this pattern as the “worker / rester” pattern, or when it’s not quite as awful we may call it “worker / watcher.” </p>
<p>Instead, make the session lively and keep everyone engaged by rapidly rotating. A five-minute rotation seems nuts--what can one person possibly accomplish in five minutes? You’ll find out, however, that short rotations:</p>
<ul>
<li>Keep everyone engaged and focused on the task at hand</li>
<li>Avoid dominance by the senior devs</li>
<li>Minimize the sweat-factor of being in the hot seat</li>
</ul>
<p>Driver sessions of 5-10 minutes seem perfectly in line with our recommendation for deliberation limits.</p>
<p>Rapid rotations are a must for successful mob-programming! Download Mobster now and use it.</p>
<h3> T: Track waste and other learnings </h3>
<p>When asked “what is mob programming good for?,” most people will list shared learning as the primary benefit.</p>
<p>How do they know? Are we sure that teams are learning, sharing, and participating together when mob programming?</p>
<p>Agile teams have long used Big Visible Charts (BVCs) for making their work visible and transparent to anyone who visits the team space. When mob programming, we will often track our daily learnings or questions on a flip chart.</p>
<p>This has a number of advantages:</p>
<ul>
<li>When someone records an item, you are aware that learning has happened.</li>
<li>You can count items on the chart as evidence of the efficacy of mob programming.</li>
<li>You can bring charts to the retrospective and reflect on knowledge acquired and problems solved.</li>
<li>You’ll have reminders of tricks you learned yesterday or the day before, easily and eventually forgotten otherwise.</li>
<li>People not present when the learning took place can review the new additions and ask questions.</li>
<li>When problems are listed on the BVC, their presence will prompt you to solve them.</li>
<li>Sometimes you become aware of blind spots or knowledge deficiencies, and are reminded by the chart to put some time into research.</li>
<li>You can visit teams that similarly radiate their learnings in order to glean new ideas. This can spice up community-of-practice meetings (guilds, scrum-of-scrums, etc).</li>
</ul>
<p>Tracking knowledge acquisition isn’t a universal practice for mob-programming teams, but we’ve found it so helpful that we recommend it for all teams, especially those new to the practice.</p>
<h3>I: Intermittent breaks</h3>
<p>When things aren’t going well in a mob programming session (yes, it will happen), sometimes the best thing you can do is get up and walk away for ten minutes (or even better--walk for ten minutes, perhaps around the building). Sometimes the best thing is for the whole team to stand up and disperse. Clear heads will often return a better solution to the mob.</p>
<p>When things are going well in a mob programming session, it’s easy to press each other to keep going. We’ve been in mob sessions that might have lasted all day without a break if we didn’t insist on one.</p>
<p>Humans need breaks, and they work better with them. Feeling sleepy, distracted, sluggish, frustrated, stupid?</p>
<p>Get up and take a short walk from time to time. Don’t worry, the mob will survive in your absence! </p>
<p>Alternatively, take regular whole-mob breaks at least once every 90 minutes, and don’t let your teammates talk you out of them (trust us, it’s easy to do). Mobster will help force the issue.</p>
<h3>E: Express intent</h3>
<p>The goal of a navigator is to provide direction and guidance, not to micromanage: “Turn left here; now put your foot on the gas. Brake! OK, ease out slowly…” Or, “Put your cursor here, now right-click, pick the third option. Okay, now click here. Now go to the other file, and click here. Right-click, I mean. Yeah, now pick the middle option, then type OJK… select the third word.”</p>
<p>Back-seat drivers frustrate everyone--driver and rest of the mob included. Rote directions are hard to follow. The driver and others in the mob find it impossible to correct or interject any ideas because they’re completely caught up in trying to figure out what the hell you’re asking the driver to do.</p>
<p>Instead, provide direction. “Let’s create a test that verifies the system rejects adding duplicate requests.” The driver can ask for guidance on specifics as needed.</p>
<p>Yes, at times the driver will need to ask for precise steps. Consider this driver’s ed, something that all drivers will experience intermittently. We want everyone to improve, so listen and learn to ingrain the new bits of learning that will come frequently. Mob nirvana is when we’ve learned to minimize detailed directions and focus instead on relating end goals.</p>
<p>If mob programming is (in Josh Kerievsky’s words) a continuous integration of ideas, then expressing actions rather than intent is the primitive obsession of mob-programming. </p>
<p>Don’t leave your partners guessing.</p>
<h3>D: Driver doesn't navigate</h3>
<p>The other most common mob-programming anti-pattern (along with stagnant drivers) is dominant drivers--people who “run away” with the code while at the keyboard. A heads-down driver choosing where to go and how to get there is going to bore the tears out of the mob--they’ll eventually fall asleep (sometimes literally) in the back seat. </p>
<p>More importantly, the mob will learn little from the driver and the driver will learn nothing from the mob.</p>
<p>To prevent runaway drivers, follow the rule of strong-style pairing: The driver isn’t allowed to decide where to go next. Instead, the mob makes navigation choices and relays them to the driver. The driver’s job is to listen and translate these directions into code. A driver who wants to head in a different direction must relinquish the driver’s seat.</p>
<p>It’s not hard for drivers to get carried away and start to “run away,” but they’ll usually not take offense if you remind them of the rule. Often they’ll even admit their breach and ask if they should just revert.</p>
<p>Newbies (new programmers, new team members, people new to the system) of all stripes are naturally intimidated by the prospect of being in the hot seat. Strong-style pairing minimizes the fear factor: The newbie isn’t expected to know what to do, and the mob is always more than willing to help them shift into higher gears.</p>
<p>Not only does strong-style pairing improve the capabilities of everyone on the team, it helps them improve their ability to communicate ideas about code and design.</p>
<p>Despite the name, mobs aren’t free-for-alls. A mob session is best treated as a focused journey that you keep on course by following our tips.</p>
<h4>Sources</h4>
<p>Industrial Logic. “A Few Tips for Mob Programming,” https://www.industriallogic.com/blog/a-few-tips-for-mob-programming/ </p>
<p>Langr, Jeff. “Two Rules for MobbingSuccess,” http://www.ranorex.com/blog/two-rules-mobbing-success/</p>
Jeff Langrhttp://www.blogger.com/profile/10499693020049210645noreply@blogger.com0tag:blogger.com,1999:blog-1697388841986104302.post-59893424155102860872016-08-16T21:20:00.001-05:002016-08-16T21:20:23.107-05:00Why Test-After Coverage Is Lower<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7MmT0X2BxghV1aQgu7A7O3wcgmJtiItFe_S9_AQ1JdsY01MrtzkXU15E5WTKJbOyG7aBQjMcbXjQixbH5MGI04siPevec2tCjLoykAgsEx5PK2GziMBc90FJdbrjiWvRlbZO4ng8QepfO/s1600/card.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7MmT0X2BxghV1aQgu7A7O3wcgmJtiItFe_S9_AQ1JdsY01MrtzkXU15E5WTKJbOyG7aBQjMcbXjQixbH5MGI04siPevec2tCjLoykAgsEx5PK2GziMBc90FJdbrjiWvRlbZO4ng8QepfO/s320/card.png" width="320" /></a></div>
<div>
<br /></div>
<div>
Unit testing after the fact? We do just enough test-after development (TAD) to please our manager, and no more.</div>
<div>
<b><br /></b></div>
<div>
<b>Just Ship It!</b> Once the business realizes they have product in hand, there's always pressure to move on to the next feature. <br /></div>
<div>
Invariably, any "after the fact" process is given short shrift. This is why post-development code reviews don't reveal deep problems, and even if they do, we rarely go back and make the costly changes needed to truly fix the problems. This is why after-the-fact testers are always getting squeezed out of the narrow space between "done" software and delivery. </div>
<div>
<br /></div>
<div>
<b>My Sh*t Don't Stink</b>. I just wrote my code, and it works. I know so because I deployed it, cranked up the server, and ran through the application to verify it. Why would I waste any more time building unit tests that I hope to never look at again?</div>
<div>
<br /></div>
<div>
<b>That Can't Possibly Break</b>. Well, two-line methods and such. I can glance at those and think they look good. Lazy initialization? That couldn't break, could it?</div>
<div>
<br /></div>
<div>
<b>That's Gonna Be a Pain.</b> Holy crud, that's a 100-line method with 3+ levels of nesting, complex conditionals, and exceptional conditions (test those? you're kidding). It's going to take me longer to write a reasonably comprehensive set of tests than it took to write the method in the first place.<br /><br />Worse, the method has numerous private dependencies on code that makes database or service calls. Or just dependencies that have nothing to do with what I'm testing. Just today I tried to instantiate a class, but failed because of a class two inheritance levels up with a dependency on another object being properly instantiated and configured. Figuring out how to test that is going to be a nightmare that eats up a lot of time.</div>
<div>
<br /></div>
<div>
Code written without immediate and constant consideration for how to unit test it is going to be a lot harder to test. Most of us punt when efforts become too daunting.</div>
<div>
---</div>
<div>
I hear that TAD coverage typically gets up to about 75% on average. Closer inspection reveals that this number is usually all over the map: 82% in one class, 38% in another, and so on. Even closer inspection reveals that classes with a coverage percent of, say, 38, often contain the riskiest (most complex) code. Why? Because they're the hardest to test.<br /><br />If I was allowed to only do TAD and not TDD, I'd scrap it and invest more in end-to-end testing.<br /><br />-- Jeff</div>
Jeff Langrhttp://www.blogger.com/profile/10499693020049210645noreply@blogger.com0tag:blogger.com,1999:blog-1697388841986104302.post-50521778863972507352015-02-22T13:25:00.000-06:002015-02-22T13:26:21.009-06:00Top Ten Agile Dangers<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyiQUez1IAtMPPGF5LFUKWI_00NluahXuXhdznJ13ijRPzO5E-dBCVDllf2V8Zh1hZMypji-1668tcgwdKh0wmVxyLf_BAQ32FIIXPY5f9mMNLkbyMB25gjk_AK_XAbxhKS9iX_3RstK5s/s1600/card.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyiQUez1IAtMPPGF5LFUKWI_00NluahXuXhdznJ13ijRPzO5E-dBCVDllf2V8Zh1hZMypji-1668tcgwdKh0wmVxyLf_BAQ32FIIXPY5f9mMNLkbyMB25gjk_AK_XAbxhKS9iX_3RstK5s/s1600/card.png" height="300" width="400" /></a></div>
<br />Jeff Langrhttp://www.blogger.com/profile/10499693020049210645noreply@blogger.com0tag:blogger.com,1999:blog-1697388841986104302.post-83070285325544342372013-01-14T11:05:00.002-06:002013-01-14T11:07:05.548-06:00Interview with TimTim had a nice <a href="http://ugtastic.com/interviews/interview-in-a-flash">mini-interview</a> with Michael Hall of <a href="http://ugtastic.com/">UGTastic</a>, who is also (as far as I'm concerned) the public face of the <a href="http://mchenry.softwarecraftsmanship.org/">Software Craftsmen McHenry County</a> in the far north suburbs of Chicago, Il.<br />
<br />
There is a little discussion of Agile In A Flash in there. Enjoy.<br />
<br />Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com0tag:blogger.com,1999:blog-1697388841986104302.post-71915764366382214402013-01-13T14:47:00.001-06:002013-01-13T14:47:27.792-06:00Continuous Improvement In A FlashJeff and I have been busy working independently.<br />
<br />
I borrowed the "brand" but <a href="https://leanpub.com/smtb">Continuous Improvement In A Flash</a> is a whole different kind of work than Agile In A Flash. It is essentially a guide for scrum masters to help them institute continuous improvement. It is a quick exposition of mindset and technique that should help any SM (even a part-time SM). <br />
<br />
I've just made the first public release, and I hope to follow up with changes, expansions, and reductions as time allows.<br />
<br />
I am also starting up a second LeanPub book as the further development of my Use Vim Like A Pro tutorial, which has lost its place on the internet with the closing of my old blog on blogsome.<br />
<br />
We'll keep you up to date with further changes, such as the publication date of Jeff's new book, as time allows.Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com0tag:blogger.com,1999:blog-1697388841986104302.post-14113101089379355092012-07-03T10:22:00.000-05:002012-07-03T10:42:54.035-05:00Premature Passes: Why You Might Be Getting Green on Red<div class="separator" style="clear: both; text-align: center;">
<a href="http://langrsoft.com/ftp/greenonred.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://langrsoft.com/ftp/greenonred.png" width="320" /></a></div>
<br />
<br />
<a href="http://agileinaflash.blogspot.com/2009/02/red-green-refactor.html">Red, green, refactor.</a> The first step in the test-driven development (TDD) cycle is to ensure that your newly-written test fails <i>before</i> you try to write the code to make it pass. But why expend the effort and waste the time to run the tests? If you're following TDD, you write each new test for code that doesn't yet exist, and so it shouldn't pass.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhazi3TWEgA_AxbFOjRKtmWJNoX25z9uR5K43SB4oUSQNyumIGZXWvpQT-zJo5YrHUivf7oOZTAsepsjJP8QarnyCvzK0DwZDinQMf13AcCvd8qnFshnTe4wR6IMhMQpznVj103dFEYHkSv/s400/06_Red_Green_Refactor.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="189" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhazi3TWEgA_AxbFOjRKtmWJNoX25z9uR5K43SB4oUSQNyumIGZXWvpQT-zJo5YrHUivf7oOZTAsepsjJP8QarnyCvzK0DwZDinQMf13AcCvd8qnFshnTe4wR6IMhMQpznVj103dFEYHkSv/s320/06_Red_Green_Refactor.JPG" width="320" /></a></div>
But reality says it will happen--you will undoubtedly get a green bar when you expect a red bar from time to time. (We call this occurrence a <i>premature pass</i>.) <span style="background-color: white;">Understanding one of the many reasons why you got a premature pass might help save you precious time.</span><br />
<ul>
<li><span style="background-color: white;"><b>Running the wrong tests</b>. This smack-your-forehead event occurs when you think you were including your new test in the run, but were not, for one of myriad reasons. Maybe you forgot to compile it, link in the new test, ran the wrong suite, disabled the new test, filtered it out, or coded it improperly so that the tool didn't recognize it as a legitimate test. <i>Suggestion: Always know your current test count, and ensure that your new test causes it to increment</i>.</span></li>
<li><span style="background-color: white;"><b>Testing the wrong code</b>. You might have a premature pass for some of the same reasons as "running the wrong tests," such as failure to compile (in which case the "wrong code" that you're running is the last compiled version). Perhaps the build failed and you thought it passed, or your classpath is picking up a different version. More insidiously, if you're mucking with test doubles, your test might not be exercising the class implementation that you think it is (polymorphism can be a tricky beast). <i>Suggestion: Throw an exception as the first line of code you think you're hitting, and re-run the tests.</i></span></li>
<li><span style="background-color: white;"><b>Unfortunate test specification</b>. Sometimes you mistakenly assert the wrong thing, and it happens to match what the system currently does. I recently coded an <code>assertTrue</code> where I meant <code>assertFalse</code>, and spent a few minutes scratching my head when the test passed. <i>Suggestion: Re-read (or have someone else read) your test to ensure it specifies the proper behavior.</i></span></li>
<li><span style="background-color: white;"><b>Invalid assumptions about the system</b>. If you get a premature pass, you know your test is recognized and it's exercising the right code, and you've re-read the test... perhaps the behavior already exists in the system. Your test assumed that the behavior wasn't in the system, and following the process of TDD proved your assumption wrong. <i>Suggestion: Stop and analyze your system, perhaps adding <a href="http://agileinaflash.blogspot.com/2009/02/writing-characterization-tests.html">characterization tests</a>, to fully understand how it behaves.</i></span></li>
<li><span style="background-color: white;"><b>Suboptimal test order</b>. As you are test-driving a solution, you're attempting to take the smallest possible incremental steps to grow behavior. Sometimes you'll choose a less-than-optimal sequence. You subsequently get a premature pass because the prior implementation unavoidably grew out a more robust solution than desired. <i>Suggestions: Consider starting over and seeking a different sequence with smaller increments. Try to apply <a href="http://cleancoder.posterous.com/the-transformation-priority-premise">Uncle Bob's Transformation Priority Premise (TPP)</a>.</i></span></li>
<li><span style="background-color: white;"><b>Linked production code</b>. If you are attempting to devise an API to be consumed by multiple clients, you'll often introduce convenience methods such as <code>isEmpty</code> (which inquires about the size to determine its answer). These convenience methods necessarily duplicate code. If you try to assert against <code>isEmpty</code> every time you assert against size, you'll get premature passes. <i>Suggestions: Create tests that document the link from the convenience method to the core functionality, demonstrating them. Or combine the related assertions into a single custom assertion (or helper method).</i></span></li>
<li><span style="background-color: white;"><b>Overcoding</b>. A different form of "invalid assumptions about the system," you overcode when you supply more of an implementation than necessary while test-driving. This is a hard lesson of TDD--to supply no more code or data structure than necessary when getting a test to pass. <i>Suggestion: Hard lessons are best learned with dramatic solutions. Discard your bloated solution and try again. It'll be better, we promise.</i></span></li>
<li><span style="background-color: white;"><b>Testing for confidence</b>. On occasion, you'll know when you think a test will generate a premature pass. There's nothing wrong with writing a couple additional tests: "I wonder if it works for this edge case," particularly if those tests give you confidence, but technically you have stepped outside the realm of TDD and moved into the realm of <a href="http://agileinaflash.blogspot.com/2009/02/why-pout-aka-tad-sucks.html">TAD</a> (test-after development). <i>Suggestions: Don't hesitate to write more tests to give you confidence, but you should generally have a good idea of whether they will pass or fail before you run them.</i></span></li>
</ul>
<span style="background-color: white;">Two key things to remember:</span><br />
<div>
<ul>
<li><span style="background-color: white;"><b><i>Never skip running the tests to ensure you get a red bar.</i></b></span></li>
<li><span style="background-color: white;"><b><i>Pause and think any time you get a premature pass.</i></b></span></li>
</ul>
</div>Jeff Langrhttp://www.blogger.com/profile/10499693020049210645noreply@blogger.com0tag:blogger.com,1999:blog-1697388841986104302.post-55814706945251428682012-06-26T06:00:00.000-05:002012-06-26T06:00:09.926-05:00Simplify Design With Zero, One, Many<div class="separator" style="clear: both; text-align: center;">
<a href="http://langrsoft.com/ftp/zom.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://langrsoft.com/ftp/zom.png" width="320" /></a></div>
<br />
Programmers have to consider cardinality in data. For instance, a simple mailing list program may need to deal with people having multiple addresses, or multiple people at the same address. <span style="background-color: white;">Likewise, we may have a number of alternative implementations of an algorithm. Perhaps the system can send an email, or fax a pdf, or send paper mail, or SMS, or MMS, or post a Facebook message. It's all the same business, just different delivery means.</span><br />
<br />
Non-programmers don't always understand the significance of these numbers:<br />
<br />
Analyst: <i>"Customers rarely use that feature, so it shouldn't be hard to code."</i><br />
<i><br /></i><br />
Program features are rather existential--they either have to be written or they don't. "Simplicity" is largely a matter of how few decisions the code has to make, and not how often it is executed.<br />
<div>
<br /></div>
<br />
<b>The Rule of Zero: No Superfluous Parts</b><br />
<i>We have no unneeded or superfluous constructs in our system.</i><br />
<ul>
<li>Building to immediate, current needs <a href="http://agileinaflash.blogspot.com/2009/04/four-options-for-agile-projects.html">keeps our options open</a> for future work. If we need some bit of code later, we can build it later with better tests and more immediate value. </li>
<li>Likewise, if we no longer need a component or method, we should delete it now. Don't worry, you can retrieve anything you delete from version control or even rewrite it (often faster and better than before).</li>
</ul>
<h4>
The Rule of One: Occam's Razor Applied To Software<br /><i style="font-weight: normal;">If we only need one right now, we code as if one is all there will ever be.</i></h4>
<ul>
<li>We've learned (the hard way!) that code needs to be <a href="http://agileinaflash.blogspot.com/2010/02/seven-code-virtues.html">unique</a>. That part of the rule is obvious, but sometimes we don't apply "so far" to the rule. Thinking that you might need more than one in a week, tomorrow, or even in an hour isn't enough reason to complicate the solution. If we have a single method of payment today, but we might have many in the future, we still want to treat the system as if there were only going to be one.</li>
<li>Future-proofing done now (see the "<a href="http://agileinaflash.blogspot.com/2009/04/four-options-for-agile-projects.html">options</a>" card) gets in the way of simply making the code work. The primary goal is to have <a href="http://agileinaflash.blogspot.com/2010/02/seven-code-virtues.html">working code</a> immediately. </li>
<li>When we had originally written code with multiple classes and we later eliminate all but one, we can often simplify the code by removing the scaffolding that made "many" possible. This leaves us with <a href="http://agileinaflash.blogspot.com/2009/02/simple-design.html">No Superfluous Parts</a>, which makes code simple again.</li>
</ul>
<h4>
The Rule of Many: In For a Penny, In For a Pound<br /><i style="font-weight: normal;">Code is simpler when we write it to a general case, not as a large collection of special cases.</i></h4>
<ul>
<li>A list or array may be a better choice than a pile of individual variables--<i>provided the items are treated uniformly</i>. Consider "point0, point1, point2." Exactly three variables, hard-coded into a series of names with number sequences. If they had different meanings, they would likely have been given different names (for instance, X, Y, and Z). What is the clear advantage of saying 'point0' instead of point[0]? </li>
<li>It's usually easier to code for "many" than a fixed non-zero number. For example, a business rule requiring there are exactly three items is easily managed by checking the length of the array, and not so easily managed by coding three discrete conditionals. Iterating over an initialized collection also eliminates the need to do null checking when it contains no elements.</li>
<li>Non-zero numbers greater than one tend to be policy decisions, and likely to change over time.</li>
<li>When several possible algorithms exist to calculate a result we might be tempted to use a type flag and a case statement, but if we find a way to treat implementations uniformly we can code for "many" instead of "five." This helps us recognize and implement useful abstractions, perhaps letting us <a href="http://sourcemaking.com/refactoring/replace-conditional-with-polymorphism">replace case statements with polymorphism</a>. </li>
</ul>
Naturally, these aren't the only simple rules you will ever need. But simple, evolutionary design is well supported by the ZOM rules regardless of programming language, development methodology, or domain.<br />
<br />Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com0tag:blogger.com,1999:blog-1697388841986104302.post-20913128843179459912012-06-05T08:30:00.002-05:002022-05-25T19:41:25.251-05:00The "Flash a Friend" Contest: A Covert Agile Give-Away!If you're reading this blog, you're probably a believer that a good agile process can make a difference. And maybe you've recognized someone on your team, on another team, or even in a different company that you think would benefit from a little covert mentoring.<br />
<br />
We'd like to help! We believe getting these cards in the hands of the right people can make a real difference. We're willing to put that belief in action.<br />
<br />
Here's how it works:<br />
<ul>
<a href="http://langrsoft.com/ftp/olag_small.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img alt="Cover Image For Agile in a Flash..." border="0" src="http://langrsoft.com/ftp/olag_small.jpg" /></a>
<li>Email us at <a href="mailto:AgileInAFlash@mail.com">AgileInAFlash@mail.com</a>, recommending one person who you think should receive a free deck. You don't have to name names, you can say "<i>my boss</i>," "<i>our architect</i>," "<i>my dog,</i>" "<i>my cousin,</i>" etc. You can even name <i>yourself</i>!</li>
<li>Tell us in one short, pithy line why you think that this person/team would benefit from Agile in a Flash. </li>
<li>We'll read the comments and pick our favorites.</li>
<li>If your entry is selected, we will contact you and get the particulars (names, addresses).</li>
<li>The person you recommended gets a deck of Agile in a Flash from us. No note, no card, no explanation. </li>
<li>To thank you for being so helpful, we send a second deck to you!</li>
<li>We'll put the winning comments on a soon-to-be-pubished Agile in a Flash blog entry. (You can choose to be attributed or anonymous.)</li>
</ul>
<div>
Deadline for entries: Friday June 15, 1200 MDT</div>Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com2tag:blogger.com,1999:blog-1697388841986104302.post-10516951143927900392012-05-15T05:45:00.000-05:002012-05-15T05:45:00.583-05:00Seven Steps to Great Unit Test Names<div class="separator" style="clear: both; text-align: center;">
<a href="http://langrsoft.com/ftp/greatUnitTests.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://langrsoft.com/ftp/greatUnitTests.png" width="320" /></a></div>
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;"><br /></span></span><br />
<b><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></b><br />
<b><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">You can find many good blog posts on <a href="http://thinkoftheepsilons.blogspot.com/2012/04/how-do-you-name-your-tests.html"><i>what</i> to name your tests</a>. We present instead an appropriate strategy for <i>when and how</i> to think about test naming.</span></b><br />
<ol>
<li><b id="internal-source-marker_0.9314969882834703"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">Don't sweat the initial name.</span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> A bit of thought about what you're testing is essential, but don't expend much time on the name yet. Type in a name, quickly. Use <a href="http://agileinaflash.blogspot.com/2009/03/arrange-act-assert.html">AAA</a> or <a href="http://blog.gdinwiddie.com/2012/01/23/contemplating-given-when-then/">Given-When-Then</a> to help derive one. It might be terrible--we've named tests "DoesSomething" before we knew exactly what they needed to accomplish. We've also written extensively long test names to capture a spewn-out train of thought. No worries--you'll revisit the name soon enough.</span></b></li>
<li><b id="internal-source-marker_0.9314969882834703"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">Write the test.</span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> As you design the test, you'll figure out precisely what the test needs to do. You pretty much have to, otherwise you aren't getting past this step! :-) When the test fails, look at the combination of the fixture name, test method name, and assertion message. These three should (eventually) uniquely and clearly describe the intent of the test. Make any obvious corrections, like removing redundancy or improving the assertion message. Don't agonize about the name yet; it's still early in the process. </span></b></li>
<li><b id="internal-source-marker_0.9314969882834703"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">Get it to pass.</span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> Focus on simply getting the test to pass. This is not the time to worry about the test name. If you have to wait any significant time for your test run, start thinking about a more appropriate name for the test (see step 4).</span></b></li>
<li><b id="internal-source-marker_0.9314969882834703"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">Rename based on content.</span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> Once a test works, you <i>must</i> <b id="internal-source-marker_0.9314969882834703" style="font-family: 'Times New Roman'; font-size: medium; white-space: normal;"><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><b id="internal-source-marker_0.9314969882834703" style="font-family: 'Times New Roman'; font-size: medium; white-space: normal;"><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">revisit its name. </span></b>Re-read the test. <b id="internal-source-marker_0.9314969882834703" style="font-family: 'Times New Roman'; font-size: medium; white-space: normal;"><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Now that you know what it does, you should find it much easier to come up with a concise name. </span></b>If you had an overly verbose test name, <b id="internal-source-marker_0.9314969882834703" style="font-family: 'Times New Roman'; font-size: medium; white-space: normal;"><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">you should be able to eliminate some noise words by using more abstract or simpler terms</span></b>. You may need to look at other tests or talk to someone to make sure you're using appropriate terms from the domain language.</span></b></span></b></li>
<li><b id="internal-source-marker_0.9314969882834703"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">Rename based on a holistic fixture view.</span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> In Eclipse, for example, you can do a ctrl-O to bring up an outline view showing the names for all related tests. However you review all the test names, make sure your new test's name is consistent with the others. The test is a member of a collection, so consider the collection as a system of names.</span></b></li>
<li><b style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">Rename and reorganize other tests as appropriate. </b><span style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">Often you'll question the names of the other tests. Take a few moments to improve them, with particular focus given to the impact of the new test's name. You might also recognize the need to split the current fixture into multiple fixtures.</span></li>
<li><b style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">Reconsider the name with each revisit.</b><span style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"> <b id="internal-source-marker_0.9314969882834703" style="font-family: 'Times New Roman'; font-size: medium; white-space: normal;"><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Unit tests can act as great living documentation -- but only if intentionally written as such. </span></b>Try to use the tests as your first and best understanding of how a class behaves. The first thing you should do when challenged with a code change is read the related tests. The second thing you should do is rename any unclear test names.</span></li>
</ol>
<div>
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;">The test names you choose may seem wonderful and clear to you, but you know what you intended when you wrote them. They might not be nearly as meaningful to someone who wasn't involved with the initial test-writing effort. Make sure you have some form of review to vet the test names. An uninvolved developer should be able to understand the test as a stand-alone artifact - not having to consult with the test's author (you). If pair programming, it's still wise to get a third set of eyes on the test names before integrating.</span></span></div>
<br />
<span style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">Unit tests require a significant investment of effort, but </span><b><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">renaming a test is cheap and safe. Don’t resist incrementally driving toward the best name possible. </span></b><span style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">Continuous renaming of tests is an easy way of helping ensure that your investment will return appropriate value.</span><br />
<span style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"><br /></span>Jeff Langrhttp://www.blogger.com/profile/10499693020049210645noreply@blogger.com9tag:blogger.com,1999:blog-1697388841986104302.post-59653728013956927392012-04-25T08:53:00.001-05:002022-05-25T19:50:15.786-05:00Is Your Unit Test Isolated?<div style="background-color: transparent;">
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;"><br /></span></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://langrsoft.com/ftp/isolatedTests.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://langrsoft.com/ftp/isolatedTests.png" width="320" /></a></div>
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;"><br /></span></span><br />
<b><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">(Kudos to the great software guru </span><a href="http://www.jefffoxworthy.com/"><span style="color: #1155cc; font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Jeff Foxworthy</span></a><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> for the card phrasing.)</span></b><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">An effective unit test should follow the </span><a href="http://agileinaflash.blogspot.com/2009/02/first.html" style="font-weight: bold;"><span style="color: #1155cc; font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">FIRST</span></a><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> prescriptions in order to verify a small piece of code logic (</span><span style="font-family: Arial; font-size: 15px; font-style: italic; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">aka</span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> “unit”). But what exactly does it mean for a unit test to be </span><span style="font-family: Arial; font-size: 15px; font-style: italic; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;">I</span><span style="font-family: Arial; font-size: 15px; font-style: italic; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> for </span><span style="font-family: Arial; font-size: 15px; font-style: italic; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;">I</span><span style="font-family: Arial; font-size: 15px; font-style: italic; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">solated</span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">? Simply put, an isolated test has only a single reason to fail.</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">If you see these symptoms, you may have an isolation problem:</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;">Can't run concurrently with any other. </span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">If your test can’t run at the same time as another, then they share a runtime environment. This occurs most often when your test uses global, static, or external data.</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">A quick fix: Find code that uses shared data and extract it to a function that can replaced with a test double. In some cases, doing so might be a stopgap measure suggesting the need for redesign.</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;">Relies on any other test in any way. </span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Should you reuse the context created by another test? For example, your unit test could assume a first test added an object into the system (a “</span><a href="http://blog.james-carr.org/2006/11/03/tdd-anti-patterns/" style="font-weight: bold;"><span style="color: #1155cc; font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">generous leftover</span></a><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">”). Creating test inter-dependencies is a recipe for massive headaches, however. Failing tests will trigger wasteful efforts to track down the problem source. Your time to understand what’s going on in any given test will also increase.</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Unit tests should assume a clean slate and re-create their own context, never depending on an order of execution. Common context creation can be factored to setup or a helper method (which can then be more easily test-doubled if necessary). You might use your test framework's randomizer mode (e.g. googletest’s </span><span style="background-color: #eeeeee; color: #444444; font-family: Consolas; font-size: 13px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">--gtest_shuffle)</span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> to pinpoint tests that either deliberately or accidentally depend on leftovers.</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">You might counter that having to re-execute the common setup twice is wasteful, and will slow your test run. Our independent </span><span style="font-family: Arial; font-size: 15px; font-style: italic; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">unit</span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> tests are ultra-fast, however, and so this is never a real problem. See the next bullet.</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;">Relies on any external service. </span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Your test may rely upon a database, a web service, a shared file system, a hardware component, or a human being who is expected to operate a simulator or UI element. Of these, the reliance on a human is the most troublesome.</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">SSDD (same solution different day): Extract methods that interact with the external system, perhaps into a new class, and mock it. </span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;">Requires a special environment. </span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">“It worked on my machine!” A </span><a href="http://blog.james-carr.org/2006/11/03/tdd-anti-patterns/" style="font-weight: bold;"><span style="color: #1155cc; font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Local Hero</span></a><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> arises when you write tests for a specific environment, and is a sub-case of </span><span style="font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;">Relies on any external service</span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">. Usually you uncover a Local Hero the first time you commit your code and it fails during the CI build or on your neighbor’s dev box.</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">The problem is often a file or system setting, but you can also create problems with local configuration or database schema changes. Once the problem arises, it’s usually not too hard to diagnose on the machine where the test fails.</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">There are two basic mitigation strategies:</span><br />
<ol style="margin-bottom: 0pt; margin-top: 0pt;"><b>
<li style="font-family: Arial; font-size: 15px; font-weight: normal; list-style-type: decimal; vertical-align: baseline;"><span style="vertical-align: baseline; white-space: pre-wrap;">Check in more often, which might help surface the problem sooner</span></li>
<li style="font-family: Arial; font-size: 15px; font-weight: normal; list-style-type: decimal; vertical-align: baseline;"><span style="vertical-align: baseline; white-space: pre-wrap;">Periodically wipe out and reinstall (“pave”) your development environment</span></li>
</b></ol>
<b>
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br /><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">Can’t tell you why it fails. </span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">A fragile test has several ways it might fail, in which case it is hard to make it produce a meaningful error message. Good tests are highly communicative and terse. By looking at the name of the test class, the name of the method, and the test output, you should know what the problem is</span><span style="font-family: 'Courier New'; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">:</span></b></div>
<div style="background-color: transparent;">
<b><span style="font-family: 'Courier New'; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> CSVFileHandling.ShouldToleratedEmbeddedQuotes -</span><br /><span style="font-family: 'Courier New'; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> Expected "Isn't that grand" but result was "Isn"</span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br /><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br /><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">You shouldn't normally need to dig through setup code, or worse, production code, to determine why your test failed.</span><br /><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br /><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">The more of the SUT exercised by your test, the more reasons that code can fail and the harder it is to craft a meaningful message. Try focusing your test on a smaller part of the system. Ask yourself “what am I really trying to test here?”</span></b><br />
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;"><br /></span></span><br />
<b><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Your test might be failing because it made a bad assumption. A precondition assertion might be prudent if you are at all uncertain of your test’s current context.</span></b><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<b><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></b><br />
<span style="font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;">Mocks indirect collaborators. </span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">If you are testing public behavior exposed by object A, and object A interacts with collaborator B, you should only be defining </span><a href="http://agileinaflash.blogspot.com/2010/03/mock-terminology.html" style="font-weight: bold;"><span style="color: #1155cc; font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">test doubles</span></a><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"> for B. If the tests for A involve stubbing of B’s collaborators, however, you’re entering into mock hell.</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Mocks violate encapsulation in a sense, potentially creating tight coupling with implementation details. Implementation detail changes for B shouldn’t break your tests, but they will if your test involves test doubles for B’s collaborators.</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;">Your unit test should require few test doubles and very little preliminary setup. If setup becomes elaborate or fragile, it’s a sign you should split your code into smaller testable units. For a small testable unit, zero or one test doubles should suffice.</span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"></span><span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"><i>In summary, unit tests--which we get most effectively by practicing TDD--are easier to write and maintain the more they are isolated.</i></span></div>Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com2tag:blogger.com,1999:blog-1697388841986104302.post-72251505158560643422011-11-30T12:17:00.072-06:002011-12-01T11:49:39.705-06:00Test Abstraction Smells<div class="separator" style="clear: both; text-align: center;">
<a href="http://langrsoft.com/ftp/testAbstractionSmells.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="http://langrsoft.com/ftp/testAbstractionSmells.png" width="400" /></a></div>
<br />
In our article <a href="http://pragprog.com/magazines/2011-04/test-abstraction">Test Abstraction: Eight Techniques to Improve Your Tests</a> (published by PragPub), we whittled down a convoluted, messy test into a few concise and expressive test methods, using this set of smells as a guide. We improved the abstraction of this messy test by emphasizing its key parts and de-emphasizing its irrelevant details.<br />
<br />
Stripped down, the "goodness" of a test is largely a matter of how quickly these questions can be answered:<br />
<ul>
<li>What's the point of this test?</li>
<li>Why is the assertion expecting this particular answer?</li>
<li>Why did this test just fail?</li>
</ul>
That's a nice short-form summary, but it is descriptive rather than prescriptive. In the Pragmatic Bookshelf article, a real-world code example was used to painstakingly demonstrate the techniques used to improve the clarity of tests by increasing their level of abstraction. Here we provide the "cheat sheet" version:<br />
<ul>
<li><b>Unnecessary test code</b>. Eliminate test constructs that clutter the flow of your tests without imparting relevant meaning. Most of the time, "not null" assertions are extraneous. Similarly, eliminate try/catch blocks from your tests (in all but negative-case tests themselves).</li>
<li><b>Missing abstractions</b>. Are you exposing several lines of implementation detail to express test set-up (or verification) that represents a single concept? Think in terms of reading a test: "Ok, it's adding a new student to the system. Fine. Then it's creating an empty list, and then adding A to that list, then B, and ..., and then that list is then used to compare against the expected grades for the student." The list construction is ugly exposed detail. Reconstruct the code so that your reader, in one glance, can digest a <em>single</em> line that says "ensure the student's expected grades are A, A, B, B, and C."</li>
<li><b>Irrelevant data</b>. "Say, why does that test pass the value '2' to the SUT? It looks like they pass in a session object, too... does it require that or not?" Every piece of data shown in the test that bears no weight on its outcome is clutter that your reader must wade through and inspect. "Is that value of '2' the reason we get output of '42'?" Well, no, it's not. Take it out, hide it, make it more abstract! (For example, we'll at times use constant names like ARBITRARY_CHARGE_AMOUNT.)</li>
<li><b>Bloated construction</b>. It may take a bit of setup to get your SUT in the state needed for the test to run, but if it's not relevant to core test understanding, move the clutter out. Excessive setup is a design smell, showing that the code being tested needs rework. Don't cope with the problem by leaving extensive setup in your test, but tackle the problem by reworking the code as soon as you have reasonable test coverage. Of course, the problem of untestable code is largely eliminated through the use of TDD.</li>
<li><b>Irrelevant details</b>. Is every step of the test really needed? For example, suppose your operational system requires the presence of a global session object, pre-populated with a few things. You may find that you can't even execute your unit test without having it similarly populate the session object. For most tests, however, the details of populating the session object have nothing to do with the goal of the test. There are usually better ways to design the code unit, and if you can't change your design to use one of those ways, you should at least bury the irrelevant details.</li>
<li><b>Multiple assertions</b>. A well-abstracted unit test represents one case: "If I do <em>this</em> stuff, I observe <em>that</em> behavior." Combining several cases muddies the abstraction--which setup/execution concepts are relevant to which resulting behaviors? Which assertion represents the goal of the test case? Most tests with multiple assertions are ripe for splitting into multiple tests. Where it makes sense to keep multiple assertions in a single test, can you at least abstract its multiple assertions into a single helper method?</li>
<li><b>Misleading organization</b>. You can easily organize tests using AAA (Arrange-Act-Assert). Remember that once green, we re-read any given test (as a document of SUT behavior) only infrequently--either when the test unexpectedly fails or when changes need to be made. Being able to clearly separate the initial state (Arrange) from the activity being tested (Act) from the expected result (Assert) will speed the future reader (perhaps yourself in 5 months) on his way. When setup, actions, and assertions are mixed, the test will require more careful study. Spare your team members the chore of repeatedly deciphering your tests down the road--spend the time now to make them clear and obvious.</li>
<li><b>Implicit meaning</b>. It's not all just getting rid of stuff; abstraction requires amplifying essential test elements. Imagine a test that says "apply a fine of 30 cents on a book checked out December 7 and returned December 31." Why those dates? Why that amount? If we challenged you to tell us the rules that govern the outcome of this test, you'd likely get them wrong. A meaningful test would need to describe, in one manner or another, these relevant concepts and elements:<br />
<ul>
<li>books are normally checked out for 21 days</li>
<li>Christmas--a date in the 21-day span following December 7--is a grace day (i.e. no fines are assessed)</li>
<li>The due date is thus December 29</li>
<li>December 31 is two days past the due date</li>
<li>Books are fined 20 cents for the first day late and 10 cents for each additional day.</li>
<li>30c = 20c + 10c</li>
</ul>
(Consider that each of these concepts could represent a separate unit test case, and that this detailed scenario represents more of an end-to-end test case.)<br />
A unit test that requires you to dig through code to discern the reasons for its outcome is wasteful.</li>
</ul>
You could easily survive without our list of test abstraction smells--and figure out on your own what to do about your tests--as long as you keep one thought in your head: "My goal is to ensure that each unit test clearly expresses its intent, and nothing else, to the next person who must understand this system behavior."Jeff Langrhttp://www.blogger.com/profile/10499693020049210645noreply@blogger.com6tag:blogger.com,1999:blog-1697388841986104302.post-89014395741846800022011-11-22T09:24:00.002-06:002011-11-22T09:27:21.903-06:00The 4 Ts of Engaging ManagementTeams self-organize and self-direct, so much of the Taylorist views of what a manager can do seem to not apply at all. What is the working arrangement between an agile team and their manager?<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH1d5gSfqgnpuTXbyAaFXHAaJFmkVcfR-Oul0F9XD3DUsJZIGqGVPjj7BVGp3ZgeTnvmN4m0fw-YrroEE5K4f2c_HnS8CkZDp2Ayn0EzBL3m84JzSmY8gABJtOn62SNYhaHkPlb0spN8I/s1600/Screen+shot+2011-11-22+at+9.21.52+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="235" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH1d5gSfqgnpuTXbyAaFXHAaJFmkVcfR-Oul0F9XD3DUsJZIGqGVPjj7BVGp3ZgeTnvmN4m0fw-YrroEE5K4f2c_HnS8CkZDp2Ayn0EzBL3m84JzSmY8gABJtOn62SNYhaHkPlb0spN8I/s400/Screen+shot+2011-11-22+at+9.21.52+AM.png" width="400" /></a></div><ul><li>Time (schedule) - As a steward of the schedule, a manager needs to know where the teams' effort stands--are they behind or ahead the expected schedule? Does the release need to be delayed or de-scoped? The manager is best positioned to communicate issues and evaluate the larger impact to the organization. When the schedule needs change, we find that your chance of success is greater the earlier the matter is communicated to management. While human nature may lead one to avoid delivering bad news, it is usually better to share problems with people who are in a position to help.</li>
<li>Talent (talent pool) - A manager may bring in additional talent in the form of trainers, consultants, staff augmentation contractors, or new employees. Sometimes having an eLearning course, a visiting expert, or a short-term consultant can make a huge long-term difference in the team's technical proficiency. <br />
A manager may change hiring criteria to bring in the kinds of developers that will help the team to work in a more fluent and productive way. <br />
Likewise, a manager can remove or reassign a team member who just isn't working for the current team. These kinds of issues require coordination with HR and possibly even legal representation, but are a good use of your manager's time. See also <a href="http://en.wikipedia.org/wiki/The_No_Asshole_Rule">Robert Sutton's research</a> on maintaining a productive workplace.</li>
<li>Target (direction, goals) - Agility (strictly defined) is the ability to change direction gracefully. Sometimes a change of technology or target audience can greatly improve a product's chance of being accepted in the market. Additionally, agile teams would rather face failures early when they're inexpensive (fail fast) than have hopeless projects run on until resources are exhausted. Any a significant change in direction, whether cost-saving or value-creating, will need to involve management.</li>
<li>Treasury (funding) - There are times that spending a few hundred or a few thousand dollars can make the difference between the team working fluidly versus struggling and slogging along. Is your biggest need for a distributed build product? A better build server? An alternative testing tool? A local version control server? More reliable intranet? A better library or framework? A minor hardware upgrade? An online training course?</li>
</ul>When a problem can only be solved using one or more of the 4Ts, then it is clearly a management problem. Make use of your manager's sphere of influence to improve the team's chance of success.<br />
<br />
Agile supports the empowered, competent team. The team should own their problems and push forward with solutions and data-based decision-making. On the other hand, a team can hardly be called "resourceful" when their management assets go unused. Remember that the manager is a member of the team, and often managers pride themselves on problem-solving.<br />
<br />
For problems in the gray area where some solutions are purely technical, it may be wise to involve management in triage. You would be surprised how many times teams have struggled with a work-around only to find that a manager would have been happy to solve the problem outright through his contacts and resources.<br />
<br />
In your next retrospective, consider adding solution category called "take it to management." See if it helps your velocity over time.Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com2tag:blogger.com,1999:blog-1697388841986104302.post-14177618734963270072011-10-12T22:42:00.000-05:002011-10-12T22:42:27.877-05:00Management TheaterGreat managers can improve teams in meaningful ways: smoothing the workflow, selecting targets worth hitting, wisely managing budget and schedule, and working to align teams with organizational goals. We have fond memories of great managers, technical or otherwise, who led and mentored us, who helped us reach new plateaus of understanding and productivity.<br />
<br />
We're not talking about those great managers today.<br />
<br />
Instead, we'll discuss a particular form of management dysfunction often seen in development shops. Daniel Pink (in Drive) points out that programming shops are full of people who are motivated by the work and excited to make progress. Intrinsic motivation tends to be quite high, though exceptions exist (see Esther Derby's <a href="http://www.cio.com/article/123406/Stop_Demotivating_Me_"><i>Stop Demotivating Me</i></a>). Most shops face problems with procedure, organization, technological limits, overly ambitious schedules, and shortage of knowledge or practice. Less astute managers don't understand the problems in their teams, and misinterpret these as motivational issues. When the problem is technical, it does not help to attempt solving it through motivation.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzqXS7qOkgolPafiKZtWaJSk3GQ_Aol4CkeU06EQgsB7NoaIePVjloJQXpig_xuGbpppZgt49bSIxtrlYCx5sU0p7Ya8Cbng5O0uZbcqEYin8OXr34b7KrBa8tDAA5fFvZ0pRBoC3MXDw/s1600/ManagementTheater.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzqXS7qOkgolPafiKZtWaJSk3GQ_Aol4CkeU06EQgsB7NoaIePVjloJQXpig_xuGbpppZgt49bSIxtrlYCx5sU0p7Ya8Cbng5O0uZbcqEYin8OXr34b7KrBa8tDAA5fFvZ0pRBoC3MXDw/s320/ManagementTheater.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2kSVRzSvB-rZx2JSxVrMRQFKfwkwp5Q6iJiu6YgzesDUVAZdD9PpKRRytC8nfhypODOeCTRtIQ2C2yhVr7-1Hamn3n-Nm5c-KX6Ww_iNBwp40ec506WW9ZUhFGcY-3nIgdE-m-ekKldo/s1600/Screen+shot+2011-10-03+at+8.49.41+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
<br />
You've probably been a witness to most of these. Just in case they're not obvious:<br />
<ul>
<li><b>Begging</b>: <i>"Please, I just really need you to work harder to get this done. Just this one time."</i></li>
<li><b>Browbeating</b>: <i>"Stop your whining and get it done before I replace you with someone who gives a darn about their job!"</i></li>
<li><b>Cheerleading</b>: <i>"I have faith in you, you're the best! Go Team!"</i></li>
<li><b>Punative Reporting</b>: <i>"I want to see daily status reports! Twice daily!"</i></li>
<li><b>Publicity Stunts</b>: <i>"I want every last one of us in this meeting. We need a show of force!"</i></li>
</ul>
Such motivational tactics tend to be ineffective. To people struggling with difficult organizational and/or technical problems, emotional appeals seem to be a kind of buffoonery. Of course, if the team succeeds despite the management theater, it merely strengthens the causal connection in the manager's mind. By simply not failing, the team locks their manager into a pattern that ensures that all future crises will be met with emotional and ineffective responses.<br />
<br />
We should not be asking how to make managers behave. We should be asking what a team can do to ensure that a manager can provide effective servant leadership. Management theater is not a manager's first choice of action, but rather a tactic of last resource. When a manager does not have sufficient information or timely opportunity to be effective, she must use whatever ethical means remain. Management theater is, therefore, primarily a process smell not of management but of the development team.Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com1tag:blogger.com,1999:blog-1697388841986104302.post-60488752209232367412011-10-03T16:51:00.002-05:002011-10-03T16:51:53.388-05:00Worldwide shortageI'm told that there are shortages of AgileInAFlash, some channels having projected waits of as much as two months for replenishment. <br />
<br />
You can still get AgileInAFlash physical decks at the Pragmatic Programmers site, and you can also pick up electronic copies there to tide you over. The electronic version is not as handy in mentoring settings, but is fine for reading or projecting. <br />
<br />
<br />Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com1tag:blogger.com,1999:blog-1697388841986104302.post-55733875654763661402011-09-16T19:22:00.001-05:002011-09-16T19:22:27.690-05:00Second PrintingThanks to the demand of our readers, Agile In A Flash is going to its second printing only 8 months after its initial release. Thanks to all of you!Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com3tag:blogger.com,1999:blog-1697388841986104302.post-86133074415863785482011-06-10T07:23:00.002-05:002011-06-10T07:23:11.889-05:00Mobile VersionThanks to our hosts at blogger.com, we now have a mobile version, so accessing Agile In A Flash from your mobile device is finally easy and even pleasant.Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com0tag:blogger.com,1999:blog-1697388841986104302.post-91359318459720376882011-05-29T21:07:00.002-05:002011-05-29T21:48:58.999-05:00Doctor Dan's Prescription<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm6xtDMwysVOE6eNJY_caSveucHaQpom6Vb9VmI5I3A9HZjDOhb0tgPZNwhaFbN1yji4nxCeBI-19e9Q9a9pkh57l2iAxsbUgH6ezOCeoenWKK2rMyWup37HpTSvx5w5R1Jr8kZOtgq_k/s1600/GeekDanIterationCard.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="456" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm6xtDMwysVOE6eNJY_caSveucHaQpom6Vb9VmI5I3A9HZjDOhb0tgPZNwhaFbN1yji4nxCeBI-19e9Q9a9pkh57l2iAxsbUgH6ezOCeoenWKK2rMyWup37HpTSvx5w5R1Jr8kZOtgq_k/s640/GeekDanIterationCard.jpg" width="640" /></a></div><br />
<i><a href="http://twitter.com/#!/geekdan/status/73913744027168769">Dr Dan's Prescription:</a> An Agile Flashcard a Day keeps the Fail away...</i><br />
<br />
This photo of card #33 was received via twitter from Daniel Thomas (<a href="http://twitter.com/#!/geekdan">@geekdan</a>) in Brisbane, Australia, complete with the quote above. <br />
<br />
I like how they have a low-tech "frame" for the cards, and a place of honor on the team whiteboard. I hope they get some help, humor, or inspiration from the <a href="http://pragprog.com/titles/olag/agile-in-a-flash">deck</a>.<br />
<br />
Dan tweets a lot of interesting links. Give him a follow.Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com3tag:blogger.com,1999:blog-1697388841986104302.post-61733981263178400582011-05-25T11:28:00.001-05:002011-05-25T11:39:04.458-05:00A Card-Enriched Workspace<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiy2Vi6F-qhbMvor5wc067xrJjz_ME6lvmNCWKLKLYDtLrzPazKJUWBqoxY1vbvh-aogqgcfOGGPaACVjvEOcFABX6F_5PfMML5xveF7tt3iv4g6_0ZmNkS1UqHjOGa_n1W3_EdcspQH0/s1600/BuildAndDeployDesk.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiy2Vi6F-qhbMvor5wc067xrJjz_ME6lvmNCWKLKLYDtLrzPazKJUWBqoxY1vbvh-aogqgcfOGGPaACVjvEOcFABX6F_5PfMML5xveF7tt3iv4g6_0ZmNkS1UqHjOGa_n1W3_EdcspQH0/s640/BuildAndDeployDesk.jpg" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div>Friend of the blog <a href="http://www.buildndeploy.com/">Brian Kelly</a> offers us a glimpse of his workspace. I notice that the books on organizational change are above the card on overcoming organizational obstinance, and that the rest are values and practices cards.<br />
<br />
The new website-only card, <a href="http://agileinaflash.blogspot.com/2011/04/rules-for-distributed-teams.html">Five Rules for Distributed Teams</a>, is shown on the monitor. It was released coincidentally with Lisa Crispin and Nanda Lankalapalli's StickyMinds article on <a href="http://www.stickyminds.com/BetterSoftware/magazine.asp?fn=cifea">Tele-teams</a>. I guess the distributed team meme is in the air.<br />
<br />
Brian is the fellow who has been posting the excellent near-daily meditations on the 52 cards of the official <a href="http://pragprog.com/titles/olag/agile-in-a-flash">Agile In A Flash</a> deck released by Pragmatic Programmers in late January of this year.<br />
<br />
We are very proud, indeed.Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com0tag:blogger.com,1999:blog-1697388841986104302.post-70681848702220397622011-05-24T15:14:00.001-05:002011-05-24T15:15:24.386-05:00Rules for Distributed Teams<div class="separator" style="clear: both; text-align: center;"></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiihGcK5oLinTW3jPyfyNDKNU9fPhC5yv2UxBcVYQoqRpPR_1qt0dBdCYsns5wzXv4Gxo-uuyyIQfNZb3mosidODKe2wE5uEzGOtq1j1_Ry-4V_Pcq6iiva5cE99blDHcRLYncdjk0pB4Q/s1600/Screen+shot+2011-05-24+at+3.12.41+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="380" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiihGcK5oLinTW3jPyfyNDKNU9fPhC5yv2UxBcVYQoqRpPR_1qt0dBdCYsns5wzXv4Gxo-uuyyIQfNZb3mosidODKe2wE5uEzGOtq1j1_Ry-4V_Pcq6iiva5cE99blDHcRLYncdjk0pB4Q/s640/Screen+shot+2011-05-24+at+3.12.41+PM.png" width="640" /></a></div><br />
As the <i>Greatest Agile-In-A-Flash Card Wielding Coaches So Far<sup>(tm)</sup></i>, we're often asked for advice (or drawn into arguments) about how to make agile work with distributed teams. Sometimes it's for more humble reasons, though: We've both been remote members of a team, pair-programming with peers daily. We prescribe the following rules for distributed development:<br />
<ol><li><b>Don't.</b> Traditional organizations should avoid the extra strain, trouble, and expense of remote members without a significant reason. For example, building a better team using remote rockstars might provide some justification, but you might also be better off with a capable, local team that works well together. It's often out of your control, though, and in the hands of a really big boss, bean counter, or entrenched culture. You can make it work: Virtual organizations, startups, and the like find great success using virtual tools, pairing, and non-traditional communication pathways. <em>Make sure you really mean it</em>, because it's not a trouble-free add-on to the way your large organization does things now.<br />
</li>
<li><b>Don't treat remotes as if they were local.</b> Treat your "satellite" developers as competent people with physical limitations. A remote is visually impaired, since he can only see through a web cam, and only when it is on. He cannot see the kanban board, the other side of the camera, and so on. Likewise, he only hears what is said into the microphone and not at all if simultaneous conversations occur. A remote cannot cross the room and talk to people, so interoffice chat (Skype, Jabber, etc) is essential. The local team has to make concessions, repeat conversations, and be the eyes and ears of the remote employees. <em>Do not treat unequal things as equal--accept that there are compromises.</em><br />
</li>
<li><b>Don't treat locals as if they were remote.</b> You certainly can install electronic kanban boards, online agile project management tools, instant messaging, cameras, email, and shared document management so that every local can sit alone in a cubicle or office and behave just like a remote employee. Rather than being empowered, you are all equally limited (see point #2). <em>Never limit so that all are equal. Allow all to rise to greatness.</em> The power of people working closely together in teams is significant (see first bullet above).<br />
</li>
<li><b>Latitude hurts, but longitude kills.</b> Just being remote hurts (see first two bullets), but the complications can be overcome when employees share the same time zone and working hours. The further you move the team across time zones, the fewer common hours they have, and the longer any kind of communication takes to make a round-trip. Agile is predicated on short feedback loops, so 24-hour turn-around is out of the question. <em>If you can't be a single team that works together, create separate agile teams.</em><br />
</li>
<li><b><span class="Apple-style-span" style="font-weight: normal;"><b>Don't always be remote</b></span>.</b> Begin your engagement with a nice long on-site visit. A week is barely enough. Two weeks starts to make it work. Visiting for one week a quarter or even a week a month can keep a feeling of partnership alive. Dealing with difficulties is easy among people who know and respect each other. While constant telepresence (Skype, Twitter, IM, etc.) can minimize the problem of "out-of-sight, out of mind," studies show that <em>distributed team success requires teams with strong interpersonal relationships, built best on face-to-face interaction</em>. The bean counters may not be able to comprehend it, but the investment is well worth the return.</li>
</ol><i>Tim:</i> Would I remote again? In fact, I do most of my Industrial Logic work remote. We are in constant touch with each other and pair frequently. I converse with Joshua Kerievsky more in the course of a week than I have any other "boss" (he'll hate that I used that word!) in my employment history. We even work across time zones. We would work more fluently and frequently side-by-side, but we'd probably not get to work together if we all had to relocate. It is a compromise that has surprisingly good return on investment for us. We also have the advantage that we are all mature agilists; it would be very hard for first-timers. It's hard for me, as I have a tendency to "go dark" sometimes.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><br />
</div><i>Jeff:</i> I enjoyed a year of remote development with a now-defunct company one time zone to the east. Pairing saved it for me. The ability to program daily in (virtually) close quarters with another sharp someone on the team helped me keep an essential connection with them. On the flip side, however, I never felt like I was a true part of that team. I missed out on key conversations away from the camera, and I felt that debating things over the phone was intensely ineffective. You do what you must, but I'd prefer to not be remote again.Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com3tag:blogger.com,1999:blog-1697388841986104302.post-84296610931178340392011-03-22T10:18:00.002-05:002011-03-28T10:25:58.917-05:00Card-Carrying Agile Team<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuTB45mkWCkmasf71n1JfSiTCh0qkj6DhDOwJDyM83D6zF9Afw6c59PE3bZdN0TQ8QbeDtMe7XM3jwNndRNVcDzJ5QYCoOTl1DsPD68rnz9o94lu9Pt7XKfvYkjcSiNCRDRfPWuC3SJuk/s1600/GeoLearning.JPG" imageanchor="1" style="clear:left; float:right;margin-left:1em; margin-bottom:1em"><img border="0" height="214" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuTB45mkWCkmasf71n1JfSiTCh0qkj6DhDOwJDyM83D6zF9Afw6c59PE3bZdN0TQ8QbeDtMe7XM3jwNndRNVcDzJ5QYCoOTl1DsPD68rnz9o94lu9Pt7XKfvYkjcSiNCRDRfPWuC3SJuk/s320/GeoLearning.JPG" /></a></div><span style="font-size: 70%;"><br />
Top row: Chris Freeman, George Sparks, Sudheer Pinna, Scott Splavec, Sreehari Mogallapalli, Matt Poush.<br />
Bottom row: Toran Billups, Ryan Bergman, Andrea de Freitas, and Benoy John<br />
Photographer: Vadim Suvorov<br />
</span><br />
<p>Say hello to the team from Sum Total. Back before acquisition, the company was known as GeoLearning, and Tim was one of the coaches to help with their transition to Agile methods. Later, while working on Agile In A Flash, Jeff and Tim were both employed as remote pair-programming team members. The team has done some remarkable things in just the past three years. </p><p>Vadim (an excellent developer, brilliant guy, friend) reminds me that he is present in this photo as a reflection in the eyes of all the developers who are standing in front of the camera. If this were a TV detective show, you could zoom in and see him clearly.</p>Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com1tag:blogger.com,1999:blog-1697388841986104302.post-74654893334173957872011-03-22T09:56:00.001-05:002011-03-22T09:56:26.200-05:00Card-Carrying Scrum Master<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpeuFvqOMSHEzu1y703Kjg9q9TPeG7oKD3GMGjn2KfEATH40bpVxSGUHofhho3DDRtCzRiaKVQIfeRdM_g6IQRjA5OMGfRm-14Or4tqSyctlJYSxFmPRGts4iG9tQPJgZFRZehzy_6UNQ/s1600/DionNicolaas.jpeg" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"><img border="0" height="166" width="208" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpeuFvqOMSHEzu1y703Kjg9q9TPeG7oKD3GMGjn2KfEATH40bpVxSGUHofhho3DDRtCzRiaKVQIfeRdM_g6IQRjA5OMGfRm-14Or4tqSyctlJYSxFmPRGts4iG9tQPJgZFRZehzy_6UNQ/s320/DionNicolaas.jpeg" /></a></div><br />
Dion Nicolaas (not pictured) displays the Agile in a Flash cards on his desk in the TomTom headquarters in Amsterdam, the Netherlands. Showing a different card each day, he has inspired some colleagues to order their own decks!Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com0tag:blogger.com,1999:blog-1697388841986104302.post-17539310435640058452011-03-18T22:05:00.000-05:002011-03-18T22:05:24.612-05:00Daily MeditationsOn twitter, follow "buildndeploy" (<a href="http://buildndeploy.wordpress.com/">Brian Kelly</a>) for a daily meditation on Agile In A Flash. Well, mostly daily. He has a day job, and we certainly forgive a missed day. Brian is going through a card a day (when possible) and providing an 140char summary of his thoughts. Follow along by card number (use this <a href="http://agileinaflash.blogspot.com/2011/02/agile-in-flash-card-index_23.html">index</a>, or <a href="http://www.pragprog.com/titles/olag/agile-in-a-flash">your own deck</a>) and see what buildndeploy has to say.<br />
<br />
Brian is using our hashtag #agileinaflash, so it is easy to catch up with his prior reflections.Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com0tag:blogger.com,1999:blog-1697388841986104302.post-10321535890876804342011-03-18T21:58:00.000-05:002011-03-18T21:58:41.699-05:00Getting Better (guest blog post)Today we have a short article from our guest blogger <a href="http://johnnosnose.blogspot.com/">Johnno Nolan</a>, who caught our attention in twitter when he said:<br />
<blockquote>Great 2 hear the team talking soft dev. We go through an Agile in a Flash card every am and critique. Can feel devs caring again<br />
</blockquote><br />
Johnno Nolan's story is still in progress, but I felt that tweet was inspirational enough that I invited him to provide a short blog post, and he kindly submitted the following story.<br />
<br />
<blockquote>I've worked here before. We developed with chaos. I left. They persuaded me to come back. They said it would be different. "We can do things a different way. Your way" they said. The chaos would be mine to tame. I accepted and returned.<br />
<br />
The cold reality set in. The team was demotivated, resigned to the current system. Worse, we'd tried to implement 'Getting Better' before (I don't like to use the term Agile) but we'd lack courage and when the main change driver had gone, adoption fell by the wayside. There was mistrust, ignorance of doing things that way and then the team was asked to pick back up where they left off. So there's a been an open dialogue of what's been wrong and we've been focusing on the basics to 'Get Better'.<br />
<br />
And we are.<br />
<br />
I can look back a couple of months and we were not talking, not thinking, just accepting of the norm. Now we're learning together. Sometimes we have bad days, but today was a good one.<br />
<br />
Before our stand-ups meetings we talk about one Agile In A Flash card. They say story cards are a placeholder for a conversation and that's exactly how we use them. We don't always agree with the card but we talk about it and try and understand. The cards provide a focal point.<br />
<br />
Today was really productive, we finished more than we expected. We passed stories back because we didn't think they were good enough. We talked about design. We returned to the cards and talked more about process. For the first time in months we cared and we're proud of what we are doing.<br />
<br />
We're not becoming Agile in a Flash but we're Getting Better Steadily.</blockquote><br />
Jeff and I are receiving several stories every week about how Agile In A Flash is helping teams re-engage with fundamentals. We'll be entertaining other guest bloggers in the future, in addition to providing some fresh content every month.Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com0tag:blogger.com,1999:blog-1697388841986104302.post-67408058213118571272011-03-15T22:39:00.000-05:002011-03-15T22:39:41.158-05:00Card-Carrying Network Weaver<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNO-2GtXDGcd8kV0Cc8xGV1YvD5cVvam4aLd4jCX4nISKK4Vw4iduNY4Ns5muZaQVsrBNSz8_WHU9OyeTTDd1-4xWj1OyNRHNJu_PFKgPHMKtdNV-oDgqXCmUDKrCNEMYWwRwopoDduWI/s1600/IMG_0023.JPG" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"><img border="0" height="240" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNO-2GtXDGcd8kV0Cc8xGV1YvD5cVvam4aLd4jCX4nISKK4Vw4iduNY4Ns5muZaQVsrBNSz8_WHU9OyeTTDd1-4xWj1OyNRHNJu_PFKgPHMKtdNV-oDgqXCmUDKrCNEMYWwRwopoDduWI/s320/IMG_0023.JPG" /></a></div>A welcome to <a href="http://patrickwilsonwelsh.com/">Patrick Wilson-Welsh</a>, seen enjoying his new deck of Agile In A Flash cards at the <a href="http://agileandbeyond.org/">Agile And Beyond</a> gathering in Dearborn, Michigan, where I dare say we had the most interesting table full of people in the entire room. Patrick really wanted these cards. Let us know how they're working out for you!Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com0tag:blogger.com,1999:blog-1697388841986104302.post-52654164549837435262011-03-10T14:24:00.002-06:002011-03-10T14:31:35.486-06:00Card-carrying Agile Tester<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg597WgnQSaNtKsJ8rgXd9tJQ9P43quktkAEfFYKQJOwgjqjdSmB7GC4vs4W8p4FttIkdAi8hhOjwICOB6Tdj-wlgssIWgxAqPf2g5T53XWoNyIusZRz3ejmH7NUI-ekbmxhUDssY7xHQg/s1600/CardCarrying-Crispin.jpg" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"><img border="0" height="239" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg597WgnQSaNtKsJ8rgXd9tJQ9P43quktkAEfFYKQJOwgjqjdSmB7GC4vs4W8p4FttIkdAi8hhOjwICOB6Tdj-wlgssIWgxAqPf2g5T53XWoNyIusZRz3ejmH7NUI-ekbmxhUDssY7xHQg/s320/CardCarrying-Crispin.jpg" /></a></div><br />
This is <a href="http://lisacrispin.com/wordpress/">Lisa Crispin</a>, brilliant Agile tester and <a href="http://lisacrispin.com/wordpress/agile-testing-book-is-now-out/">author</a>, trainer, and early adopter of Agile In A Flash. Here you see her sharing deep testing insights with Jo, Edgar and Chester.<br />
<br />
<span style="font-size:60%;">No animals were harmed or insulted in the making of this blog post.</span>Agileotterhttp://www.blogger.com/profile/10773578598860454277noreply@blogger.com0