<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>patrickwilsonwelsh.com</title>
	<atom:link href="http://patrickwilsonwelsh.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://patrickwilsonwelsh.com</link>
	<description>Agile coding, agile testing, agile coaching, the agile enterprise, and Network Weaving.</description>
	<lastBuildDate>Mon, 06 May 2013 15:27:03 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Selenium 2 / WebDriver: Rockin&#8217; Web App Testing</title>
		<link>http://patrickwilsonwelsh.com/?p=785</link>
		<comments>http://patrickwilsonwelsh.com/?p=785#comments</comments>
		<pubDate>Fri, 12 Apr 2013 15:04:30 +0000</pubDate>
		<dc:creator>patrickwilsonwelsh</dc:creator>
				<category><![CDATA[agile testing]]></category>
		<category><![CDATA[Agility]]></category>
		<category><![CDATA[learning]]></category>
		<category><![CDATA[software craftsmanship]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://patrickwilsonwelsh.com/?p=785</guid>
		<description><![CDATA[Some Context In past posts, I have shared my experiences with you concerning how best to use Selenium 1 RC (Remote Control) to test web applications, based on my experiences helping teams. I even wrote a bit of framework code &#8230; <a href="http://patrickwilsonwelsh.com/?p=785">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h3>Some Context</h3>
<p>In past posts, I have shared <a title="The Ole-Fashioned Se 1 posts" href="http://patrickwilsonwelsh.com/?p=332" target="_blank">my experiences with you</a> concerning how best to use Selenium 1 RC (Remote Control) to test web applications, based on my experiences helping teams. I even wrote a <a title="The old Se 1 framework code, obsolete from Se 2" href="https://github.com/PillarTechnology/SeleniumPatterns/tree/master/selenium-rc-patterns" target="_blank">bit of framework code that I shared with you</a> that had helped me and others minimize total-cost-of-ownership of Se test suites. Back when Se RC was one of the very few games in town for page-traversal and DOM-traversal, I found it tricky but workable. I had to write a lot of framework code to keep Se 1 RC Java code as clean as I needed it to be. But it all worked, and I could keep costs contained.</p>
<p>Soooo, a couple of years ago, when I tried using Se 2, I ran into several problems. And I was skeptical about how in the world three different web testing frameworks (Selenium, HTMLUnit, and WebDriver) could be successfully married. At that time I could not, in good concience, recommend to my clients that they use Se 2 and WebDriver. I was afraid that Se had become <a href="http://www.urbandictionary.com/define.php?term=bloatware" target="_blank">bloatware</a>. I was afraid that the entire tool was nearing end-of-life.</p>
<h3>SE PULLS OUT OF A NOSE DIVE</h3>
<p>Well, I&#8217;ve been using Se 2 and WebDriver (NOT Se 2 RC) recently (in Java), as I work with <a title="Josh K" href="http://www.industriallogic.com/people/joshua" target="_blank">Josh Kerievsky</a> and others at <a title="Some of IL's eLearning offerings. More all the time. " href="http://www.industriallogic.com/elearning/" target="_blank">Industrial Logic</a> to develop a <a title="Driving Selenium Safely" href="http://www.industriallogic.com/driving-selenium-safely/" target="_blank">Selenium 2 album and workshop</a>, and I am here to report to you that as far as I can tell, <a title="Se 2 / WebDriver" href="http://docs.seleniumhq.org/projects/webdriver/" target="_blank">Se 2 / WebDriver</a> rocks. End-to-end testing with tools like Se are still, in my opinion, testing options of last resort, for reasons<a href="http://patrickwilsonwelsh.com/?p=32" target="_blank"> I covered in another old post</a> (in short, <em>NEVER</em> use Se to test <em>ANYTHING</em> you can test more affordably with another automated testing tool). But Se 2 / WebDriver in its current incarnation (I&#8217;m using selenium-server-standalone jar 2.32 as of this writing) is indeed a whole new ballgame, and deserves more attention, more traction, and more respect in the Web App testing world. Let me summarize.</p>
<h3>In With The New</h3>
<p>Se 2 is a marriage of Selenium, <a title="HTMLUnit: Same as it ever was: rockin good" href="http://htmlunit.sourceforge.net/" target="_blank">HTMLUnit</a> (which years and years ago invented the notion of <a title="My own flavor of PageObjects" href="http://patrickwilsonwelsh.com/?p=343" target="_blank">PageObjects</a>, very quietly, simply as a matter of good OO practice), and WebDriver (which is very strong at automating browsers natively, from the operating system, in whatever way a particular browser wants to be controlled by a particular OS version). And in my recent experience, many things that used to burn me about Se RC and Se testing generally are now either way easier, or completely fixed in my current version of Se 2.</p>
<h3><span style="font-size: 10px; letter-spacing: 0.1em; line-height: 2.6em;">The OLD WAY: UGLY SE 1 CODE</span></h3>
<p>Let&#8217;s see an example. Selenium 1 Remote Control (RC), when I asked it questions, returned me primitives: integers, strings, booleans. These primitives are all about &#8220;how to get lots of stuff done, no matter how confusing that is to try to figure out later.&#8221; Here is a classic, old-fashioned, crappy Selenium 1 RC test, with Se calls in-line in the test code (Java in this case):</p><pre class="crayon-plain-tag">public class ClassicFuglySeRCTest
    private static SeleniumServer seleniumServer;
    private static DefaultSelenium selenium;

    protected static final String SELENIUM_SERVER_HOST = "localhost";
    protected static final int SELENIUM_SERVER_PORT = 4444;	

    @Before
    public void setup() {
    	launchSeleniumBrowser();
    }

    @Test
    public void navigatePages() {
    	selenium.open("http://demo.fatfreecrm.com/login");
    	selenium.waitForPageToLoad("60000");

    	selenium.type("css=input[id=authentication_username]", "seleniumpatterns");
    	selenium.type("css=input[id=authentication_password]", "seleniumpatterns");
    	selenium.click("css=input[id=authentication_submit]");
    	selenium.waitForPageToLoad("60000");

    	assertTrue(selenium.isElementPresent("css=div[id=welcome]"));
    	assertTrue(selenium.isElementPresent("css=div[id=welcome] span[id='welcome_username']"));
    	assertTrue(selenium.isElementPresent("css=div[id=welcome] a[id=jumper]"));
    	assertTrue(selenium.isElementPresent("css=div[id=welcome] a[href='/profile']"));
    	assertTrue(selenium.isElementPresent("css=div[id=welcome] a[href='/logout']"));

    	selenium.click("css=div[id=tabs]  a:contains('Tasks')");
    	selenium.waitForPageToLoad("60000");

    	assertTrue(selenium.isElementPresent("css=div[id=welcome]"));
    	assertTrue(selenium.isElementPresent("css=div[id=welcome] span[id='welcome_username']"));
    	assertTrue(selenium.isElementPresent("css=div[id=welcome] a[id=jumper]"));
    	assertTrue(selenium.isElementPresent("css=div[id=welcome] a[href='/profile']"));
    	assertTrue(selenium.isElementPresent("css=div[id=welcome] a[href='/logout']"));

...
   }
}</pre><p>Few people ever recommended writing Se RC code like this, but too many programmers, testers, and teams wrote (and still write) Selenium RC code exactly this. There are many problems with this code. You cannot easily tell what the code is doing (in terms of the app being tested, much less its problem domain). And most of us in the Se world have seen much worse code than this, sad to say. But the main thing here, for our discussion, is that you cannot tell easily <em>WHAT</em> pages are being traversed, and <em>WHY</em> they are being traversed (for functional testing purposes). You cannot tell <em>WHAT</em> the test is doing. Also, the mechanics of waiting for pages to be available is embedded in the tests. As I&#8217;ve covered elsewhere, you can do a lot of things to clean up code like this. And you shouldn&#8217;t have to do so much work.</p>
<h3>AN OBJECT ORIENTED API</h3>
<p>Let&#8217;s hear it for a good old-fashioned Object Oriented API, in which, when I ask a framework object a question, I get returned to me a true object that skillfully encapsulates just the behavior and state I require.</p>
<p>These days, I&#8217;m mostly writing Se 2 / WebDriver code that looks like this:</p><pre class="crayon-plain-tag">public class WhenAUserCreatesAnAccount extends BaseFFCRMTest {
	private static final String ACCOUNT_NAME = "Bob's Bearings and BassOmatics";
	private WebElement accountsTab;
	private WebElement createAccountPanel;

	@Test
	public void theyCanVerifyThatTheyCreatedIt() throws Exception {
		accountsTab = goToAccountsTab();

		createAnAccount(ACCOUNT_NAME);
		verifyAccountCreated(ACCOUNT_NAME);

		deleteAccount(ACCOUNT_NAME);
		verifyAccountDeleted(ACCOUNT_NAME);
	}

	private void createAnAccount(String accountName) throws Exception {
		createAccountPanel = openAccountCreationPane();
		fillOutCreateAccountPanel(accountName);
	}

	private WebElement openAccountCreationPane() {
		WebElement createAccountPaneOpeningToggle = accountsTab.findElement(By
				.id("create_account_arrow"));
		createAccountPaneOpeningToggle.click();
		xdriver.assertElementPresent(By.id("create_account_title"));
		return accountsTab.findElement(By.id("create_account"));
	}

	private void fillOutCreateAccountPanel(String accountName) throws Exception {
		enterNewAccountName(accountName);
		submitForm();
	}

	private void enterNewAccountName(String accountName) {
		WebElement accountNameInputField = createAccountPanel.findElement(By
				.id("account_name"));
		accountNameInputField.sendKeys(accountName);
	}

	private void submitForm() throws Exception {
		WebElement submit = createAccountPanel.findElement(By
				.className("buttonbar"));
		submit.submit();
	}

	private void verifyAccountCreated(String accountName) {
		searchForAccount();
		WebElement accountLink = xdriver.getElementOnceNotStale(By.partialLinkText("BassOmatics"));

		accountLink.getTagName();
		accountLink.click();
		driver.findElement(By.id("edit_account_title"));
	}

	private void searchForAccount() {
		WebElement searchBox = driver.findElement(By.id("query"));
		searchBox.sendKeys(ACCOUNT_NAME);
	}

	private void deleteAccount(String accountName) {
		WebElement deleteAccountLink = driver.findElement(By.linkText("Delete?"));
		deleteAccountLink.click();
		WebElement confirmation = driver.findElement(By.linkText("Yes"));
		confirmation.click();
	}

	private void verifyAccountDeleted(String accountName) {
		searchForAccount();
		WebElement noResultsFound = driver.findElement(By.id("empty"));
		xdriver.assertElementVisible(noResultsFound);
		assertEquals("Couldn't find any accounts matching " + ACCOUNT_NAME
				+ "; please try another query.", noResultsFound.getText());
	}
}</pre><p>No, I am not employing any PageObjects here, because I have not needed to. I did have to home-grow a bit of frameworkie-code to work around occasional StaleElementReferenceExceptions that too-frequently crop up when testing Ajax-rich apps in which jQuery does a lot of attaching, detaching, and re-attaching elements to the DOM. Yes, WebDriver should provide a driver-configuration API for, perhaps, returning only elements that are NOT STALE, since they are useless. This would impose an ambient load on all element-locating findElement(By &#8230;) code, so a nice complement would be an explicit as-needed call to something like findElementOnceFresh(By &#8230;). Meanwhile, I am using this workaround, adapted from various ideas on the interwebz:</p><pre class="crayon-plain-tag">public WebElement getElementOnceNotStale(By locator) {
	WebElement element = null;
	long maxTimeInMillis = timeoutInSeconds/1000; 
	long loopWaitTimeInMillis = 500; 
	long elapsedTimeInMillis = 0;

	do {
		try {
			element = driver.findElement(locator);
			flowContinuesIfNotStale(element);

			break; 
		} catch (StaleElementReferenceException sere) {
			// Element is stale; need to wait briefly and retry findElement()
		}

		try {
				Thread.sleep(loopWaitTimeInMillis);
		} catch (InterruptedException ie) {
			ie.printStackTrace();
		}

	} while (weHaventTimedOut(maxTimeInMillis, loopWaitTimeInMillis, elapsedTimeInMillis));

	return element;
}

private void flowContinuesIfNotStale(WebElement element) {
	element.getTagName();
}

private boolean weHaventTimedOut(long maxTime, long waitTime, long elapsedTimeInMillis) {
	return (elapsedTimeInMillis += waitTime) &lt; maxTime;
}</pre><p>This is illustrative. My point is that in the arms race between web-app-testing frameworks and internet application richness (great gobs of good, bad, and ugly legacy JS and jQuery, much of it un-microtested), workarounds are still inevitable.</p>
<p>But with Se 2, I am writing cleaner code, faster and easier. And so far, I am rolling my own PageObjects much less frequently, since WebElement objects are very handy right out of the box.</p>
<p>More importantly, Same source origin policy workarounds (proxy servers), and other issues resulting from Se 1 driving the browser from within the JS sandbox, are <a title="Se 2: driving from outside the browser" href="http://docs.seleniumhq.org/docs/03_webdriver.jsp" target="_blank">overcome entirely by Se 2 / WebDriver</a>, which drives the browser natively from outside, in whichever way a browser/OS permutation prefers the browser be driven. This is huge.</p>
<p>So I am doing more with method extractions, so far, and less with entire framework classes. Since test code is not production code, and functional test code can be exceptionally expensive to maintain, less code is a very good thing.</p>
<p>I&#8217;ll keep you updated. But I&#8217;m going to get to know Se 2 / WebDriver really, really well.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://patrickwilsonwelsh.com/?feed=rss2&#038;p=785</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why Should You Consider a Career in Programming?</title>
		<link>http://patrickwilsonwelsh.com/?p=687</link>
		<comments>http://patrickwilsonwelsh.com/?p=687#comments</comments>
		<pubDate>Wed, 09 Feb 2011 16:39:48 +0000</pubDate>
		<dc:creator>patrickwilsonwelsh</dc:creator>
				<category><![CDATA[Agility]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SW Mgmt]]></category>

		<guid isPermaLink="false">http://patrickwilsonwelsh.com/?p=687</guid>
		<description><![CDATA[A Pitch to the Underemployed: An Appeal to Industry and Academia In a recent twitter thread amongst several long-time programmers, including me, Tim Ottinger, Corey Haines, Dave Astels, and Jason Gorman, we agreed that we wished we had a collective series &#8230; <a href="http://patrickwilsonwelsh.com/?p=687">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h3>A Pitch to the Underemployed: An Appeal to Industry and Academia</h3>
<p>In a recent twitter thread amongst several long-time programmers, including me, <a href="http://agileotter.blogspot.com/" target="_blank">Tim Ottinger</a>, <a href="http://www.coreyhaines.com/" target="_blank">Corey Haines</a>, <a href="http://techblog.daveastels.com/" target="_blank">Dave Astels</a>, and <a href="http://parlezuml.com/blog/" target="_blank">Jason Gorman</a>, we agreed that we wished we had a collective series of pitches (blog posts, interviews in YouTube videos, a domain), about why and how we got started as programmers. And why we are still so passionate about it after years and years. And related questions. So we are launching this thing, <a href="http://geekstorycorp.blogspot.com/" target="_blank">inspired by Corey&#8217;s original &#8220;How I Got Started in Programming&#8221; interviews</a> , and we will refine it as agilists do: via collaboration, iteration and incremental improvement.</p>
<h3>My Personal Programming Mission</h3>
<p>I love helping people, and programmers in particular, learn to be great. I mostly program, these days, with this mission in my mind and heart. Here&#8217;s my story.</p>
<p>My Dad is a Physicist. He used to do lots and lots of expensive banging of particles into each other at high speed, at various <a href="http://en.wikipedia.org/wiki/Particle_accelerator" target="_blank">particle accelerators</a>. Giant round <a href="http://www.nytimes.com/2010/11/02/science/space/02cern.html?_r=1" target="_blank">electromagnets</a>, like some James Bond special effect. (When my Dad worked at <a href="http://www.nytimes.com/2010/11/02/science/space/02cern.html?_r=1" target="_blank">CERN</a>, we would bike and scooter everywhere, just like the guy in the picture, back before Segways.) Lead bricks, liquid nitrogen, and wires everywhere. Radiation detection badges on every shirt.</p>
<p>So this relates back to programming, I swear. My Dad and his grad students were hacking around on expensive DEC boxes in the 60s to do data analysis, using <a href="http://en.wikipedia.org/wiki/Fortran" target="_blank">Fortran</a> and Unix shell scripts, and <a href="http://en.wikipedia.org/wiki/Nixie_tube" target="_blank">Nixie Tube</a> digital readouts. I was in awe of all of this, truly. He got into the books by measuring the decay rate of the <a href="http://en.wikipedia.org/wiki/Hyperon" target="_blank">Sigma Hyperon</a>. Back when that was totally HARD to do.</p>
<p>One of the many things my Dad was, and is, good at, is pulling community, inspiration, money, practical hacking, and great research ideas together. And he was especially good at helping people learn Science. My Dad is good at making Physics, and learning Physics in particular, really fun and accessible. We would go to the Physics building on a weekend, and hang out with one of Dad&#8217;s heros, Bill Vulcan, a guy who could hack together electronics to do anything. The researchers would ask Bill to cook up some odd, special, one-off device for a cyclotron run, and (this is in like 1966, mind you) Bill would just make it. My Dad loved that, and it was infectious.</p>
<h3>Learning By Blowing Stuff Up</h3>
<p>You want to know about gas pressure as it relates to temperature? My Dad would buy a brand new metal gas can, and put it (without the cap) into our kitchen oven preheated to 600 degrees. My Mom comes in and says &#8220;Bob! Why is the oven at 600 degrees!&#8221;  Dad says &#8220;Because I can&#8217;t get it to go any higher.&#8221;</p>
<p>When the new, empty gas can is glowing a nice red color, my Dad gets his welders&#8217; gloves (important accessory for research Physicists), pulls out the can, screws on the cap, and plunges the can into a tub of water spiked with ice and dry ice (also important, as was liquid nitrogen, though we didn&#8217;t usually keep that at the house).</p>
<p>The gas can makes a terrifying sound, and scrunches up to about the size of a baseball. As I remember it anyway. I should try it again. Hmmmm. [Oh, safety tip: don't have your hand in the gas can handle when you plunge the hot can. It doesn't stay a handle for long.]</p>
<p>In a class on the Physics of electronics, Dad would walk into a class with a fully-charged-up  <a href="http://en.wikipedia.org/wiki/Farad" target="_blank">10,000-microfarad capacitor</a> with the terminals running parallel to each other. It was the size of a can of coffee beans back then. And he would be wearing his safety goggles, and those welders gloves again, and the biggest flat-head screwdriver Sears makes. He would walk up to the front row of a stadium-seating classful of students, and say, &#8220;As those of you who did the reading for last week know, this is a capacitor, and capacitors hold charge.&#8221;</p>
<p>And then he would do the obvious thing: discharge that sucker. Sounded like 5 12-gauge shotguns going off at once. It got one&#8217;s attention.</p>
<p>Years later, my brothers and my Dad would experiment with heavily modified <a href="http://www.spudtech.com/" target="_blank">spud cannons</a>, and Dad would determine how high we were launching spuds by timing launch to landing.</p>
<p>Anyway, stuff like that. All through my youth. That&#8217;s how I got addicted to helping people learn, and making learning fun.</p>
<h3>Why I Got Into Programming</h3>
<p>I was in college in 1978 at the University of California Santa Barbara, studying English, playing a lot of music and writing  a lot of poetry, and, ah, other stuff. Some buddies of mine and I decided to take the new programming class, because they had finally gotten green-screen terminals (of a crude sort), and a real-time OS (W00t!) for their IBM 360 clone, and the new programming intro class was taught by a well-known UCSB CS hippie, <a href="http://tnc2008.terena.org/speakers/index1434.html?id=28" target="_blank">Dr Ken Klingenstein</a>, who <a href="http://www.google.com/images?client=safari&amp;rls=en&amp;q=bell+bottoms&amp;oe=UTF-8&amp;um=1&amp;ie=UTF-8&amp;source=univ&amp;ei=R75STcW-M4L48Abmr7WLCg&amp;sa=X&amp;oi=image_result_group&amp;ct=title&amp;resnum=2&amp;ved=0CEYQsAQwAQ&amp;biw=1328&amp;bih=753" target="_blank">wore bell bottoms</a>, and had hair like someone out of a <a href="http://www.google.com/images?client=safari&amp;rls=en&amp;q=peter+max&amp;oe=UTF-8&amp;um=1&amp;ie=UTF-8&amp;source=univ&amp;ei=H75STc7GKsKt8AahstStCg&amp;sa=X&amp;oi=image_result_group&amp;ct=title&amp;resnum=6&amp;ved=0CFAQsAQwBQ&amp;biw=1328&amp;bih=753" target="_blank">Peter Max poster</a>. It was Dr Ken who told me, when programming still looked scary to me, like, way too much Math, &#8220;Patrick, it turns out that poets and artists come up with great algorithms and data structures. It&#8217;s not all just Math. You should stick this out.&#8221; He was so right.</p>
<p>And first class, Dr Ken threw down a case of good beer on the podium up front, and said &#8220;Whoever among you can come up with a three-dimensional tic-tac-toe game that beats mine, within two weeks, gets this case of beer.&#8221; It was good German beer.</p>
<p>We knew right then that Ken knew how to make learning fun. We were working in <a href="http://en.wikipedia.org/wiki/WATFIV_(programming_language)" target="_blank">WatFiv</a>, a Fortan variant (thanks, guys). We worked our tails off, going to the CS lab between midnight and dawn to get the most terminal time. A friend of mine, Mark Gordon, devised a game that actually beat Ken&#8217;s. Ken was, unexpectedly, chagrinned. But he handed over the beer. These days Ken is an Internet bigwig. I&#8217;m unsurprised.</p>
<p>And the class got more interesting after that. I ended up studying CS at UC Santa Cruz (WAY more hippie professors &#8211; great stories there: the grads and undergrads and profs all just hung out together and came up with stuff to learn and teach: I was immersed in boolean math, turing machines, and on and on), and UC Berkeley (where I was taught DEC PDP-11 assembler from Dr Arthur Gill, from Scotland, who as I remember it, had written the definitive text on DEC PDP-11 assembler, and disliked humans). I worked in assembly language, Fortran, PL/1, and Pascal. I wish to goodness I had bumped into <a href="http://en.wikipedia.org/wiki/Alan_Kay" target="_blank">Alan Kay</a>, but that didn&#8217;t happen. I bumped into fugly COBOL shops instead, in Walnut Creek, CA. Talk about bad luck.</p>
<p>Unlike many of my contemporaries, I did not program for all of my software career. I was daunted by COBOL, and drawn equally to programming and writing. So I spent years as a tech writer, then years programming in the small (hacking) as a UI/UX designer, and then a &#8220;multimedia programmer&#8221; (hacker). All this before I got serious, not that many years ago, about OO and agile programming and software craftsmanship.</p>
<h3>Why I Still Love Programming</h3>
<p>Well-crafted code that is demonstrably valuable, correct, defect free, and &#8212; best of all &#8212; in some way new and delightful in ways customers didn&#8217;t expect! Well. It makes one feel like a wizard. It is a kind of wizardry.</p>
<p>And it demands all the things I love most: creativity, collaboration, inspiration, improvisation, discipline, and continuous improvement and refinement. Above all, it demands continuous learning.</p>
<p>Programming really, really challenges me. I find talking and writing prose much easier, frankly. But when I truly grok key concepts in programming, I get an awesome thrill.</p>
<p>And when I can help someone else grok some key programming concept, I get a much bigger thrill.</p>
<h3>Why Programming Matters</h3>
<p>This world we have made is increasingly made of programs, most of them absolutely terrifyingly badly made. (For a wonderful summary of the history of this, and the stakes involved, <a href="http://parlezuml.com/blog/?postid=1002" target="_blank">read Jason Gorman&#8217;s awesome blogpost on the subject</a>.) For a broader treatment of how declining software quality (&#8220;normalization of deviance&#8221;) relates to quality issues in other industries, <a href="http://practicalagility.blogspot.com/2011/01/normalization-of-deviance-in-software.html" target="_blank">see Dave Rooney&#8217;s excellent summary here</a>.</p>
<p>Meanwhile the Internet, as it evolves like a vast organism, matters as much as anything humans have done, period. We will rely more and more on it for connection, for learning, for helping each other, and for evolving consciousness. Truly, it matters a great deal how well the fabric of the Internet, and all of the programs on it, are made. (I link all the time to <a href="http://en.wikipedia.org/wiki/Main_Page" target="_blank">Wikipedia</a>, increasingly an international treasure. Do you know what that thing is made of, and how? Ouch.)</p>
<p>The software that is showing up in our cars sometimes crashes. I rented a <a href="http://www.youtube.com/watch?v=8g9MCGCrgm0" target="_blank">Ford Edge last year whose dashboard display kept rebooting</a>. It was ominous. Now my car can crash before it crashes.</p>
<p>That&#8217;s not OK. That&#8217;s pathetic. We can and must and will do better. It will take many more passionate, productive, pragmatic, disciplined, dedicated software craftsmen. It will take more creativity, collaboration, inspiration, improvisation, discipline, and continuous improvement and refinement.</p>
<p>And above all, continuous learning.</p>
<h3>Why Men and Women Should Consider Programming as a Career</h3>
<p>Programming done really well, by the best programmers I know, is awesomely fun, inspiring, and cool. The culture of the best 10,000 programmers in the world is populated by people who are perhaps 1000 times more skillful, passionate, and productive than the average programmer. (Oddly, most of them are also very good musicians. Most of them, in fact, are great guitarists. Go figure, Dr Ken.)</p>
<p>Programming as a craft (pursued with creativity, collaboration, inspiration, improvisation, discipline, and continuous improvement and refinement and learning) is deeply rewarding. It&#8217;s really, really fun. It makes and saves people time and money. It connects people. It enables people to have fun.</p>
<p>Small groups of programmers have about them the same magic as the very best teams in professional sports, the very best Special Forces military teams, the very best college faculties, the very best teams of any kind who routinely challenge each other and themselves. (Heck,<a href="http://www.google.com/search?client=safari&amp;rls=en&amp;q=pike+place+fish+youtube&amp;ie=UTF-8&amp;oe=UTF-8#q=pike+place+fish+youtube&amp;hl=en&amp;client=safari&amp;rls=en&amp;prmd=ivns&amp;source=univ&amp;tbs=vid:1&amp;tbo=u&amp;psj=1&amp;ei=FApTTd3oEMmr8AajuYzwCQ&amp;sa=X&amp;oi=video_result_group&amp;ct=title&amp;resnum=1&amp;ved=0CDUQqwQwAA&amp;fp=77a55f96cdc77e53" target="_blank"> you can do it throwing fish</a>.) Groups of the best programmers are very boisterous, sometimes contentious, inspiring. Very alive. It&#8217;s almost like they are throwing fish. But ideas instead. I think you follow me.</p>
<p>I created <a href="http://animoto.com/play/PSRb3tnOlQQmmcdU0efFRQ?autostart=false" target="_blank">this animoto video</a> and <a href="http://animoto.com/play/Osl57xq1Ok2pC04UoyB80Q?autostart=false" target="_blank">this other one</a> a couple of years ago from pix I took at the <a href="http://patrickwilsonwelsh.com/?p=40" target="_blank">very first CodeRetreat</a>. (The music for both vids, by the way, is mine, from like 16 years ago, back when I did sound tracks for CD-ROM games.)</p>
<p>I think about moments like that when I think about awesome programmers.</p>
<p>Someday, as in the novel <a href="http://en.wikipedia.org/wiki/The_Diamond_Age" target="_blank">Diamond Age</a>, perhaps software can help make learning 1000 times better than our current &#8220;education systems,&#8221; which are paternalistic, conformist, hierarchical, performance-based, dehumanizing, mechanizing, demoralizing, and otherwise just plain bad. I really do look to programmers to help change that.</p>
<h3>The Kind of Programming You Don&#8217;t Want to Do</h3>
<p>You don&#8217;t want to end up with your head down in a cubicle, engaged in Microsoft Artifact Wars all day. The more time you are spending in ClearCase, Word, Excel, and (God save us all) Outlook, the more you are likely to be a <a href="http://wageslaverebel.com/diary-of-a-wage-slave-rebel-a-brief-intro-to-my-madness/" target="_blank">software wage-slave</a>.</p>
<p>That was never the only option, and it is decreasingly the only option. There is a small but powerful, growing army out there of programmers who will not give up on the true promise of programming. Programming and learning to program, like Physics and learning Physics, can be an absolute gas.</p>
<p>Trust me, you want to be part of something that cool, something that makes you feel that alive.</p>
<h3>Other Blogs and Resources In this Blog Chain</h3>
<p>As they emerge, I will link to YouTube vids, other blogs, books, and other resources that answer these (and related questions).</p>
<p>In the long run, as Corey points out, what we really want is to bust out of our own community into a mainstream, funded source of continuous inspiration for those who might flourish in software. <a href="http://www.pbs.org/wgbh/nova/secretlife/" target="_blank">Something like this</a> might be related.</p>
<p>Start with this: <a href="http://geekstorycorp.blogspot.com/" target="_blank">Corey&#8217;s vids</a>, and the <a href="http://pragprog.com/titles/cfcar2/the-passionate-programmer" target="_blank">Passionate Programmer</a> by <a href="http://chadfowler.com/" target="_blank">Chad Fowler</a>.</p>
<p>Also, <a href="http://parlezuml.com/blog/?postid=1002" target="_blank">Jason Gorman&#8217;s passionate call to action along these lines</a>: reaching out to folks and pitching programming to them as a career.</p>
<p>Also, check out <a href="http://thisdeveloperslife.com/" target="_blank">This Developer&#8217;s Life</a>, and this thread on <a href="http://stackoverflow.com/questions/1668100/did-hobby-programming-magazines-inspire-your-career-and-whats-their-modern-day" target="_blank">old-skool programming inspiration</a>.</p>
<p>[More soon...]</p>
]]></content:encoded>
			<wfw:commentRss>http://patrickwilsonwelsh.com/?feed=rss2&#038;p=687</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Whack-A-Method</title>
		<link>http://patrickwilsonwelsh.com/?p=671</link>
		<comments>http://patrickwilsonwelsh.com/?p=671#comments</comments>
		<pubDate>Tue, 08 Feb 2011 16:07:20 +0000</pubDate>
		<dc:creator>patrickwilsonwelsh</dc:creator>
				<category><![CDATA[agile testing]]></category>
		<category><![CDATA[Agility]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://patrickwilsonwelsh.com/?p=671</guid>
		<description><![CDATA[I Feel a Framework Coming On [Agile Programming: Lesson One, Part Four] I&#8217;ve been pitching to the world this notion of a gradual ascent into programming excellence, starting with just a bit of refactoring the innards of classes in a &#8230; <a href="http://patrickwilsonwelsh.com/?p=671">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h3>I Feel a Framework Coming On</h3>
<h4>[Agile Programming: Lesson One, Part Four]</h4>
<p>I&#8217;ve been pitching to the world this <a href="http://patrickwilsonwelsh.com/?p=455" target="_blank">notion of a gradual ascent into programming excellence</a>, starting with just a bit of refactoring the innards of classes in a small problem space, and just a bit of test-driving in the same problem space.</p>
<p>I ask people to do the exercises, keeping methods really, really small, and really simple. But up until now, if someone asked, Got a Test for That?, my answer, sadly, was <em>No, Sorry, Use Static Analysis Tools &#8211; There Are Tons of Them Out There</em>. Lame answer.</p>
<p>Inspired (again) at a recent <a href="http://www.codemash.org/" target="_blank">CodeMash</a> by another whack at the excellent <a href="http://rubykoans.com/" target="_blank">Ruby Koans</a>, and having heard great things about similar <a href="http://www.srtsolutions.com/codemash-recap-scala-koans-precompiler" target="_blank">Scala Koans</a>, I wanted a koans-ish learning tool for refactoring. You know what&#8217;s cool and fun about these koans? Everything, that&#8217;s what. Learning should be fun. Yes, that&#8217;s right. You heard it here first. These test-based koans are super fun.</p>
<p>When I asked people to keep methods under some number of lines of code, and under some cyclomatic complexity threshold,<em><strong> I Wanted a Test for That</strong></em>. And now, indeed, I do. I have two Whack-A-Method exercises; <a href="https://github.com/PillarTechnology/Training-Codebases/tree/master/Refactor_BankOCR_Whack_A_Method" target="_blank">one for refactoring a sub-optimal implementation</a> of <a href="http://codingdojo.org/cgi-bin/wiki.pl?KataBankOCR" target="_blank">BankOCRKata</a>, and another for <a href="https://github.com/PillarTechnology/Training-Codebases/tree/master/TDD_BankOCRKata_Whack_A_Method" target="_blank">continuing to test-drive a pretty-good-so-far partial implementation</a> of the <a href="http://codingdojo.org/cgi-bin/wiki.pl?KataBankOCR" target="_blank">BankOCRKata</a>. The first exercise has a couple of really Eager end-to-end tests, but Hey! They give you 100% Code Coverage! Yay for anything!</p>
<p>So, these are Eclipse projects. If you have <a href="http://www.eclemma.org/" target="_blank">Eclemma</a> installed, then you can pull down Coverage As &gt; JUnit Test, and behold: you see your code coverage, of course. And in either Whack-A-Method exercise, you see the results of the tests for current production code behavior, AND YOU ALSO see results of tests that automagically recurse through your output folders for .class files, and ask a little jarred-up, embedded static analysis tool called <a href="http://cyvis.sourceforge.net/" target="_blank">CyVis</a> (Tx, Guys!) to instantiate a test case for each of your classes, and instantiate a different test case for each of your methods.</p>
<p>Because I used the Junit 4 built-in parameterized test runner extension, you don&#8217;t get much info from the tests that run green, and you cannot (at least as yet) click through ugly classes or methods in the failures (though I&#8217;ve provided meaningful failure semantics).</p>
<p>But Hey!  It&#8217;s totally version 0.1, and it works OK.</p>
<h3>Caveat Lector: Yes, We are Refactoring on Red</h3>
<p>So, in the real world, you never want to refactor on a red bar, because you cannot tell whether you are screwing up existing behavior.</p>
<p>And, on the other hand, in the world of koans and learning tools, tests are an awesomely addicting, engaging learning mechanism. So, friends, consider this current Whack-a-Method a proof of concept. It&#8217;s easy to try, requires no installation, works right outa the box, and is fun.</p>
<p>But you must indeed distinguish between red bars in the tests that cover the production code, vs whackAmethod red bars. In this pair of exercises, it&#8217;s OK if your whackAmethod tests are red while you refactor. The other tests are saving your bacon with respect to code behavior. It&#8217;s not OK if those non-whackAmethod tests are red.</p>
<p>Of course, you are heading toward a green bar. And you want to get there as fast as you can, and stay there as much of the time as you can.</p>
<p>And ultimately this tool is likely to become plugins and extensions for editors like emacs and eclipse. Not because the world needs scads of additional source analysis plugins, but because most of them are as simple as a Saturn V rocket, and this one is dead simple. And for now, as I&#8217;ve said before, you really only need a couple of metrics.</p>
<h3>Whack-Extract Till Green</h3>
<p>In the refactoring Whack-A-Method exercise, you just keep extracting methods and classes until everything runs green. Easy? Try it and find out!</p>
<p>In the TDD Whack-A-Method exercise, you just keep test-driving your code till you have fulfilled all of the requirements in the Requirements.txt file, and you keep all the tests green as much of the time as you can.</p>
<h3>Tweak the Thresholds, Once You Know What You&#8217;re Doing</h3>
<p>You can tweak the constants in CleanTestBase.java to tighten or loosen the method/class size and complexity thresholds. But please don&#8217;t at first. The defaults help learning to happen.</p>
<h3>Does it Eat its Own Dogfood?</h3>
<p>Yes, it does. All the classes in the whackAmethod package are themselves fully Whack-A-Method compliant, given the default thresholds. Let&#8217;s see a plugin do THAT.</p>
<h3>A Bit of 0.1 Framework Fer Ya</h3>
<p>So, if you want to try this experiment on any Java codebase of your own, you totally can, with minimal copy, paste, config (well, as far as I know today &#8212; again, version 0.1).</p>
<ol>
<li>Copy the entire whackAmethod package from my test source-folder to your own test source folder. (If you want to refactor my source, go for it, lemme know, and I&#8217;ll likely give you commit rights to the project).</li>
<li>Copy the cyvis.jar and the asm-all-2.1.jar to your project and build path.</li>
<li>Change the constant STARTING_DIRECTORY_NAME in  RecursiveClassFileFinder.java to point to the root of your output folder (it currently defaults to &#8220;bin&#8221;).</li>
<li>Run the tests. The Whack-A-Method tests should all run.</li>
<li>Contact me with any problems.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://patrickwilsonwelsh.com/?feed=rss2&#038;p=671</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OK, Now Let&#8217;s Discuss Microtests &amp; TDD</title>
		<link>http://patrickwilsonwelsh.com/?p=619</link>
		<comments>http://patrickwilsonwelsh.com/?p=619#comments</comments>
		<pubDate>Thu, 30 Dec 2010 18:28:26 +0000</pubDate>
		<dc:creator>patrickwilsonwelsh</dc:creator>
				<category><![CDATA[agile testing]]></category>
		<category><![CDATA[Agility]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SW Mgmt]]></category>

		<guid isPermaLink="false">http://patrickwilsonwelsh.com/?p=619</guid>
		<description><![CDATA[Agile Programming: Lesson One (Part Three) At the start of this series of posts I suggested that those who really, really want to become Agile Programmers start with a couple of refactoring exercises. In another post I explained why I &#8230; <a href="http://patrickwilsonwelsh.com/?p=619">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h3>Agile Programming: Lesson One (Part Three)</h3>
<p><a href="http://patrickwilsonwelsh.com/?p=455" target="_blank">At the start of this series of posts</a> I suggested that those who really, really want to become Agile Programmers start with a couple of refactoring exercises. <a href="http://patrickwilsonwelsh.com/?p=560" target="_blank">In another post I explained why I suggest this as a starting point</a>. I&#8217;ll reiterate here that I am suggesting that you perform those exercises several times, several ways, before you attempt the exercises coming up next.</p>
<p>All done?  OK. Cool. Now, three posts in, I&#8217;ll introduce the ideas of microtests and Test-Driven Development (referring you to other sources for deeper dives into these large topics).</p>
<p>If you have been following along in code, as well as in your reading, you may by now have discovered and learned several things. Here are a few, any one or two of which may have occurred to you:</p>
<ul>
<li>You would not really be safe trying to do those original refactoring exercises without the handful of tests that cover them.</li>
<li>It&#8217;s not hard to break existing tests if you keep running them after each little refactoring step</li>
<li>The refactoring steps in the exercises can be pretty hard to do, even in those really small amounts of code.</li>
<li>As you extract behavior into lots of new methods, and perhaps into a few new classes, it would be really cool to have new, separate JUnit tests that cover those specific little behaviors.</li>
<li>It can be tricky trying to determine how to keep test code itself clean and concise.</li>
</ul>
<p>I suspect that after enough repetitions of those first exercises I suggested, one or more of these does occur to you. Let&#8217;s dig into testing in the context of these kinds of observations.</p>
<h3>Definition: Microtests</h3>
<p>By <a href="http://anarchycreek.com/2009/05/20/theyre-called-microtests/" target="_blank">Microtests</a>, which term was coined by <a href="http://anarchycreek.com/" target="_blank">Mike (@GeePawHill) Hill</a>, I mean the same thing that people like <a href="http://michaelfeathers.typepad.com/michael_feathers_blog/" target="_blank">Mike Feathers</a> and <a href="http://www.jbrains.ca/" target="_blank">J.B. Rainsberger</a> (and many other TDD thoughtleaders) mean by unit tests or isolation tests or <a href="http://c2.com/cgi-bin/wiki?ProgrammerTest" target="_blank">programmer tests</a>. So in Java, a JUnit test is a Microtest if it:</p>
<ul>
<li>Tests a single discrete behavior/responsibility (&#8220;in isolation&#8221;)</li>
<li>Runs completely in memory: does not touch databases, GUI frameworks, file systems, or networks. Those other tests are frequently useful, but they are not microtests.</li>
<li>Runs really, really fast. Fast enough means somewhere between 10 and 100 per second, or faster.</li>
</ul>
<h3>Vital Ends: Enough Microtests for a Production Codebase</h3>
<p>Every production codebase desperately needs to have enough microtest coverage.</p>
<p>Your codebase has enough microtests if your code coverage (as previously discussed) is at least 85%, and your median test-method length and production method-length is really small (as previously discussed), and each test class and test method is itself SRP-compliant, and <em>very experienced microtesters have looked over the entire test suite and pronounced it healthy.</em></p>
<p>There are leaps of faith for you to take here, admittedly. And that last clause is really fuzzy and subjective. I get it.</p>
<p>Nevertheless, I&#8217;ll emphasize this:</p>
<p style="padding-left: 30px;"><em>Aside from the production code itself, there is no more important artifact for any codebase than its suite of microtests. A codebase without enough microtests, as Feathers has pointed out, is by definition Legacy Code. Agile Programmers are careful about microtests the way veteran skydivers are careful about packing parachutes. </em></p>
<p>Again, an exhaustive suite of microtests are <em><strong>ends</strong></em>, worthy in their own right, for protecting us from introducing defects when we change code.</p>
<p>But as is very frequently discussed in agile circles, Test-Driven Development (TDD), <em>as a means to those ends</em>, is important in other ways.</p>
<h3>Definition: <a href="http://en.wikipedia.org/wiki/Test-driven_development#Test-driven_development_cycle" target="_blank">Test-Driven Development (TDD)</a></h3>
<p><a href="http://en.wikipedia.org/wiki/Test-driven_development#Test-driven_development_cycle" target="_blank">Test-Driven Development</a> is the practice and craft of writing tiny little microtests for production code before you write the production code itself. The practice has been covered exhaustively in other sources, so I&#8217;ll only sketch it here, starting with its benefits. Again, prepare to make leaps of faith:</p>
<ul>
<li>TDD is the most efficient, least-expensive way to produce high-ROI, low-TCO suites of exhaustive microtests.</li>
<li>TDD is the most efficient, least-expensive way to drive production code in the direction of high-ROI, low-TCO Clean Code.</li>
<li>TDD and microtesting have layers of sophistication, auxiliary practices and techniques, and otherwise a world of richness of their own.</li>
<li>Skilled TDD (and refactoring) completely change how you feel about programming, for the better.</li>
<li>Only after you have written a few thousand microtests using TDD (and other practices) do those first four points above become experientially clear.</li>
<li>For many programmers, TDD seems at first (perhaps for months) to be a maddening, fanatical waste of time. It feels (to some) like walking backward up a staircase, blindfolded, carrying a tray of expensive flute glasses full of expensive champagne. Senseless, in other words. But that does pass.</li>
</ul>
<p>Yes, you can write tests last, after you have written production code. But in exercises coming up soon here, I hope to provide you an opportunity to learn that this slows you down more than you can tolerate. I&#8217;ll also explain why that seems to be true.</p>
<p>One more thing: it can be very, very difficult to do real TDD, or to add or change code at all, in existing codebases with very low code coverage. Before continuing with this post/lesson, if you doubt what I just said, please consider <a href="http://patrickwilsonwelsh.com/?p=18" target="_blank">attempting this exercise I created a few years ago</a>. Then come back here and continue.</p>
<h3>The TDD References</h3>
<p>First, the references. <a href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank">TDD basics are covered on-line pretty darned well</a>. The more advanced, sneaky design mechanisms behind it are covered (for the advanced reader) <a href="http://anarchycreek.com/2010/12/08/how-tdd-works-its-magic-reducing-mental-scope/" target="_blank">here</a> and <a href="http://anarchycreek.com/2010/12/20/how-tdd-works-its-magic-2-multiplying-intent/" target="_blank">here</a> and <a href="http://www.jbrains.ca/permalink/how-test-driven-development-works-and-more" target="_blank">here</a> and <a href="http://cleancoder.posterous.com/the-transformation-priority-premise" target="_blank">here</a>.</p>
<p><em><strong>Aside:</strong></em> My fave, <a href="http://jamesshore.com/Blog/Lets-Play/" target="_blank">fave intro to TDD online is @JamesShore &#8216;s &#8220;Let&#8217;s Play&#8221; series</a>. James models to us all expertise, poise, fun, and best of all, supreme openness and vulnerability. Also the desire for a pair! You can follow these videos and learn enormous amounts (the pace of learning is different from what I am attempting here &#8212; it&#8217;s OK if you find yourself lost by him pretty fast; if you revisit these next year you likely won&#8217;t be). You can also hear his cat whining about TDD in the background, if you listen carefully.</p>
<p>In all seriousness, in the opinion of some, James dives quickly into &#8220;TDD by the book,&#8221; which is to say with very, very little up-front design. Note that, as James proceeds, given his level of skill, this is not a serious problem for him. Master that he is, he can refactor himself out of any design misstep<em><strong>. This is not TDD at a novice level. </strong><span style="font-style: normal;">Also notice in this series of videos how deeply James dives into mastering the problem domain at hand. It is his deepening mastery of that domain, coupled with his TDD mastery, that allows his design to emerge in increments that might at first seem ungainly, but are in fact elegant. </span></em></p>
<p>TDD is also covered in a slew of great books. Good ones in Java include (at least)</p>
<ul>
<li><a href="http://www.amazon.com/Agile-Java-TM-Test-Driven-Development/dp/0131482394/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1293729302&amp;sr=1-1" target="_blank">Agile Java</a>,</li>
<li><a href="http://www.amazon.com/Test-Driven-Development-Practical-David-Astels/dp/0131016490/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1293729361&amp;sr=1-1" target="_blank">TDD: a Practical Guide,</a></li>
<li><a href="http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530" target="_blank">TDD: By Example</a>,</li>
<li>and my all-time fave: <a href="http://www.amazon.com/Test-Driven-Acceptance-Java-Developers/dp/1932394850/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1293729399&amp;sr=1-1" target="_blank">Test Driven</a>.</li>
</ul>
<p>No, you need not purchase and read all of these books. Any one of them is likely sufficient to challenge you with Java TDD exercises and thinking for some time. And you need not purchase any of them this minute. But you will need at least one of them soon, both for tutorial and for reference. There is a completely different slew of books for  test-driving in other languages, BTW. [More later.]</p>
<h3>The Classic <span style="color: #ff0000;">Red</span>-<span style="color: #00ff00;">Green</span>-Refactor TDD Cycle</h3>
<p><a href="http://patrickwilsonwelsh.com/wp-content/uploads/2010/12/red-green-refactor-cycle.jpg"><img class="alignnone size-full wp-image-650" title="red-green-refactor-cycle" src="http://patrickwilsonwelsh.com/wp-content/uploads/2010/12/red-green-refactor-cycle.jpg" alt="" width="450" height="245" /></a></p>
<p>The classic <a href="http://en.wikipedia.org/wiki/Test-driven_development#Test-driven_development_cycle" target="_blank">TDD cycle </a>is covered well, in all seriousness, in the <a href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank">wikipedia TDD write-up</a>. When you are learning TDD, taking this grand leap of faith, stick to this cycle like glue. Follow it blindly for a good long while. Internalize it.</p>
<p>If you need a little humor to keep you on track, you can use this <a href="http://pairprogrammingbot.com/" target="_blank">handy on-line &#8220;pair partner&#8221;</a> to remind you where you are in the cycle.</p>
<h3>A New Rule to Follow in Our Challenges</h3>
<p>We&#8217;ve been working in the <a href="http://codingdojo.org/cgi-bin/wiki.pl?KataBankOCR" target="_blank">BankOCR Kata </a>for awhile now. We&#8217;ve been refactoring existing code. As we go, we&#8217;ve been adhering to certain rules (paraphrased here, for our next challenges):</p>
<ul>
<li>Keep all tests running green as much as possible. Also try to purposefully break them sometimes, to see what kinds of coverage they give you in the code (more on that later, too).</li>
<li>Rename each entity (project, package, class, method, variable) at least twice, as you learn more and more about what it should be doing</li>
<li>By the time you are done, no method should contain more than 8 lines of code (this also applies to test methods), and most methods should be in the neighborhood of 4 or 5 lines of code, including declarations and return statements. This includes test methods.</li>
<li>Don&#8217;t let <a href="http://en.wikipedia.org/wiki/Code_coverage" target="_blank">code coverage</a> fall below 85%.</li>
</ul>
<p>As we switch to test-driving brand-new code, the rules above still apply. To this I&#8217;ll add a new rule, for the test-driven code:</p>
<ul>
<li>Test-drive classes that contain only a single public method, no more than 3 fields, and no more than 4 private helper methods. Try to avoid accessors (getters and setters). Can you avoid them? If not, why not?</li>
</ul>
<h3>Your Next Challenges</h3>
<p>Start by ignoring the design you have been working with in the first exercises. Empty your mind of design ideas for the <a href="http://codingdojo.org/cgi-bin/wiki.pl?KataBankOCR" target="_blank">BankOCR Kata</a>. <a href="https://github.com/PillarTechnology/Training-Codebases/tree/master/TDD_BankOCRKata_Whack_A_Method" target="_blank">Start with this new, nearly fresh version of an implementation</a>, which can now help you with the special love provided by the <a href="http://patrickwilsonwelsh.com/?p=671" target="_blank">Whack-A-Method testing mechanism</a>.</p>
<p>Try test-driving just one part of the <a href="http://codingdojo.org/cgi-bin/wiki.pl?KataBankOCR" target="_blank">BankOCR Kata</a> at a time, and in this order (for now):</p>
<ul>
<li>Test-drive code that parses  a bunch of raw OCR-like String data (represented however you like) into separate OCR digits. Remember the input data looks like this:</li>
</ul>
<p></p><pre class="crayon-plain-tag">_     _  _     _  _  _  _  _
| |  | _| _||_||_ |_   ||_||_|
|_|  ||_  _|  | _||_|  ||_| _|</pre><p></p>
<ul>
<li>How many classes does this need?  I mean, if they are really, really small, SRP-compliant classes?</li>
<li>Next, test-drive code that converts those individual OCR digits into integers. Again, how many classes do you need? How do you know?</li>
<li>Finally, test-drive code that converts groups of those OCR digits into proper account numbers.</li>
</ul>
<p>Now, after having done that the above way, throw away all the code, and do it in reverse. Is that harder? Easier?</p>
<p>Remember to follow all of the above rules. And stay tuned, next, for some more deep dive into emergent design: the magic thing that happens as we begin to master TDD, Clean Method Hierarchies, and Clean Code generally.</p>
]]></content:encoded>
			<wfw:commentRss>http://patrickwilsonwelsh.com/?feed=rss2&#038;p=619</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clean Method Hierarchies: Why Start Here?</title>
		<link>http://patrickwilsonwelsh.com/?p=560</link>
		<comments>http://patrickwilsonwelsh.com/?p=560#comments</comments>
		<pubDate>Mon, 27 Dec 2010 04:37:44 +0000</pubDate>
		<dc:creator>patrickwilsonwelsh</dc:creator>
				<category><![CDATA[Agility]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SW Mgmt]]></category>

		<guid isPermaLink="false">http://patrickwilsonwelsh.com/?p=560</guid>
		<description><![CDATA[Agile Programming: Lesson One (Part Two) Two posts ago, I suggested a first pair of exercises for programmers who want to learn some Agile Programming off-line, which is to say, by themselves. The exercises in that first post ask you &#8230; <a href="http://patrickwilsonwelsh.com/?p=560">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h3>Agile Programming: Lesson One (Part Two)</h3>
<p>Two posts ago, I suggested a <a href="http://patrickwilsonwelsh.com/?p=455" target="_blank">first pair of exercises</a> for programmers who want to learn some <a href="http://patrickwilsonwelsh.com/?p=521" target="_blank">Agile Programming</a> off-line, which is to say, by themselves. The exercises in that first post ask you to focus on learning to refactor existing code to what I call a <em>Clean Method Hierarchy</em>. It asked you to make a leap of faith, trying the exercises, without first reading several more paragraphs about why I think that makes such a great starting point for learning Agile Programming. In this post, I&#8217;m trying to backfill that explanation and justification.</p>
<h3>The Original Goals</h3>
<p><a href="http://patrickwilsonwelsh.com/?p=455" target="_blank">In that first post</a>, I suggested that the target level of cleanliness you should shoot for in the first two exercises should include these characteristics:</p>
<ul>
<li>Keep all existing tests, such as they are, running green as much as possible. Also try to purposefully break them sometimes, to see what kinds of coverage they give you in the code (more on that later, too).</li>
<li>Rename each entity (project, package, class, method, variable) at least twice, as you learn more and more about what it should be doing</li>
<li>By the time you are done, no method should contain more than 8 lines of code (this also applies to test methods), and most methods should be in the neighborhood of 4 or 5 lines of code, including declarations and return statements.</li>
</ul>
<h3>Now: Why Start with Just These Exercises?</h3>
<p>Below, I explain why it matters so much that you learn to accomplish the above ends instinctively as an agile programmer, as a software craftsman.</p>
<h3>A Clean Class is Much Easier to Learn than Clean Everything Else</h3>
<p>Below we&#8217;ll dive into the handful of things you need to understand deeply in order to get really, really good at keeping one class clean. Compared to what is necessary to keep an entire object model clean, a multi-tiered architecture clean, a codebase build clean, web application framework implementations clean, continuous integration systems clean, and continuous delivery systems clean (not to mention thorny subjects like exception handling and concurrency), the short list of things required to keep one class clean is pleasantly tractable.</p>
<h3>It&#8217;s Easier Partly Because There are Only a Few Things Involved</h3>
<p>The specific list of practices, principles, and patterns, as mentioned in the first post, includes:</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Code_coverage" target="_blank">Code Coverage</a></li>
<li>Naming and <a href="http://www.refactoring.com/catalog/renameMethod.html" target="_blank">Renaming</a></li>
<li>Basic <a href="http://en.wikipedia.org/wiki/Code_refactoring" target="_blank">Refactoring</a></li>
<li><a href="http://en.wikipedia.org/wiki/Command-query_separation" target="_blank">Command/Query Separation</a></li>
<li>The <a href="http://c2.com/cgi/wiki?ExtractMethod" target="_blank">Extract Method</a> refactoring</li>
<li>The <a href="http://www.jetbrains.com/resharper/webhelp/introduce-field.html" target="_blank">Introduce variable/field </a>refactorings (and scope change refactorings generally)</li>
<li>The <a href="http://www.refactoring.com/catalog/extractClass.html" target="_blank">Extract Class refactorin</a>g</li>
<li>The <a href="http://www.refactoring.com/catalog/moveMethod.html" target="_blank">Move Method refactoring</a></li>
<li>The <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle" target="_blank">Single-Responsibility Principle (SRP)</a></li>
<li><a href="http://blog.objectmentor.com/articles/2009/09/11/one-thing-extract-till-you-drop" target="_blank">Keeping Modules Really, Really, Insanely Small</a></li>
<li>Squeeze Class</li>
</ul>
<p>In this post, let&#8217;s cover just the few of these that are most vital:</p>
<ul>
<li>Code Coverage</li>
<li>Naming and Renaming</li>
<li>Basic Refactoring</li>
<li>The Extract Method refactoring</li>
<li>Keeping Modules Small</li>
<li>The SRP (Single-Responsibility Principle)</li>
<li>Cyclomatic  Complexity</li>
<li>Squeeze Class</li>
</ul>
<h3>Code Coverage</h3>
<p>To the above list of original goals, let me now suggest that you add this item (you are going to keep working on the exercises over and over again, right?):</p>
<ul>
<li>Don&#8217;t let <a href="http://en.wikipedia.org/wiki/Code_coverage" target="_blank">code coverage</a> fall below 85%.</li>
</ul>
<p>The definition of a Clean Class includes (contextually) something like 85% <a href="http://en.wikipedia.org/wiki/Code_coverage" target="_blank">code coverage</a> (the measured extend to which your code is protected by tests). (For some kinds of code, you&#8217;ll need higher coverage.) For Java code, you can measure code coverage  (and observe the detailed results, line by line of code) using any number of commercial and open source tools, including IDE plugins. One such useful, good-enough open-source pair of code-coverage tools for Java is <a href="http://emma.sourceforge.net/" target="_blank">Emma</a> and <a href="http://www.eclemma.org/" target="_blank">Eclemma</a>.</p>
<p>The reason good enough code coverage with tests is so important is that without those tests, you don&#8217;t know if you are introducing defects when you change the code.</p>
<p style="padding-left: 30px;"><em>Good enough code coverage does not just mean the coverage metric and other metrics. It mainly means that if you accidentally introduce a defect in existing code, some test somewhere that just ran <span style="color: #00ff00;"><strong>green</strong></span></em><em> now runs <span style="color: #ff0000;"><strong>red</strong></span></em><em>. </em></p>
<p>Does the code, as originally delivered to you, have 85% coverage?  When you first went through the exercise, did you decrease or increase the coverage, or did it stay the same? How did that happen?</p>
<h3>The Problem with Code Coverage: It&#8217;s a <em>One-Way Metric</em></h3>
<p>If you measure that a codebase has 2% code coverage, it is guaranteed to be in danger.<a href="http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/product-description/0131177052" target="_blank"> Increasingly, the industry-accepted definition of Legacy Code is simply &#8220;insufficient tests.&#8221;</a></p>
<p>On the other hand, if you have 90% code coverage, what does that mean? Unfortunately, in the absence of other assessment and measurement, it means nothing. Smart people have learned how to &#8220;game&#8221; the coverage metric so that they can achieve the magic, imposed high numbers with very few, very bad tests that have no real value.</p>
<p>Only if both code coverage numbers, median module size, and median cyclomatic complexity are reasonably good for a codebase can you begin to breathe easy about it. That&#8217;s because</p>
<p style="padding-left: 30px;"><em>If you have high enough code coverage, across a codebase that consists of very small classes and methods, you can almost always rescue it completely (if you need to). </em></p>
<p>Put another way:</p>
<p style="padding-left: 30px;"><em>If you have high code coverage and low median method-level cyclomatic complexity alone, your codebase is probably in pretty good shape. </em></p>
<p>Notice the word <em>probably</em>. It is still possible to test-drive codebases with 85% coverage and median method-level complexity of 2, and still have a very bad object model, very hard-to-understand names, and a slew of other non-trivial problems. But you can probably do something about those other problems, if truly you have 85% coverage and median method-level complexity of 2.</p>
<p>That&#8217;s much of why I emphasize mastering this small list of things first, in these first few exercises: <em>it can make the difference between a codebase that can be rescued, and one that truly must be thrown away and rewritten</em>.</p>
<p>So what about these few other things?</p>
<h3>Naming and Renaming</h3>
<p>The most vital, and most subjective and difficult, Clean Code practice is the art of naming and renaming. The very best writing on the subject is by Tim Ottinger (<a href="http://twitter.com/#!/tottinge" target="_blank">@tottinge</a>), who covered it succinctly and beautifully in Chapter Two of <a href="http://twitter.com/#!/unclebobmartin" target="_blank">Bob Martin&#8217;s</a> <a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882" target="_blank">Clean Code</a> book (this is one of the first books you should buy, BTW). Tim self-describes as more of an artist than a scientist/logician, and I think that may be why he is such a virtuosic namer. Naming and renaming are art, not science. I won&#8217;t recap Tim&#8217;s material here; like I said, you&#8217;ll need to own the book anyway in order to make sense of this series of blog posts.</p>
<p>I&#8217;ll add my own naming practice, FWIW: <em>Attempt to Rename Each Entity Three Times, at Each Contextual Change</em></p>
<ul>
<li>When you first encounter an entity (class, field, constant, method, local variable) that you don&#8217;t completely understand at first glance, consider renaming it to what you suspect it actually means. Feel free, for especially pernicious names, to include modifiers like &#8220;perhaps,&#8221; &#8220;maybe,&#8221; or &#8220;WTF&#8221; to the name, in order to remind you that you know this name is not quite right.</li>
<li>The next time you encounter that same entity in the context of code change, if you have now learned more about it&#8217;s responsibility, rename it again.</li>
<li>Do this one more time (at least), the next time you find yourself working with the same entity, as the code evolves, and <em>especially as your understanding of the underlying problem domain evolves</em>.</li>
<li>Anytime an entity&#8217;s relationship with its clients, its delegates, its home scope, or any of its context changes, it may indeed require a new name. Is some new client calling it? Did you change its access level or method signature? Did you extract behavior from it? Did you move it to another class? Did it&#8217;s class name change, or its class&#8217;s package name? These are reasons to consider renaming it.</li>
</ul>
<h3>Basic Refactoring</h3>
<p>The original <a href="http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672" target="_blank">Refactoring</a> book by <a href="http://martinfowler.com/" target="_blank">Martin Fowler</a> does not attempt to sort <a href="http://en.wikipedia.org/wiki/Code_refactoring" target="_blank">refactorings</a> in order of most common use, or in order of easiest to learn. That&#8217;s OK. Since the book was first published, the list of known, useful <a href="http://www.refactoring.com/catalog/" target="_blank">refactorings</a> has continued to evolve. But learning refactorings in alphabetical order is not necessarily the most pragmatic or friendly approach.</p>
<p>There are a handful of refactorings that are really all you need for the scope of this series of blog posts on refactoring code to Clean Method Hierarchies. We&#8217;ll cover about a half-dozen refactorings that I believe are most useful to learn first, in coming blog posts.</p>
<p>For today, please consider, primarily, the <a href="http://www.refactoring.com/catalog/extractMethod.html" target="_blank">Extract Method</a> refactoring.</p>
<h3>The Extract Method Refactoring</h3>
<p>Extract Method, which most IDE&#8217;s will let you attempt automatically these days, is simply about taking complex methods and extracting smaller bits of named responsibility out of them in the form of new methods. It is simply letting the pregnant cat give birth to her kittens, naturally. One of its best on-line <a href="http://blog.objectmentor.com/articles/2009/09/11/one-thing-extract-till-you-drop" target="_blank">write-ups is here</a>.</p>
<h3>Keeping Modules Really, Really, Insanely Small</h3>
<p>Really, really small means, in Java, median method size of around 5 lines; and median class size of around 5 methods. Insanely small means median method size of 3 or 4 lines, and median class size of 3 methods. Again, the premise is that this code has good enough code coverage.</p>
<p>Although there is more detail involved here (see below), and it can be frightfully hard to keep methods this small when you are not yet skillful at it, it can be astonishing what a positive difference it can make.</p>
<p style="padding-left: 30px;"><em>When modules are really, really small, it begins to become magically easier to read, understand, and modify code &#8212; especially for those who have not seen that code before, or for awhile.</em></p>
<p>Yes, this is my judgment and experience talking. It requires a leap of faith from you. Please see if it&#8217;s  true for you, after you have worked enough code into this kind of shape. And please let me know what you find.</p>
<p>Now onto a few deeper items behind &#8220;small modules.&#8221;</p>
<h3>The Single-Responsibility Principle (SRP)</h3>
<p>The <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle" target="_blank">Single-Responsibility Principle</a> states that every object &#8220;should have a single responsibility, and that responsibility should be entirely encapsulated by the class.&#8221;  But the SRP applies equally to methods and modules at other levels of granularity and abstraction.</p>
<p>And as I was taught the SRP, every module should have a single responsibility means that its components all operate <em>at the same level of abstraction</em>. What the hell is a &#8220;level of abstraction&#8221;?  Indeed. This is not always easily detected and policed.</p>
<p>Think back to the &#8220;building a garage&#8221; example in the <a href="http://patrickwilsonwelsh.com/?p=455" target="_blank">first post</a>. A Clean Method Hierarchy means that at each level of the &#8220;outline,&#8221; each method is SRP-compliant <em>at that level</em>. This doesn&#8217;t even really <em><strong>begin to make sense</strong></em> until you have used the <a href="http://c2.com/cgi/wiki?ExtractMethod" target="_blank">Extract Method</a> refactoring to make lots and lots of methods really, really, insanely small.</p>
<p>One rule of thumb, however: if a method has more than a single level of indentation, it is not likely SRP-compliant: it likely includes code from at least two different levels of abstraction. And it likely has a <a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity" target="_blank">Cyclomatic Complexity</a> that is unnecessarily high. Nested if statements within if statements within if statements are always asking for trouble.</p>
<h3>Cyclomatic Complexity</h3>
<p><a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity" target="_blank">Cyclomatic Complexity</a> is simple the number of discrete flow-of-control paths a module has. In Java, for example, every conditional statement or clause, every loop, every continue statement, and every other return point or exception clause constitutes another level of complexity.</p>
<p>Every method with low enough Cyclomatic Complexity is by definition SRP-compliant and small enough. Wherever you can, shoot for a method-level complexity of 1 or 2 (e.g., a 5-line method with a single If statement).</p>
<p>The reason that Cyclomatic Complexity matters so much in Agile Programming is that complex code attracts more complexity.</p>
<p style="padding-left: 30px;"><em>Code complexity is like crime in a neighborhood: it attracts more crime, which attracts more crime. </em></p>
<p>Complex code is hard code to read, hard code to test, and hard code to modify safely. It contributes to, in Bob Martin&#8217;s pattern language, the &#8220;viscosity&#8221; of code: complexity in a module, alone, can make it substantially easier to &#8220;do the wrong thing&#8221; than to &#8220;do the right thing.&#8221;</p>
<p>As you can read at the bottom of this <a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity" target="_blank">wikipedia write-up</a>, there is increasing evidence that code complexity corresponds with high defect rates. This is like high crime and general urban decay correlating. And it makes intuitive sense to agile programmers. If I cannot easily understand, test, or modify complex code, of course it provides a breeding ground for defects. Defects will tend to lurk in places where they are hard to find, verify, and fix.</p>
<p>We need our object models, our lower level designs, our service layers, our architectures, our builds, and our frameworks to be as simple as possible. Unnecessary complexity is ever an enemy in code as in prose (&#8220;<a href="http://www.bartleby.com/141/strunk5.html" target="_blank">Omit needless words</a>.&#8221;).</p>
<p>But first, we need you to become expert at keeping the small stuff, the easier stuff, insanely simple. Learn to excel at it the way you would learn, as a classical pianist, to play Chopin etudes at insanely high speeds with insanely smooth flow. Learn to excel at it as you would practice military techniques in a safe bootcamp before you are thrown before enemy fire.</p>
<p>Regardless of the level of complexity and code coverage your current or eventual jobs permit, learn to turn the dials to 11 in these exercises, so that when you need them in a pinch, they flow like a jazz solo.</p>
<h3>Squeeze Class</h3>
<p><em>Squeeze Class</em> is the term invented by <a href="http://anarchycreek.com/" target="_blank">Mike (&#8220;@GeePaw&#8221;) Hill</a> for the algorithm the exercises in the first post make you repeat, again and again:</p>
<ul>
<li>Try to extract small methods from larger ones, within a single class</li>
<li>Run into variable scope problems and control flow problems and conditional logic problems that you have to fix first</li>
<li>Try to extract methods again; this time you have more success</li>
<li>Now extract those smaller methods into even smaller methods</li>
<li>Fix, at a lower level, the same kinds of problems you encountered the first time</li>
<li>Now finish extracting those smaller methods</li>
<li>Keep going until you have <a href="http://blog.objectmentor.com/articles/2009/09/11/one-thing-extract-till-you-drop" target="_blank">extracted till you drop</a> &#8212; you can go no further</li>
<li>Now notice, from various clues, that your class full of small methods really &#8220;wants&#8221; to be two or three or four separate classes, each with its own responsibility.</li>
</ul>
<p style="padding-left: 30px;"><em>Squeeze Class is one way to refactor to Clean Method Hierarchies, SRP-compliant methods, and SRP-compliant classes</em>.</p>
<h3>Tracking Test Coverage and Median Complexity Together</h3>
<p>Commercial static analysis tools like <a href="http://www.atlassian.com/software/clover/" target="_blank">Clover</a> will give you handy mechanisms for plotting module size against code coverage throughout a codebase. With Clover, it&#8217;s also trivial to measure and plot complexity and coverage together.  This is a fabulous, actionable measure of how your codebase is deteriorating or improving as an asset as time goes by.</p>
<p>But you can measure code coverage with open source tools, and some IDEs will monitor complexity for you in real-time as well.</p>
<p>For the exercises from the first post, I&#8217;ve provided a <a href="http://patrickwilsonwelsh.com/?p=671" target="_blank">fun, odd, useful mechanism for monitoring size and complexity called Whack-A-Method</a>. For code coverage, I recommend tools like Emma and <a href="http://www.eclemma.org/" target="_blank">Eclemma</a>.</p>
<p>With and without the help of tests and tools, you will need to learn to recognize when a module is violating the SRP. Learn to spot when it is conflating and combining responsibilities that belong in different levels of abstraction. Again, in our book outline metaphor: learn when a chapter really wants to be a section, or a section really wants to be a subsection, or when a subsection needs no title at all.</p>
<h3>Summary: Keep Your Methods Really Small, and SRP Compliant, with Low Complexity</h3>
<p>There is a roteness and mechanistic quality to keeping methods under 5 lines, and classes under 3 or 4 methods. <a href="http://www.google.com/search?client=safari&amp;rls=en&amp;q=paint+the+fence+sand+the+floor&amp;ie=UTF-8&amp;oe=UTF-8#q=paint+the+fence+sand+the+floor&amp;hl=en&amp;client=safari&amp;rls=en&amp;prmd=ivns&amp;source=univ&amp;tbs=vid:1&amp;tbo=u&amp;ei=_x8YTd7DM8G78gbxg6WLAQ&amp;sa=X&amp;oi=video_result_group&amp;ct=title&amp;resnum=3&amp;ved=0CDcQqwQwAg&amp;fp=82b2276fb7f759eb" target="_blank">Paint the fence; sand the floor.</a> That&#8217;s OK. Practice like that for awhile anyway. A lot of new learning has this rote quality while principles and deeper meaning are internalized.</p>
<p>If you are truly committed to learning this Agile Programming magic deeply, you will make this leap of faith like many of us have. And after awhile, you will indeed get a feel for it. You will be able to spot SRP violation.</p>
<p style="padding-left: 30px;"><em>Eventually, you will go from keeping modules small in order to approximate SRP-compliance, to mastering SRP-compliance in a way that automatically results in small modules.</em></p>
<p>And then, magical things will begin to happen in your code. Magical things that you have difficulty expressing to people sometimes, much less justifying.</p>
<p>And if you are like me, Extract Method and Renaming will become a way of life: I use them all the time to learn new code, to learn new problem domains, to spike problems. I use them continually in production code, test code, and toy code.</p>
<p style="padding-left: 30px;"><em>Extract Method and Renaming are two refactorings that are especially useful for learning to keep software truly soft. </em></p>
<p><em>Next Up: </em>We&#8217;ll <a href="http://patrickwilsonwelsh.com/?p=619" target="_blank">dive more deeply into microtests, and test-driving </a>our <a href="http://codingdojo.org/cgi-bin/wiki.pl?KataBankOCR" target="_blank">KataBankOCR</a> problem domain.</p>
]]></content:encoded>
			<wfw:commentRss>http://patrickwilsonwelsh.com/?feed=rss2&#038;p=560</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Agile Programming: Why Bother?</title>
		<link>http://patrickwilsonwelsh.com/?p=521</link>
		<comments>http://patrickwilsonwelsh.com/?p=521#comments</comments>
		<pubDate>Wed, 22 Dec 2010 17:20:09 +0000</pubDate>
		<dc:creator>patrickwilsonwelsh</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://patrickwilsonwelsh.com/?p=521</guid>
		<description><![CDATA[I&#8217;m working on a series of posts that outline a book&#8217;s worth of suggested curriculum on how to learn some of the technical practices that Agile Programming involves. The first post is here. The Myth of Affordable Technical Debt Along &#8230; <a href="http://patrickwilsonwelsh.com/?p=521">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m working on a series of posts that outline a book&#8217;s worth of suggested curriculum on how to learn some of the technical practices that Agile Programming involves. <a href="http://patrickwilsonwelsh.com/?p=455" target="_blank">The first post is here</a>.</p>
<h3>The Myth of Affordable <a href="http://en.wikipedia.org/wiki/Technical_debt" target="_blank">Technical Debt</a></h3>
<p>Along the way, I&#8217;ve re-discovered that too, too many software professionals <em>still</em> misunderstand, fundamentally, what Agile Programming and Software Craftsmanship are about, and why we bother with them. So I&#8217;m summarizing my view on that here. I&#8217;m not recapitulating the history now (later, perhaps). I&#8217;m just trying to gently make the case that <a href="http://xprogramming.com/articles/quality/" target="_blank">sufficient long-term quality is something we can never not-afford</a>.</p>
<p>In the heat of the production pressure to get a User Story out the door by hook or by crook, the discussion about &#8220;how much craftsmanship can we afford here&#8221; does keep arising (with the best intentions on all sides, no doubt). That&#8217;s my context for how and why programmers should learn deep craft. I suggest that almost no-one in software is ready to ask that question.</p>
<h3>By Agile Programming, I Do Mean Computer Programming</h3>
<p>My definition of Agile Programming is computer programming done at <a href="http://manifesto.softwarecraftsmanship.org/" target="_blank">a high level of craft</a>. (Note that in this series of posts, I am <em>not</em> talking about the entire superset of <a href="http://en.wikipedia.org/wiki/Agile_software_development" target="_blank">Agile Software Development practices and principles</a>, some of which are technical, and some of which are not.)</p>
<p>Another definition of Agile Programming is <a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882" target="_blank">Clean Code</a>. These are ways to think about <em>what</em> it is. But <em>why</em> do we do it? It really is all about the smoothest flow of value through the code and the team. It is about highest <a href="http://en.wikipedia.org/wiki/Return_on_Investment" target="_blank">ROI</a>, and lowest <a href="http://en.wikipedia.org/wiki/Total_cost_of_ownership" target="_blank">TCO</a>. Put another way:</p>
<p style="padding-left: 30px;"><em>Any programming practice or choice that does not make or save money for someone, somewhere, someday is not agile, and is not software craftsmanship.</em></p>
<h3>Truly: Why Do we Bother? Are we Being Quality Fanatics?</h3>
<p>We are not being fanatics. <a href="http://patrickwilsonwelsh.com/?p=10" target="_blank">We are avoiding lots and lots of pain</a>.</p>
<p style="padding-left: 30px;"><em>To a new regular-army combatant fresh to Guadalcanal in 1942, it may appear that the combat-veteran marines are completely obsessive-compulsive about cleaning their weapons. That&#8217;s because those fresh arrivals have not had their weapons jam frequently enough in heated enough battle in a nasty jungle. Field stripping a weapon in a way that appears obsessive and fanatic is just pain prevention. Pure and simple.</em></p>
<p>The idea of the high software craft inherent in true Agile Programming is to provide exactly, and only, the highest short-term <a href="http://en.wikipedia.org/wiki/Return_on_Investment" target="_blank">ROI</a> and long-term <a href="http://en.wikipedia.org/wiki/Return_on_Investment" target="_blank">ROI</a>, and the lowest short-term and long-term <a href="http://en.wikipedia.org/wiki/Total_cost_of_ownership" target="_blank">TCO</a> for a codebase as simply another <a href="http://en.wikipedia.org/wiki/Asset" target="_blank">asset to be managed</a> (around which, for example,  <a href="http://en.wikipedia.org/wiki/Capital_expenditure" target="_blank">CAPEX</a> and <a href="http://en.wikipedia.org/wiki/Operating_expense" target="_blank">OPEX</a> expenditures must be carefully predicted and managed these days).</p>
<p>Too frequently, we are asked to build straw houses when only brick houses will do, and we have no way of making it clear how <a href="http://en.wikipedia.org/wiki/False_economy" target="_blank">false an economy this is</a>. In a <a href="http://myagileeducation.com/2010/need-we-always-write-clean-code/" target="_blank">comment thread on a great blog post of a friend of mine&#8217;s</a>, the debate rages about, essentially, the economics of Clean Code (&#8220;CC&#8221;) versus Quick and Dirty (&#8220;QD&#8221;).</p>
<p>Two things: I have frequently found that the advocates of QD have not bothered to learn CC deeply. They are arguing from at least partial ignorance and fear. (That is not true, BTW, of Naresh Jain, who is a very advanced Agile Programmer.) If you really are as good at Agile Programming as <a href="https://elearning.industriallogic.com/gh/submit?Action=PageAction&amp;album=blog2009&amp;path=blog2009/2010/sufficientDesign&amp;devLanguage=Java" target="_blank">Josh Kerievsky</a>, or <a href="http://xprogramming.com/articles/quality/" target="_blank">Ron Jeffries</a>, or <a href="http://anarchycreek.com/2009/05/26/how-tdd-and-pairing-increase-production/" target="_blank">Mike Hill</a>, or <a href="http://blogs.agilefaqs.com/" target="_blank">Naresh Jain</a>, then yeah, I&#8217;m willing to have User-Story-specific discussions about specific short-term &#8220;speed vs quality&#8221; tradeoffs. Otherwise, I&#8217;m not willing to have that discussion with you. All these guys have spent more than 10,000 hours test-driving. Once you&#8217;ve done that, let&#8217;s talk about CC vs QD again.</p>
<p style="padding-left: 30px;"><em>Only if you are deeply, deeply expert at test-driving clean code does it make sense for you to talk about breaking the rules. Only then do you have a feel, and deep knowledge about, the rules for breaking the rules. </em></p>
<p>The other thing is that QD experts (the <a href="http://www.joelonsoftware.com/items/2009/09/23.html" target="_blank">Duct-Tape Programmer</a>) are not taking long-term ROI and TCO into account fully enough. Yes, I want to ship product as regularly and quickly as I possibly can, with least thumb-twiddling. But no, I don&#8217;t want an asset in my portfolio made of duct tape and WD40. What&#8217;s the duty cycle on that thing? One release? Two?</p>
<p>The QD experts are arguing that QD works for a User Story, or an Iteration, or a Release. Well, yeah, you can have a roof over your head faster if you build with straw. So what? Is that a way of saying &#8220;I don&#8217;t believe in storms.&#8221; ? In the specific context of getting good-enough releases out the door for startup ventures, are we making it clear enough when we are distinguishing between prototypes designed to win investment capital, and production code designed to live for 25 releases?</p>
<p style="padding-left: 30px;"><em>The questions &#8220;How much craftsmanship can we afford for this Iteration? or this Release? or this User Story?&#8221;,  when asked about anything but spikes or prototypes, are </em>nearly<em> always premised in </em><a href="http://en.wikipedia.org/wiki/False_economy" target="_blank"><em>false economy</em></a><em>. </em></p>
<p>As my friend Dave LeBlanc says: Later == Never. You will never be able to &#8220;Refactor&#8221; your straw house into a brick house. It will need to be rebuilt from scratch, eventually. Factor this into your ROI and TCO estimates. Oh, again, in the context of CC vs QD for startups, there is another sad corollary I&#8217;ve seen borne out time after time:</p>
<p style="padding-left: 30px;"><em>Every prototype ships, and becomes long-term production code. Especially for boot-strapped startups, whose investors will not agree to purchase or fund prototypes. </em></p>
<p>High software craft, Agile Programming, are not knob polishing, or gold plating. Agile Programming is about getting it right the first time, and getting it right over and over again. It is about optimizing the long-term return on an investment.</p>
<p>How come our codebases cannot last as long as our best cars? Why do most codebases that have not exhausted their business value end up going through expensive, dangerous rewrites?  Aren&#8217;t these rewrites fundamentally avoidable? You bet they are.</p>
<p style="padding-left: 30px;"><em>The fundamental unit of waste in software development is also the fundamental unit of denial: the gigantic codebase rewrite.</em></p>
<p>We can do much, much better than that. That&#8217;s what Agile Programming and software craft is about.</p>
<p>This level of dedication to quality is very much like Honda dedication to quality. It&#8217;s not about burlwood on the dashboard, or spoilers on the trunk, or pinstripes down the sides (though if you want those in the GUI, we can do that too, as in an Infiniti). It&#8217;s about a <a href="http://patrickwilsonwelsh.com/?p=20" target="_blank">300,000-mile-duty-cycle drivetrain, come hell or high water</a>. It&#8217;s about the industry growing out of its addiction to rewriting business-valuable codebases after a few releases, <a href="http://patrickwilsonwelsh.com/?p=45" target="_blank">because we can&#8217;t work them anymore</a>.</p>
<p>How many 1993 Chevies does anyone in Michigan see out there on the roads, still purring along with few issues? Few. But you know what? There are still lots of 1993 Toyota Camries out there on these snowy, badly-maintained roads. Until recently I drove one every day (and I still own it as a spare-loaner-beater). It&#8217;s a little dinged up. And the AC just gave out (after 18 years!). But it also still starts in 6 degree weather, and runs smooth at 80mph, and gets 30mpg. Because those Camries were made with highest long-term ROI and lowest long-term TCO in mind.</p>
<p>So, throughout <a href="http://patrickwilsonwelsh.com/?p=455" target="_blank">the series of &#8220;How To&#8221; posts</a>, please keep this definition of the what and why of Agile Programming in mind.</p>
]]></content:encoded>
			<wfw:commentRss>http://patrickwilsonwelsh.com/?feed=rss2&#038;p=521</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Agile Programming: Lesson One (Part One)</title>
		<link>http://patrickwilsonwelsh.com/?p=455</link>
		<comments>http://patrickwilsonwelsh.com/?p=455#comments</comments>
		<pubDate>Thu, 16 Dec 2010 19:44:02 +0000</pubDate>
		<dc:creator>patrickwilsonwelsh</dc:creator>
				<category><![CDATA[Agility]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SW Mgmt]]></category>

		<guid isPermaLink="false">http://patrickwilsonwelsh.com/?p=455</guid>
		<description><![CDATA[What is Agile Programming, Anyway? Why Bother? Great questions: I&#8217;ve tried to address them in this other post. Meanwhile, for programmers who wish to learn how to become more skillful, valuable, and excellent, the paragraphs and exercises below are for &#8230; <a href="http://patrickwilsonwelsh.com/?p=455">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h3>What is Agile Programming, Anyway? Why Bother?</h3>
<p>Great questions: I&#8217;ve <a href="http://patrickwilsonwelsh.com/?p=521" target="_blank">tried to address them in this other post</a>. Meanwhile, for programmers who wish to learn how to become more skillful, valuable, and excellent, the paragraphs and exercises below are for you.</p>
<h3>The Bad News: Lots of Learning, Poorly Arranged</h3>
<p>Agile Programming with <a href="http://en.wikipedia.org/wiki/Object-oriented_programming" target="_blank">object-oriented programming languages</a> takes a good long while to learn to do &#8220;well enough.&#8221;</p>
<p>One chunk of practices at a time, or in a single chunk of total mastery, the books ask you to pick up technical practices, principles, and patterns:  <a href="http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530" target="_blank">TDD</a>. <a href="http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/ref=pd_bxgy_b_img_b" target="_blank">Refactoring</a>. <a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882" target="_blank">Clean Code</a>. Etc, etc.</p>
<p>It&#8217;s not entirely unfair to say this:</p>
<p style="padding-left: 30px;"><em>As currently described by the various books and training available, learning Agile Programming is itself a waterfall project.</em></p>
<p>Your journey will be incremental and iterative, but the books themselves are, without intending it, phase-like. Even when they provide good tutorial, they provide it in the context of an isolated practice or set of practices. Too many books presume you have read the other books already. And some of them are truly only reference, with no real tutorial at all.</p>
<p>Even if the learning path were better (and a better learning path is exactly what I hope to provide here), and even if you are an experienced programmer, it takes thousands of hours to master Agile Programming well enough that you can be reliably productive on a mature, healthy agile team in the real world.</p>
<p>&#8220;Good enough&#8221; Agile Programming skill, by that standard, requires an amount of learning equivalent to an engineering Masters Degree, coupled with many more hours of supervised residency. You&#8217;ll need to learn the material using &#8220;breakable toy&#8221; codebases, and then (in a sense), all over again in real enterprise codebases. And it&#8217;s a moving target: the craft keeps advancing in the direction of saving us and our stakeholders time and money, which is what all software craft is intended to accomplish.</p>
<p>By the way, please don&#8217;t call it &#8220;<a href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank">TDD (Test-Driven Development)</a>,&#8221; which is one critical practice in Agile Programming, but only one practice:</p>
<p style="padding-left: 30px;"><em>Calling Agile Programming TDD is like calling a car a transmission. Trust me: you&#8217;re gonna need the whole car.</em></p>
<h3>The Good News: You Can Start Small</h3>
<p>What you want is to learn a thin slice of Refactoring, along with a thin slice of TDD, and a thin slice of Clean Code, etc. One iteration at a time, one increment at a time. I intend to help you with a learning path that looks just like that.</p>
<p>So, as a programmer committed to becoming skillful in Agile Programming, where do you start? I have a suggestion that I&#8217;ve been marinating in for some time now. It might not surprise you, at this point, that I do not recommend starting by learning how to Test-Drive. Instead, I recommend starting with just a bit of Refactoring. Learn how to clean up small messes. Learn how to turn fairly small Java messes into spotlessly <a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882" target="_blank">Clean Code</a>.</p>
<p>Programmers should begin by learning how to make a few methods in a couple of classes spotlessly clean, exactly because only when they are truly expert and speedy at that, will they be able to make sensible choices when faced with horrific codebases, tight deadlines, mediocre colleagues, or any two of those three.</p>
<p style="padding-left: 30px;"><em>Once you&#8217;re good at cleaning small messes, and at test-driving small chunks of code, you&#8217;ll be ready for larger messes and larger test-driving projects. </em></p>
<h3>Lesson One: Refactoring to a <em>Clean Method Hierarchy</em></h3>
<p>If life throws at you a decently test-protected, somewhat ugly Java class (which won&#8217;t happen all that frequently, I admit), learn how to get it into a decent Clean Hierarchy of <a href="http://c2.com/ppr/wiki/WikiPagesAboutRefactoring/ComposedMethod.html" target="_blank">Composed Methods</a> &#8212; a Clean Method Hierarchy. This is my term for a class whose hierarchy is outlined and organized into short, clear, descriptive methods at each hierarchical level.</p>
<p>Get good at cleaning up small messes in this specific way, THEN learn how to test-drive a replacement for the refactored code. (In a separate post, I&#8217;ll try to justify why I think this makes a good starting point; meanwhile, I&#8217;m going to ask you to make that leap of faith.)</p>
<p><strong>Hierarchy: Outline Within Outline</strong></p>
<p>Complex systems are naturally hierarchical, and we use outlining as a tool to help the right hierarchy emerge. Books, symphonies, organizations &#8212; all tend to have natural hierarchies. (They also tend to be more network-like than hierarchical, but that&#8217;s a concern for later.) If you were writing a book called How to Build Your Own Garage, would it&#8217;s Table of Contents start like this?</p>
<ul>
<li>Buy more two-stroke fuel</li>
<li>Fuel up the big chainsaw</li>
<li>Take down any big Willow trees out back</li>
<li>Rent a stump grinder</li>
<li>Remove the tree stumps</li>
<li>Cut the trunks into logs</li>
<li>Have logs and stump debris hauled away&#8230;</li>
</ul>
<p>Well, I hope it would not. Like any thoughtful book author, you would likely outline your book, then re-outline, then outline again.</p>
<p>One outline draft, translated into Java, might something like this:</p><pre class="crayon-plain-tag">public void buildYourGarage() {
  chooseYourSite()
  removeAnyNearbyTreesWithPotentiallyInvasiveRoots()
  clearTheSite()
  digTheFooterTrenches()
  pourFooterAndFoundation()
  frameTheWalls()
  roofTheGarage()
  installServices()
  installTheDoor()
  finishingTouches()
}</pre><p>But of course, few books, like few Java classes, can get away with hierarchies this shallow. Again, being the thoughtful book author you are, you would sooner or later see that another hierarchical level is trying to emerge here. It seems that buildYourGarage() really wants to be just a few methods at a larger hierarchical level than the ones above:</p><pre class="crayon-plain-tag">public void buildYourGarage() {
  prepareTheSite()
  pourTheFoundation()
  buildTheStructure()
  finishingTouches()
}</pre><p>The rest of our hierarchy might then look like this:</p><pre class="crayon-plain-tag">private void prepareTheSite() {
  chooseYourSite()
  removeAnyNeaarbyTreesWithPotentiallyInvasiveRoots()
  clearTheSite()
}</pre><p></p><pre class="crayon-plain-tag">private void pourTheFoundation() {
  digTheFooterTrenches()
  pourFooterAndFoundation()
}</pre><p></p><pre class="crayon-plain-tag">private void buildTheStructure() {
  frameTheWalls()
  roofTheGarage()
  installServices()
  installTheDoor()
}</pre><p>Believe it or not, and like it or not, the consensus of Agile Programmers is that this is the sort of hierarchy into which we need to organize our code.</p>
<p>This is your ends, the way you want your individual classes to read when you are done test-driving or refactoring them. A class that is a Clean Method Hierarchy reads like a really well-written book outline, with clear and sensible hierarchical levels: chapters, sections, sub-sections, and sub-sub-sections. You can see how a good author has thought through a book&#8217;s natural hierarchy in a really well-organized Table of Contents.</p>
<p>Most Java code I read does not read this way. Indeed, much of it reads not like a Table of Contents, but like an Index that someone has resorted in page-number order. Like an exploded view of a car&#8217;s parts. Like the inventory list for a large hardware store after a tornado. You get the idea.</p>
<p><strong>So Again, Don&#8217;t Test-Drive Clean Hierarchies First</strong></p>
<p>Again, for reasons I&#8217;ll provide elsewhere, based in my coding, coaching, and training experience, I really think you just start by <a href="http://en.wikipedia.org/wiki/Code_refactoring" target="_blank">refactoring</a> code that could have been test-driven to a Clean Method Hierarchy, but <em>WAS NOT</em>. This drives home certain principles, patterns, practices, and techniques in a way that will make your test-driving more meaningful and easier to learn later. I predict. We&#8217;ll revisit the whole idea of test-driving Clean Method Hierarchies in another post.</p>
<p><strong>Some Exercises to Start With</strong></p>
<p>I&#8217;ll give you the following two little code laboratories in which to practice learning how to get to a Clean Method Hierarchy state. These are inspired by <a href="http://blog.objectmentor.com/articles/2009/09/11/one-thing-extract-till-you-drop" target="_blank">Uncle Bob Martin&#8217;s Extract Till You Drop blog post</a>. The rules for the Challenges are fairly simple:</p>
<ul>
<li>Keep all existing tests, such as they are, running green as much as possible. Also try to purposefully break them sometimes, to see what kinds of coverage they give you in the code (more on that later, too).</li>
<li>Rename each entity (project, package, class, method, variable) at least twice, as you learn more and more about what it should be doing</li>
<li>By the time you are done, no method should contain more than 8 lines of code (this also applies to test methods), and most methods should be in the neighborhood of 4 or 5 lines of code, including declarations and return statements.</li>
</ul>
<h3>The &#8220;Somewhat Ugly&#8221; Challenge</h3>
<p>Learn to start with a somewhat-ugly class (an implementation of part of a kata called the <a href="http://codingdojo.org/cgi-bin/wiki.pl?KataBankOCR" target="_blank">BankOCRKata</a>), and refactor the code till it&#8217;s gorgeous. Do that lots of times (dozens), several ways. Here are three ways, right off the bat:</p>
<ol>
<li>Refactor all of the methods in the AccountNumber class, without extracting any of them to new classes. You can change variable scope however you like.</li>
<li>Same as first way, except try not to turn method-scope variables into fields on the class. Try instead to find some other way to accomplish your method extractions.</li>
<li>Same as first way, except extract groups of related methods to new classes however you see fit. Try to keep each class to no more than 3 public methods, and no more than 5 private helper methods. As you extract behavior to new classes, write new tests for the public methods in new test classes.</li>
</ol>
<p><a href="https://github.com/PillarTechnology/Training-Codebases/tree/master/Refactor_BankOCR_Whack_A_Method" target="_blank">You can find the Java code for this first Challenge here</a>, in the<a href="https://github.com/organizations/PillarTechnology" target="_blank"> Pillar Technology github repository</a>. It&#8217;s set up to work out of the box as an Eclipse project. (BTW, <a href="http://patrickwilsonwelsh.com/?p=671" target="_blank">as I describe here</a>, it is now wrapped up in a little testing framework called Whack-A-Method, which can help you police your compliance with the above goals as you go.)</p>
<h3>EM-Pathy: The &#8220;Way Uglier&#8221; Challenge</h3>
<p>Then tackle a much uglier class, and refactor it till it&#8217;s gorgeous. Again, repeat this lots of times. <a href="https://github.com/PillarTechnology/Training-Codebases/tree/master/EM-Pathy" target="_blank">You can find the Java code for this second Challenge here</a>, in the <a href="https://github.com/organizations/PillarTechnology" target="_blank">Pillar Technology github repositor</a>y. It too is set up to work out of the box as an Eclipse project.</p>
<h3>Clean Method Hierarchy: Practices and Principles Under the Hood</h3>
<p>In other posts, there are a few things I&#8217;ll introduce you to (should you not already know them) as you learn to master this technique of refactoring classes into well-organized hierarchies. For the exercises in this post, I believe the list includes the following items (I reserve the right to revise this list as smart people give me feedback):</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Code_coverage" target="_blank">Code Coverage </a></li>
<li>Naming and <a href="http://www.refactoring.com/catalog/renameMethod.html" target="_blank">Renaming</a></li>
<li>Basic <a href="http://en.wikipedia.org/wiki/Code_refactoring" target="_blank">Refactoring</a></li>
<li><a href="http://en.wikipedia.org/wiki/Command-query_separation" target="_blank">Command/Query Separation</a></li>
<li>The <a href="http://c2.com/cgi/wiki?ExtractMethod" target="_blank">Extract Method</a> refactoring</li>
<li>The <a href="http://www.jetbrains.com/resharper/webhelp/introduce-field.html" target="_blank">Introduce variable/field </a>refactorings (and scope change refactorings generally)</li>
<li>The <a href="http://www.refactoring.com/catalog/extractClass.html" target="_blank">Extract Class refactorin</a>g</li>
<li>The <a href="http://www.refactoring.com/catalog/moveMethod.html" target="_blank">Move Method refactoring</a></li>
<li>The <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle" target="_blank">Single-Responsibility Principle (SRP)</a></li>
<li><a href="http://blog.objectmentor.com/articles/2009/09/11/one-thing-extract-till-you-drop" target="_blank">Keeping Modules Really, Really, Insanely Small</a></li>
<li>Squeeze Class</li>
</ul>
<p>You can read about several of these in more detail <a href="http://patrickwilsonwelsh.com/?p=560" target="_blank">in this following post. </a></p>
<p>If you practice understanding and using these and only these principles, patterns, and practices, you can get to a point where, indeed, your methods and classes are very clean, and you have great test coverage.</p>
<p>And maybe, for a little while, that&#8217;s not just OK, but awesome. At that point, you will be ready for different learning.</p>
<h3>What Not To Learn Yet</h3>
<p>Eventually you will have to learn agile patterns, principles, and practices that touch on dependency injection, test doubles, storytesting/acceptance-test-driven development, complex object models (Gof Design Patterns, small and large refactorings), databases and data modeling, continuous integration, version control strategies, continuous deployment, heavyweight frameworks, convention-based frameworks, concurrency, pair-programming, domain-driven design, dynamically typed vs statically typed languages, etc, etc.</p>
<p>But not today. In fact, not this month, nor in the coming few months. You may very well want to explore some of that material; good for you if you do.</p>
<p>In the meantime, though, if you really are committed to becoming expert at Agile Programming, and if you really are puzzled about where to start, why not start by mastering the art of keeping one class gorgeously clean (which may involve breaking it up into a few classes), and gorgeously tested?</p>
<p>You might say that with this first bit of knowledge to master, what you are really learning to conquer is modular programming. That&#8217;s fine. We&#8217;ll have more for you to learn later, but truth be told, most programmers in the software industry have not yet mastered modular programming as initially described well more than 3o years ago &#8212; and Agile Programming gives us just the tools to measure how modular our code truly is.</p>
<p>I guarantee you this: Agile Programming Lesson One a bite-sized bit of learning to start with, and it cannot possibly hurt you. If you get stuck in the above exercises, try reading ahead <a href="http://patrickwilsonwelsh.com/?p=560" target="_blank">to this next bit of explanation</a>, to see if it helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://patrickwilsonwelsh.com/?feed=rss2&#038;p=455</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Selenium RC Patterns: Links that, uh, Go to Pages</title>
		<link>http://patrickwilsonwelsh.com/?p=381</link>
		<comments>http://patrickwilsonwelsh.com/?p=381#comments</comments>
		<pubDate>Wed, 08 Sep 2010 21:46:39 +0000</pubDate>
		<dc:creator>patrickwilsonwelsh</dc:creator>
				<category><![CDATA[agile testing]]></category>
		<category><![CDATA[Agility]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://patrickwilsonwelsh.com/?p=381</guid>
		<description><![CDATA[[Part of a series of posts on Java Selenium RC patterns I find useful.] In the last post, we looked at self-verifying PageObjects: Java classes that are &#8220;testable representations&#8221; of a web app page, and that automatically verify for us, on &#8230; <a href="http://patrickwilsonwelsh.com/?p=381">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>[Part of a <a href="http://patrickwilsonwelsh.com/?p=332" target="_blank">series of posts on Java Selenium RC patterns I find useful</a>.]</p>
<p>In the last post, we looked at <a href="http://patrickwilsonwelsh.com/?p=343" target="_blank">self-verifying PageObjects</a>: Java classes that are &#8220;testable representations&#8221; of a web app page, and that automatically verify for us, on instantiation, that we have indeed arrived on the actual web page we intended to.</p>
<p>So how do we handle page flow? I&#8217;ve handled it numerous ways in the past. I don&#8217;t like any of them anymore. Ultimately what I wanted, and now have, is something that mimics the way an actual &lt;a href&gt;&lt;/a&gt; takes you to a new page: classes that represent html links that, when clicked by Selenium, take you (predictably) to new PageObjects or pane objects. So the Selenium RC Java mechanics for page flow are no longer cluttering the test code, nor, in fact, the PageObjects.</p>
<p>Instead, I use what I call <strong>ElementObject</strong> classes. <strong>PageLink</strong> and <strong>DhtmlLink</strong> classes, in particular, behave like little <a href="http://en.wikipedia.org/wiki/Factory_pattern" target="_blank">Factories</a>. When instantiated, these objects are told which PageObject to instantiate when Selenium &#8220;clicks&#8221; on the actual html links those classes represent. Whew!  Confused yet? Let&#8217;s see some code, starting with a package structure, and let&#8217;s explain ElementObjects more generally.</p>
<h3>Background: ElementObjects</h3>
<h3>
<p><div class="wp-caption alignnone" style="width: 477px"><a href="http://patrickwilsonwelsh.com/wp-content/uploads/2010/09/Picture-21.png"><img class=" " title="ElementObject package structure" src="http://patrickwilsonwelsh.com/wp-content/uploads/2010/09/Picture-21.png" alt="ElementObject package structure" width="467" height="200" /></a><p class="wp-caption-text">util.elements package structure</p></div></h3>
<p>Above are the ElementObject classes I use, in <a href="http://htmlunit.sourceforge.net/" target="_blank">HTMLUnit</a> style, to represent discrete  html element varieties and their behaviors.</p>
<p>(Note: The <a href="http://patrickwilsonwelsh.com/?p=343" target="_blank">introductory post in this  series</a> tells you how to get all of this code. If you have the code, explore this little object tree, starting with the abstract BaseElement class. Explore how different pages and panes use these element classes.)</p>
<p>Let&#8217;s tour a slice of the BaseElement tree briefly. Here is the abstract BaseElement class:</p><pre class="crayon-plain-tag">package util.elements;
package util.elements;

import util.browserdriver.BrowserDriver;

public abstract class BaseElement {
  public String locator;

  public BaseElement(String locator) {
    this.locator = locator;
  }

  public final boolean isPresent() {
    return BrowserDriver.isElementPresent(locator);
  }

  public final boolean isVisible() {
    return BrowserDriver.isElementVisible(locator);
  }
}</pre><p>So all elements, since they extend BaseElement, have locators (which are all <a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/#selectors" target="_blank">CSS selectors</a>, as discussed in the <a href="http://patrickwilsonwelsh.com/?p=343" target="_blank">previous post</a>). The isPresent() method (using the conventional Selenium isElementPresent() method), uses vanilla Selenium to reveal whether any element is indeed present in the browser&#8217;s representation of the HTML, rendered (usually) by a real HTTP Request/Response cycle. Similarly, isVisible() reveals whether  an element is &#8220;visible&#8221; after any dynamic call that does NOT involve a real HTTP Request/Reponse cycle. Under the covers, isVisible() uses jQuery to check visibility in the in-memory DOM. The short answer to &#8220;Why have both?&#8221; is that isVisible() is heavier-weight and slower, but usually works when isPresent() does not. The even shorter answer is that browser manufacturers hate each other, and sometimes ignore the <a href="http://www.w3.org/" target="_blank">w3c</a>, but they all standardize on jQuery.</p>
<p>So, for example,  ClickableElement extends BaseElement, and adds just a predictable smidgeon of clickable-ness:</p><pre class="crayon-plain-tag">package util.elements;
package util.elements;

import util.browserdriver.BrowserDriver;

public class ClickableElement extends BaseElement {

  public ClickableElement(String locator) {
    super(locator);
  }

  public void click() {
    BrowserDriver.click(locator);
  }
}</pre><p>And further down the tree, a CheckBox gives us the ability to check a checkbox, or if it is one of those fancy graphical checkbox simulacra, we can just click() on it using the inherited method in ClickableElement. Either way, we have checkbox-looking things covered.</p><pre class="crayon-plain-tag">package util.elements;

import util.browserdriver.BrowserDriver;

public class CheckBox extends ClickableElement {

  public CheckBox(String locator) {
    super(locator);
  }

  public void check() {
    BrowserDriver.check(locator);
  }
}</pre><p>Notice all of the static method calls to BrowserDriver.java. We&#8217;ll cover him in deep detail later, but he is our <a href="http://en.wikipedia.org/wiki/Decorator_pattern" target="_blank">Decorator</a>/<a href="http://en.wikipedia.org/wiki/Facade_pattern" target="_blank">Facade</a> for Selenium and jQuery calls. It provides <a href="http://en.wikipedia.org/wiki/Singleton_pattern" target="_blank">singleton</a> access to DefaultSelenium and several of its useful methods, as well as several convenience methods we have found useful.</p>
<p>The point here is that only down at the ElementObject level does our framework &#8220;know&#8221; about BrowserDriver, and the nuts-and-bolts mechanics of getting Selenium (or whatever frameworks we want) to do stuff to real web page elements.</p>
<p>And of course the most essential point is that in our PageObjects, we can represent every HTML element as one of these types, keeping the test framework code nice and <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself" target="_blank">DRY</a>.</p>
<p>In general, this is how the ElementObjects work. Caveat Lector: I don&#8217;t have a full, complete set of these in my sample code; I have the ones I have been using all the time. Feel free to extend this package as necessary (and to send me your contributions).</p>
<h3>PageLinks and DhtmlLinks</h3>
<p>Now the meat of this post: how do we get from page to page?</p>
<p>First let&#8217;s look at how a PageLink client uses it for a field on a PageObject. Let&#8217;s look at a test for creating a Task in FatFreeCRM:</p><pre class="crayon-plain-tag">package task;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.Random;

import org.junit.Before;
import org.junit.Test;

import bizdomain.common.BaseWebTest;
import bizdomain.common.Common;
import bizdomain.pages.TasksPage;
import bizdomain.panes.CreateTaskPane;
import bizdomain.panes.DueTodayTaskStrip;

public class CreateTaskTest extends BaseWebTest {
  private TasksPage tasksPage;
  private String taskName;

  @Before
  public void setup() {
    tasksPage = Common.mainNavTabsSet.tasks.clickToNewPage();
    taskName = createRandomTaskName();
  }

  @Test
  public void canCreateAndCompleteLunchTodayTask() throws Exception {
    assertTrue(tasksPage.noPendingTasksLabel.isVisible());
    CreateTaskPane createTaskPane = tasksPage.createTaskLink.clickToNewContainer();

    DueTodayTaskStrip taskStrip = createTaskPane.createTask(&quot;Today&quot;, &quot;Lunch&quot;, taskName);
    assertFalse(tasksPage.noPendingTasksLabel.isVisible());

    String expectedCategory = &quot;Lunch&quot;;
    assertTrue(taskStrip.taskNameLabel.getText().contains(taskName));
    assertEquals(taskStrip.whenLabel.getText(), expectedCategory);

    taskStrip.clickCompleteBox();
    assertFalse(taskStrip.isVisible());
  }

  private String createRandomTaskName() {
    Random intGenerator = new Random(System.currentTimeMillis());
    int randomInt = intGenerator.nextInt();
    return &quot;testTask&quot; + randomInt;
  }

}</pre><p>Note in the setUp() method that we get to a TasksPage by clicking clickToNewPage() on the tasks field on a MainNavigationTabsSet class, which looks like this:</p><pre class="crayon-plain-tag">package bizdomain.panes;

import util.BasePane;
import util.elements.PageLink;
import bizdomain.pages.AccountsPage;
import bizdomain.pages.CampaignsPage;
import bizdomain.pages.ContactsPage;
import bizdomain.pages.DashBoard;
import bizdomain.pages.LeadsPage;
import bizdomain.pages.OpportunitiesPage;
import bizdomain.pages.TasksPage;

public class MainNavigationTabsSet extends BasePane {
  public static final String PANE_IS_LOADED_CSS = &quot;div[id=tabs]&quot;;

  public PageLink dashBoard;
  public PageLink tasks;
  ...

  public MainNavigationTabsSet() {
    dashBoard = PageLink.create(
        PANE_IS_LOADED_CSS + &quot; a:contains('Dashboard')&quot;, DashBoard.class);
    tasks = PageLink.create(PANE_IS_LOADED_CSS + &quot; a:contains('Tasks')&quot;,
        TasksPage.class);
    ... 
 }

  @Override

  public String getPageLoadedCssLocator() {
    return PANE_IS_LOADED_CSS;
  }</pre><p></p><pre class="crayon-plain-tag">}</pre><p>Note that tasks field is of type PageLink, parameterized with a  class. And notice that when you instantiate a PageLink, you call a PageLink.create() method. Between these two things, we ensure that when we ask Selenium to click on that tasks link, we end up instantiating an actual TasksPage PageObject.</p>
<p>It&#8217;s a smidge confusing, perhaps. Bear with me. Here is the PageLink class:</p><pre class="crayon-plain-tag">package util.elements;

import util.browserdriver.BrowserDriver;

public class PageLink&lt;T&gt; extends ClickableElement {
	private Class&lt;T&gt; clazz;

	public PageLink(String locator, Class&lt;T&gt; clazz) {
		super(locator);
		this.clazz = clazz;
	}

	public T clickToNewPage() {
		try {
			click();
                        BrowserDriver.waitForPageToLoad( 
                              BrowserDriver.STANDARD_PAGE_LOAD_WAIT_TIME);
			return clazz.getConstructor().newInstance();
		} catch(Exception e) { 
			throw new RuntimeException(e);
		}
	}
}</pre><p>Notice that PageLink extends ClickableElement, so whatever element a PageLink object represents, we can click on it. Yay! Notice also that when we instantiate PageLink, it expects a css locator.</p>
<p>Most critically and cryptically, notice all the Java generics magic, which can be confusing Java syntax to many programmers. The upshot is noisy framework code, but it keeps explicit casting out of the test code. It keeps the test code very simple indeed.</p>
<p>Now notice what happens when a test method calls the clickToNewPage() method: first, we click on ourselves (which will, if you look at click() in ClickableElement, get BrowserDriver to click on the locator we were instantiated with. Then the tricky bits. We call clickToNewPage(), which asks BrowserDriver.waitForPageToLoad() to let us know when the new page is done loading. Because Selenium can tell when a real HTTP Request/Response cycle is done, this will work for real pages with actual, different urls.</p>
<p>Then, aha! Our little Factory method uses a little lightweight Java <a href="http://en.wikipedia.org/wiki/Reflection_(computer_science)" target="_blank">Reflection</a> to construct and return us an instance of that PageObject whose Class we passed in on instantiation. In MainNavigationTabsSet above, you can see that the tasks PageLink is declared and instantiated with TasksPage.class. So indeed, a <a href="http://patrickwilsonwelsh.com/?p=343" target="_blank">self-verifying</a> TasksPage PageObject gets constructed and handed back to test code when that test calls Common.mainNavTabsSet.tasks.clickToNewPage().</p>
<p>So a bit of Java design forethought gives us this ability to click on a tasks link, and proceed without further ceremony to a TasksPage. Our page flow does, in fact, much mirror the HTML and pages in the production code.</p>
<p>Our test code (above) is, again, succinct and expressive, and only a link to a page need know how to get there. Just like in real life.</p>
<p>Similar to PageLink, DhtmlLink provides us a little factory for dynamic html behaviors (clickToNewContainer()), whether they have Ajax-like server conversations, or just change the html in the browser. In this case, because we don&#8217;t have a real HTTP Request/Response cycle, we don&#8217;t call waitForPageToLoad() on Selenium. Selenium has no idea whether the &#8220;page&#8221; or &#8220;pane&#8221; we need is now visible. Our PageObjects take care of that. We just click(). Like PageLink, DhtmlLink uses much of the same Java generics gobbletygook to keep track of concrete Class types to be instantiated at our request. In this case, the base class is BasePane, not BasePage:</p><pre class="crayon-plain-tag">package util.elements;

import util.BasePane;

public class DhtmlLink&lt;T&gt; extends ClickableElement {
	private Class&lt;T&gt; clazz;

	public DhtmlLink(String locator, Class&lt;T&gt; clazz) {
		super(locator);
		this.clazz = clazz;
	}

	public T clickToNewContainer() {
		try {
			click();
			return clazz.getConstructor().newInstance();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}</pre><p>Next up: what the heck is this BrowserDriver thing, and how might we use it?</p>
]]></content:encoded>
			<wfw:commentRss>http://patrickwilsonwelsh.com/?feed=rss2&#038;p=381</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Selenium RC Patterns: Self-Verifying Page Objects</title>
		<link>http://patrickwilsonwelsh.com/?p=343</link>
		<comments>http://patrickwilsonwelsh.com/?p=343#comments</comments>
		<pubDate>Sat, 04 Sep 2010 00:53:12 +0000</pubDate>
		<dc:creator>patrickwilsonwelsh</dc:creator>
				<category><![CDATA[agile testing]]></category>
		<category><![CDATA[Agility]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SW Mgmt]]></category>

		<guid isPermaLink="false">http://patrickwilsonwelsh.com/?p=343</guid>
		<description><![CDATA[[Part of a series of posts on Java Selenium RC patterns I find useful.] What we Want: Expressive, Succinct Tests Let&#8217;s say I want to test that I can log into an app. I want my Selenium RC Java test &#8230; <a href="http://patrickwilsonwelsh.com/?p=343">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>[Part of a <a href="http://patrickwilsonwelsh.com/?p=332" target="_blank">series of posts on Java Selenium RC patterns I find useful</a>.]</p>
<h3>What we Want: Expressive, Succinct Tests</h3>
<p>Let&#8217;s say I want to test that I can log into an app. I want my Selenium RC Java test code to look something like this, because I want it to read, aloud, the way I would describe actually logging in and checking that everything went mostly OK:</p><pre class="crayon-plain-tag">@Test
public void canLoginToFatFreeCRM() throws Exception {
  LoginPage loginPage = new LoginPage();
  DashBoard homePage = loginPage.login(BrowserDriver.DEFAULT_USERNAME,
                          BrowserDriver.DEFAULT_PASSWORD);

  assertTrue(homePage.isLoaded());
}</pre><p>Several techniques make this possible, but the one we will focus on in this blog post is the notion of a<strong> self-verifying <a href="http://code.google.com/p/selenium/wiki/PageObjects" target="_blank">PageObject</a>, </strong>which is essentially a &#8220;testable representation&#8221; of an actual web app page we wish to traverse, manipulate, and test. So my LoginPage class, above, allows me succinct manipulation of the corresponding login page in the system under test.</p>
<p>Note that this test knows nothing about Selenium. Indeed, neither does the LoginPage class (below). More on that later. Note that this test does not include any waitUntilPageIsFrickinLoaded() calls, nor (worse) Thread.sleep() code, and very little direct instantiation of PageObjects. The page flow mechanics is encapsulated elsewhere. Note also that as I go from page to page, I don&#8217;t explicitly assert that I got there. I shouldn&#8217;t have to. My test should be able to take that for granted. It turns out that assertions are being made under the covers about having arrived successfully on intermediate pages, but that code is abstracted away. That&#8217;s what this post covers.</p>
<p>The only useful assertion in the test proper is that, once I have logged in with proper credentials, I arrive safely at the homepage (and even this assertion in the test is redundant, and included here only to reveal intention; the DashBoard page is also self-verifying).</p>
<h3>Glance-Readability</h3>
<p>A test as short and expressive as the one above passes the &#8220;glance readability&#8221; test. Anyone familiar with automated testing semantics, and the biz language of this CRM domain, ought to be able to grasp what this test does at a single glance.</p>
<p>Suffice to say, we want our Selenium RC tests, as much as they can, to be this succinct. And, again, that requires that they stick to expressing page traversal and manipulation in the local biz-specific language of the web app&#8217;s business domain. So, finally, let&#8217;s see the under-the-covers page self-verification mechanics.</p>
<h3>PageObjects as I Use Them</h3>
<p>The <a href="https://github.com/PillarTechnology/SeleniumPatterns" target="_blank">selenium-rc-patterns</a> sample Java codebase that illustrates all of the patterns in this series of posts talks to a localhost copy of a Rails project called <a href="http://www.fatfreecrm.com/" target="_blank">Fat Free CRM</a>. If you want to learn a bit about this app, you can play with a <a href="http://demo.fatfreecrm.com/" target="_blank">hosted sample version here</a> (you have to sign up for an account first, which is easy).</p>
<p>This <a href="http://en.wikipedia.org/wiki/Customer_relationship_management" target="_blank">CRM</a> system has discrete web pages like a Dashboard (home page, essentially), and pages for Tasks, Leads, Campaigns, Contacts, Accounts, and Opportunities. For each of these actual, production pages, my selenium-rc-patterns Eclipse project contains a matching <a href="http://code.google.com/p/selenium/wiki/PageObjects" target="_blank">PageObject</a> with methods and fields that provide access to the services on that page.</p>
<p>Above, when you ask an instance of a LoginPage to login(username, password), then the TextFields and PageLink type know how to return us a <a href="http://code.google.com/p/selenium/wiki/PageObjects" target="_blank">PageObject</a> that should then be cast to a DashboardPage and returned. (More on that in another post.)</p>
<p>Selenium RC developers have been using a <a href="http://code.google.com/p/selenium/wiki/PageObjects" target="_blank">PageObject</a> pattern for awhile. The pattern dates back, at least, to the original <a href="http://htmlunit.sourceforge.net/" target="_blank">HTMLUnit</a>, whose API rather strongly encourages you to represent your pages under test as extensions of what it calls an HtmlPage. I don&#8217;t use Se 2 yet (might someday, might not), so I don&#8217;t use its PageFactory pattern.</p>
<p>Instead, I use my own PageObjects that extend a BasePage (or BasePane), partly so that I can control how and when PageObjects are instantiated, and verify <strong><em>automatically and ambiently</em></strong> on instantiation that Selenium is indeed on that page. Again, that&#8217;s much of what keeps the above test code so simple: I&#8217;m not explicitly waiting for a page to load, and I&#8217;m not asserting all over the place that I&#8217;ve successfully arrived on a given page.</p>
<p>So, my LoginPage class has a login() method that accepts a username and password (we&#8217;ll cover the return types of these fields and methods in another post that describes how page-flow works):</p><pre class="crayon-plain-tag">package bizdomain.pages;

import util.BasePane;
import util.elements.PageLink;
import util.elements.TextField;

public class LoginPage extends BasePane {
  public static final String PAGE_IS_LOADED_CSS = &quot;input[id=authentication_username]&quot;;

  private TextField userNameField;
  private TextField passwordField;
  private PageLink&amp;lt;DashBoard&amp;gt; loginButton;

  public LoginPage() {
    super();
    userNameField = new TextField(&quot;input[id=authentication_username]&quot;);
    passwordField = new TextField(&quot;input[id=authentication_password]&quot;);
    loginButton = PageLink.create(&quot;input[id=authentication_submit]&quot;,
        DashBoard.class);
  }

  @Override
  public String getPageLoadedCssLocator() {
    return PAGE_IS_LOADED_CSS;
  }

  public DashBoard login(String userName, String password) {
    userNameField.enter(userName);
    passwordField.enter(password);
    return loginButton.clickToNewPage();

  }
}</pre><p></p>
<h3><span style="font-style: normal;">Verifying That the Production Page has Been Loaded</span></h3>
<p><span style="font-style: normal;">The real point of my flavor of PageObject pattern is the self-verifying bit. Let&#8217;s dive into that &#8212; not later, but now. </span></p>
<p><span style="font-style: normal;">Note that each of these PageObjects extends BasePane, and has a PAGE_IS_LOADED_CSS constant:</span></p><pre class="crayon-plain-tag">package bizdomain.pages;
public class LoginPage extends BasePane {
  public static final String PAGE_IS_LOADED_CSS = &quot;input[id=authentication_username]&quot;;</pre><p><span style="font-style: normal;">In the LoginPage constructor way above up there, you can see we first explicitly call super() on BasePane. Here is BasePane:</span></p><pre class="crayon-plain-tag">public abstract class BasePane {
  public BasePane() {
    waitUntilLoaded();
  }

  public final boolean isLoaded() {
    return BrowserDriver.isElementPresent(getPageLoadedCssLocator());
  }

  public final boolean isVisible() {
    return BrowserDriver.isElementVisible(getPageLoadedCssLocator());
  }

  public final void waitUntilLoaded()  {
    BrowserDriver.waitForElementVisible(getPageLoadedCssLocator());
  }

  public abstract String getPageLoadedCssLocator();
}</pre><p><span style="font-style: normal;">You can see that this constructor calls waitUntilLoaded(), which makes a static call to a method on our BrowserDriver (the Facade / Decorator that handles all of the actual Selenium calls) in order to loop until our LoginPage (in this case) actually is loaded. The argument supplied is the result of calling getPageLoadedCssLocator(). </span></p>
<p><span style="font-style: normal;">But wait! That&#8217;s an abstract method! So Yes, we have something very like a <a href="http://en.wikipedia.org/wiki/Template_method_pattern" target="_blank">template method pattern</a> here in waitUntilLoaded(): the concrete implementation of getPageLoadedCssLocator() on LoginPage returns that PAGE_IS_LOADED_CSS constant String.</span></p>
<p><span style="font-style: normal;">Deep, deep under the covers, the BrowserDriver.waitForElementIsVisible() method looks like this:</span></p><pre class="crayon-plain-tag">public static void waitForElementVisible(String cssLocator)  {
  for (int second = 0;; second++) {
    if (second &amp;gt;=
 Integer.valueOf(BrowserDriver.STANDARD_DHTML_LOAD_WAIT_  TIME) / MS_PER_SECOND)

  fail(&quot;Timeout waiting for element &quot; + cssLocator + &quot; to become visible.&quot;);
    if (isElementVisible(cssLocator)) break;
    sleepForASecond();
  }
}

public static boolean isElementVisible(String cssLocator) {
  injectJqueryIfAbsent();
  return executeJavascript(JqueryCodeFactory.getVisibilityCode(cssLocator)).equals(TRUE);
}</pre><p>We&#8217;ll discuss the BrowerDriver class at length elsewhere. And we&#8217;ll also discuss the injectJqueryIfAbsent() method, which we hope an upcoming Selenium RC release will obviate.</p>
<p><span style="font-style: normal;">The upshot of the waitForElementVisible() method and the LoginPage and BasePane code above is that <strong><em>the LoginPage object will not successfully finish instantiating</em></strong> until Selenium can <strong><em>successfully verify that a unique element on that page has been loaded.</em></strong> In other words, once a LoginPage instance is loaded in memory, we actually are on the LoginPage, by definition, as long as that CSS element selector syntax is correct. Voila, automatic, ambient page flow assertion. </span></p>
<p><span style="font-style: normal;">This is much of how we get our test methods so succinct. The PageObjects take care of verifying for us, at instantiation, that we have safely arrived on their corresponding production app web pages.</span></p>
<p><span style="font-style: normal;">Caveat Lector: there is a flaw in my code I have yet to squeeze out:  duplication between a BasePane, used above, which I usually use for dynamic changes in the HTML, and a BasePage, which presumes that a real HTTP Request/Response cycle has occurred. I will collapse those two together shortly. </span></p>
<p><span style="font-style: normal;">Next: we&#8217;ll talk about reusable HTML Element objects, and how the linkish ones know, in my code, how to return the PageObject we wish to traverse to next. </span></p>
<p><span style="font-style: normal;"><br />
</span></p>
]]></content:encoded>
			<wfw:commentRss>http://patrickwilsonwelsh.com/?feed=rss2&#038;p=343</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Selenium RC Java Patterns: Watch this Space</title>
		<link>http://patrickwilsonwelsh.com/?p=332</link>
		<comments>http://patrickwilsonwelsh.com/?p=332#comments</comments>
		<pubDate>Thu, 12 Aug 2010 18:30:40 +0000</pubDate>
		<dc:creator>patrickwilsonwelsh</dc:creator>
				<category><![CDATA[agile testing]]></category>
		<category><![CDATA[Agility]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://patrickwilsonwelsh.com/?p=332</guid>
		<description><![CDATA[My opinion about through-the-web-GUI enterprise-app-testing, in general, is that it is like driving on ice in a blizzard: not something you want to do lots and lots of, because sooner or later you&#8217;ll get into deep trouble. But given your &#8230; <a href="http://patrickwilsonwelsh.com/?p=332">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>My opinion about through-the-web-GUI enterprise-app-testing, in general, is that it is like driving on ice in a blizzard: not something you want to do lots and lots of, because sooner or later you&#8217;ll get into deep trouble. But given your context (living in MI, for me), driving on ice in the snow is something that is useful to know how to do well, in a pinch.</p>
<p>I&#8217;ve blogged in the past about <a href="http://patrickwilsonwelsh.com/?p=47" target="_blank">low-TCO (Total Cost of Ownership) Selenium RC testing in general</a>, and about  <a href="http://patrickwilsonwelsh.com/?p=32" target="_blank">how much of your automated testing budget should be allocated to different kinds of testing at different points in an agile transformation</a>. Of late, I have been helping teams learn to use Selenium RC, in Java, to test web apps through their GUIs. Once the above Caveat Tester is spoken, I help them do the Selenium RC testing that they feel they MUST do as well as possible.</p>
<p>I have been diving more deeply into it for several clients recently, and finding and refining some useful patterns I had not needed or found before (with the help of several colleagues). And, admittedly, some of what I am doing is refining my old patterns in response to things like Refactoring pressure. In general, I am devising increasingly DRY Object Oriented Selenium RC Java patterns. I recently<a title="Why your Selenium tests are so dang brittle, and what to do about it." href="http://agile2010.agilealliance.org/testing.html#5496" target="_blank"> presented on them at Agile 2010</a>.  Using git, you  can checkout the code that illustrates these patterns <a href="https://github.com/PillarTechnology/SeleniumPatterns" target="_blank">from github here</a>.</p>
<p>I intend to share each of these patterns with you, each in its own blog post, in coming weeks.</p>
<p>So watch this space for blog posts covering the following topics:</p>
<ul>
<li><a href="http://patrickwilsonwelsh.com/?p=343" target="_blank">Clean, clear test methods</a></li>
<li><a href="http://patrickwilsonwelsh.com/?p=343" target="_blank">Separating DRY test-framework code from &#8220;wetter&#8221; tests, and separating reusable, generic test-framework code from biz-domain-specific framework code</a></li>
<li>Wrapping Selenium and other frameworks in Facade/Decorator that provides static Singleton test framework access.</li>
<li>Pushing all framework static Singleton references down into base classes and html element classes.</li>
<li><a href="http://patrickwilsonwelsh.com/?p=343" target="_blank">Biz-Domain-specific Page Objects that are &#8220;lazy loaded&#8221; and self-verifying, and that encourage Dry OO test code</a></li>
<li><a href="http://patrickwilsonwelsh.com/?p=343" target="_blank">Always using CSS as a DOM element locator strategy; never using XPath</a>.</li>
<li>Injecting the entire jQuery framework into pages under test, in order to verify visibility of elements that appear after dynamic html or Ajax calls.</li>
<li><a href="http://patrickwilsonwelsh.com/?p=381" target="_blank">Generic HTML Element objects (ala HtmlUnit&#8217;s API) that encourage Dry OO test cod</a>e</li>
<li><a href="http://patrickwilsonwelsh.com/?p=381" target="_blank">DhtmlLink and PageLink Factory classes</a> that are instantiated with the <a href="http://patrickwilsonwelsh.com/?p=343" target="_blank">Page Object classes</a> they should &#8220;go to,&#8221; and that automatically return those objects when &#8220;clicked&#8221;.</li>
<li>Pushing out access to common elements across several pages to static Singletons on base page classes.</li>
</ul>
<p>The code I link to above illustrates all of these patterns, expecting (for now) to run against a demo instance of a Rails app called <a href="http://www.fatfreecrm.com/" target="_blank">FatFreeCRM</a>, which is available for you to play with at <a href="http://demo.fatfreecrm.com/login" target="_blank">http://demo.fatfreecrm.com/login</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://patrickwilsonwelsh.com/?feed=rss2&#038;p=332</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
