7/31/2009

Test objects, not methods


As you may or may not know, I am part of the team pushing the boundaries of Agile & XP at Industrial Logic with Josh Kerievsky. As such, I'll be posting some of my rantings in our new Industrial Blogic album (the blog portion of our truly kick-ass "Greatist Hits" eLearning platform).
My debut there is a classic, but so grossly unknown topic. Summarize it as so: if you want to test your private methods, take out a ruler and slap yourself over the wrist. As a personal mentor of mine, J.B. Rainsberger, used to tell me: "if you really need to test that private method, then it should go somewhere else dude."
Check out the rest of the story here, and while you're in add our Industrial Blogic to your RSS reader, we'll be keeping it hot there.

7/08/2009

Checking In (but no, not source control)



So sorry, I've been sooooo lax about posting any new thoughts (very busy training for a triathlon) - trust me though I've had many, my "rants todo" list is billowing over. Soon, they will be here in all their glory for you to chew on, I promise (to both of us).

In the meantime, I thought you'd be interested to know that today we experienced two very very unique moments:
12:34:56 07/08/09 and 04:05:06 07/08/09
Won't happen again in any of our lifetimes. Wow, pretty darn neat, huh? One day past a full moon to boot.

And also, hopefully to keep you really distracted from my absense, I thought I'd treat you to what I thought to be a pretty damn funny joke my dad forwarded my way:

A Dog Story

A guy is driving around the back woods of
Montana and he sees a sign in front of a broken down shanty-style house: 'Talking Dog For Sale ' He rings the bell and the owner appears and tells him the dog is in the backyard.

The guy goes into the backyard and sees a nice looking
Labrador retriever sitting there.

'You talk?' he asks.

'Yep,' the Lab replies.

After the guy recovers from the shock of hearing a dog talk, he says 'So, what's your story?'

The Lab looks up and says, 'Well, I discovered that I could talk when I was pretty young. I wanted to help the government, so I told the CIA. In no time at all they had me jetting from country to country, sitting in rooms with spies and world leaders, because no one figured a dog would
be eavesdropping.'

'I was one of their most valuable spies for eight years running. But the jetting around really tired me out, and I knew I wasn't getting any younger so I decided to settle down. I signed up for a job at the airport to do some undercover security, wandering near suspicious characters and listening in. I uncovered some incredible dealings and was awarded a batch of medals.'

'I got married, had a mess of puppies, and now I'm just retired..'

The guy is amazed. He goes back in and asks the owner what he wants for the dog.

'Ten dollars,' the guy says.

'Ten dollars? This dog is amazing! Why on earth are you selling him so cheap?'

'Because he's a liar. He never did any of that shit.'

;-) C ya soon...
MB

5/16/2009

TDD: The Rhythm


Good TDD, well real TDD, provides the team with a heartbeat.

Everyone has a heartbeat, you know what it's like: continuous and clear, smoothly flowing, subtle yet ever so present and soothing. Its unlikely that you're explicitly listening to it, but you are without doubt subconciously aware of the supreme comfort and reassurance that heartbeat provides you each and every minute of your day. It keeps you alive!

Same is true with software development. And while Iterations, Stand-ups, and CIT no doubt provide an essential macro-heartbeat, those things aren't what give us that minute to minute assurance analogous to our human heartbeat. That's where TDD comes in - true TDD provides us that comforting development heartbeat to actually get us productively and happily through the day.

It provides the transition from story card to failing storytest (acceptance test). Then from failing storytest to the first failing microtest (unit test). Then minutes later to the first passing microtest. Then minutes later to the next failing microtest, then the next passing microtest, and our first refactoring. Then minutes later to our next quick cycle of "red/green/refactor". Then within an hour our first check-in. Then a few more "red/green/refactor" cycles and another checkin. And before you know it, after one of those cycles, boom, a passing storytest! A high-five and a final checkin, then home by 6 to see the kids.

Do you hear it? Thum-THUMP, Thum-THUMP, Thum-THUMP...RedBar-GREENBAR, RedBar-GREENBAR, RedBar-GREENBAR...
A development heartbeat.

It's this rhythm that guides you, that keeps you on track. Its what gives you the constant feedback to know, at every step of the way, that you're growing the right design, that you're satisfying the customer's needs, and that you haven't broken any windows. It's what allows you to move freely and move fast. It's this rhythm that makes you feel good. It's this rhythm that makes you feel alive and happy.

Ask anyone whose felt it. Once you've actually truly experienced this rhythm - this heartbeat - I assure you, just as with your human heartbeat, you'll find it unbearable to ever live without.


4/02/2009

PropertyFor Sale

Properties. And, Java. Lots of languages really, but let's look at Java. Every Java (and other langs too) application of any size is going to be using some properties. Typically, they'll be held in a "myspecializedvalues.properties" file, but not necessarily. For this example, let's assume you are using such a file (and can then thus use Java's built-in property management mechanism), but again, its not really the point. And this approach can be applied no matter what format you choose to store your properties.

The point of this is to show you a better way to manage - a better way to encapsulate and access - your properties so that the implementation is hidden behind an expressive interface, easy for anyone to understand and use.

The point is to show the PropertyFor class, and to tell you why its better than what you probably have in place.

So, this example has a strategy factory class that needs to make its decisions based on a property setting, this property having a true/false (boolean) value. It starts off looking like this:
public class GeneratorFactory {
public String propFileName =
"ELearningSettings.properties";

public GenerationStrategy projectGenerationStrategy() {
if (shouldIgnoreCode())
return new GenerateWithoutCode();
else
return new GenerateWithCode();
}

private boolean shouldIgnoreCode() {
Object valueObj = getProperty("CODE_IS_USELESS");
if (valueObj != null)
return Boolean.parseBoolean((String)valueObj);
return false;
}

private Object getProperty(String key) {
Properties properties = new Properties();
try {
properties.load(new FileInputStream(propFileName));
} catch (IOException e) {
throw new RuntimeException(e);
}

return properties.get(key);
}
}

You'll hopefully notice something about this factory. First, it's primary responsibility is to serve up the correct strategy to its caller. Of course though, you'll also notice that not only does this class do its primary purpose, but it also has a lot of low-level knowledge about how to obtain the information it needs to make its decision. It knows all sorts of things about icky java property mania.

Now, if this is the lone property in your system, than maybe this is okay and doing any kind of extraction here might be YAGNI (you might though, even if that is the case, be bothered by that fact that this class clearly violates the SRP, nonetheless...).

Of course though, this is not the case, and so let's assume that although this is the only class you see in this example there are in fact more properties in your system and more users of them.

So, the logical thing to do is to extract that property reading management into its own class, happy to have its sole responsibility being providing property values. You do so, and end up with this new "Settings" class:
public class ELearningSettings {
public String propFileName =
"ELearningSettings.properties";

public Object getProperty(String key) {
Properties properties = new Properties();
try {
properties.load(new FileInputStream(propFileName));
} catch (IOException e) {
throw new RuntimeException(e);
}

return properties.get(key);
}
}

public class GeneratorFactory {
public GenerationStrategy projectGenerationStrategy() {
if (shouldIgnoreCode())
return new GenerateWithoutCode();
else
return new GenerateWithCode();
}

private boolean shouldIgnoreCode() {
Object valueObj =
ELearningSettings.getProperty("CODE_IS_USELESS");
if (valueObj != null)
return Boolean.parseBoolean((String)valueObj);
return false;
}
}
You slap five with your pair and check in, this is much better! Now your factory can do it's job without having any internal worry about where the settings (properties) are really coming from or how they're implemented. Any other users of properties also get the same luxury. A big improvement, no doubt.

Many systems I've seen have figured this much out, and have this in place. A "Settings" class that hides the details of how to look up properties, all you have to give it is the key to the property you want.

But, this has limitations.

First, and as many will figure out and solve on their own, a sprawl of the property key strings hard-coded in the various users of the properties. You want to change this key? Have fun chasing all the uses down. Of course you could create a constants file for these keys, and have the callers only know the constants (which, in Java at least, provides the big benefit of being able to leverage you IDE when you want to change its name), but is that really enough?

Second, yes your factory doesn't know about "ELearningSettings" or the "java...Properties" guts, but it does still have the job of knowing the format of these property values ('Object' in this case) and how to turn that into what it really wants, a boolean.

Third, particularly if haven't created a constants file (in response to the first problem), how easy is it for future developers to go to one place and see all the possible properties/settings the system has available for them?

There may be more limitations, but that's enough for me.

So, our answer to each of these questions is where the magic happens, the MBark of this article. We evolve our generic "Settings" class into a domain-friendly "PropertyFor" class:
public class PropertyFor {
public static String propFileName =
"ELearningSettings.properties";

public static boolean shouldIgnoreCode() {
Object valueObj = getProperty("CODE_IS_USELESS");
if (valueObj != null)
return Boolean.parseBoolean((String)valueObj);
return false;
}

private static Object getProperty(String key) {
Properties properties = new Properties();
try {
properties.load(new FileInputStream(propFileName));
} catch (IOException e) {
throw new RuntimeException(e);
}

return properties.get(key);
}
}

public class GeneratorFactory {
public GenerationStrategy projectGenerationStrategy() {
if (PropertyFor.shouldIgnoreCode())
return new GenerateWithoutCode();
else
return new GenerateWithCode();
}
}
What did we do here? Well, we've taken all the knowledge highlighted above as our limitations and removed it from our factory (really, from all of the users of settings), and put it into our "Settings" class - which, as a result, now becomes a more useful, expressive PropertyFor utility.

So, you'll see our factory now has to worry just about choosing a strategy, and no longer has any overhead related to obtaining the values it needs to make its decision. More specifically, it doesn't know where the settings come from, doesn't know the details of how to access them or the keys that identify them, and it doesn't know what raw format they come in. The factory knows it needs the boolean value of whether or not to "ignore code", and it gets that in one clear, simple line of code.

Further, you've got the beauty of expressive methods on singular class to be very domain-centric in assisting other programmers to access the available setttings/properties for your system - these methods, not only being clearly and expressively named, but also being typed appropriately for ultimate ease to the consumer. And of course, when you need to change the name of the setting and/or the name the callers know it by, no problemo.

So, that's really the main meat.

For good measure though, we take a moment to improve the design of our PropertyFor class. First, this isn't the only boolean setting we have (use your imagination) so we should have a nice clear reusable method to handle our boolean typed settings:
public class PropertyFor {
public static String propFileName =
"ELearningSettings.properties";

public static boolean shouldIgnoreCode() {
return boolanValueFor("CODE_IS_USELESS");
}

private static boolean boolanValueFor(String key){
Object valueObj = valueFor(key);
if (valueObj != null)
return Boolean.parseBoolean((String)valueObj);
return false;
}

private static Object valueFor(String key) {
Properties properties = new Properties();
try {
properties.load(new FileInputStream(propFileName));
} catch (IOException e) {
throw new RuntimeException(e);
}

return properties.get(key);
}
}


And then, it really is pretty inefficient of us to read the properties file over and over, so let's take care of doing that just once and being done with it:
public class PropertyFor {
public static String propFileName =
"ELearningSettings.properties";

private static Properties properties;
static {
loadProperties();
}

private static void loadProperties() {
properties = new Properties();
try {
properties.load(new FileInputStream(propFileName));
} catch (IOException e) {
throw new RuntimeException(e);
}
}

public static boolean shouldIgnoreCode() {
return boolanValueFor("CODE_IS_USELESS");
}

private static boolean boolanValueFor(String key){
Object valueObj = properties.get(key);
if (valueObj != null)
return Boolean.parseBoolean((String)valueObj);
return false;
}
}
So there you have it: PropertyFor.

And, of course, this isn't a post about TDD, but here is the test that was in place and passing before and after any of these refactorings went down:
public class GenerationStrategyFactoryTest {
@Test
public void needingACodelessStrategy() {
propertiesFileIs("CodelessGenerationStrategy");
assertTrue(strategy() instanceof GenerateWithoutCode);
}

@Test
public void needingACodeStrategy() {
propertiesFileIs("IncludeCodeGenerationStrategy");
assertTrue(strategy() instanceof GenerateWithCode);
}

private void propertiesFileIs(String fileNameBase) {
String filePath = "testdata/"
+ fileNameBase + ".properties";
PropertyFor.propFileName = filePath;
}

private GenerationStrategy strategy() {
return new GeneratorFactory().
projectGenerationStrategy();
}
}
As an exercise, go ahead and write the test you think I have for the PropertyFor class, because of course you know I do!


ps// I'm really not liking this code highlighter library so far. Any other Bloggers have good suggestions for a good library?!?

3/28/2009

Doing The Right Thing And Getting It Done

Been following my man Corey as he moves along on his Journeyman Tour (which I posted about on InfoQ at its onset), in fact had dinner with him tonight!

Here's a talk he did recently on "Practice", which I'm totally in agreement with. Check it.


Practice - Corey Haines from 8th Light on Vimeo.

Keep on keepin' on, Corey!

3/27/2009

Killing "Quality"


So, a guy walks into a bar...

No, just kidding. But seriously though...

You walk into a bar and order a "low quality" beer (tough economy these days). What does this mean to you? That it'll come out with a bug swimming in it? That it will be served heated up? That it will be skunked? Glass only half full?

No, of course not. You'd be appalled, outraged. Have every right to ask for your money back. This place has acted in bad faith, they've acted unacceptably. You leave angered and vow to never return.

Your wife wants you to drop $600 on a new Louis Vuitton bag (you gotta buy cheap beer and she' still asking for Louis?!?), because it's a "top quality" product. Does she describe it this way because she knows it has less likelihood of falling apart the minute she gets it, or its colors smearing, or it having holes in the bottom? Again, no. These things are assumed to be absent. In the rare case you do happen to find anything like this, you are sure to invoke "return to sender, no questions asked".

I could continue on this way throughout various types of products, but I suppose you get the point.

Well, this ain't the case with our industry (Software Development). So I ask ye: WTF, man?

We use the word "quality" as an indicator of both "value" and/or "defect" presence, interchangeably.

When someone says "high quality" they could very well be talking about the absence of defects or they could be talking about the presence of value. And by software standards, neither would be an inappropriate use of the word.

Not so in the bar, not with your beer. Why then for us? Again I ask, WTF?

I know, I know. Some of you are sitting there saying (correctly), "hey, wait, agile pays attention to customer feedback to iterate towards a higher quality solution. We're talking about 'value presence' there." Or maybe your saying, "Our company's website says 'highest quality product in the industry!'. That's talking about 'value presence' too! That's what we mean when we say 'quality'."

Well, maybe so (and good for you, seriously). But I bet many of you still call your testers "the QA folk". "QA", as in Quality Assurance, as in "Those who ensure quality". But really, is their (primary) function that of ensuring 'value presence', or of ensuring 'defect absence'? Look, don't get me wrong, on a healthy agile team these wicked cool cats ARE involved in 'ensuring high value', but at the end of the day that isn't why you're calling them "QA'ers".

I've seen my share of "quality review" meetings, or fancy charts of "quality metrics", or annual budgets that talk of "quality goals" ... where in each of these cases, "quality" is talking about DEFECTS.

When was the last time someone described the benefits of TDD without mentioning, excitedly, "increased quality"? (And, yes indeed, I am certainly just as guilty as the next guy.)

So, why do I care? Why the rant?

Because, it's an indication of the generally absurdly high level of tolerance our industry has for defects.

That we describe defect density with the same word that we use to describe product "value" (to our customer/consumer) is gross.

Heck, I'd go as far as to say its a part of the reason that we have such a generally high tolerance in the first place. It's confusing and it is misleading. It's too easy to masquerade our defect problems as a "quality improvement initiative" or some other politically wimpy label.

When our customers get a bunch of "bugs in their beer" why aren't they appalled and outraged? Why aren't we? Why don't they storm out and vow to never come back? Why is it so damn okay to have defective software? For the third time, WTF?

Don't get me wrong, I'm not saying we should have an absolute "zero defect, period" attitude, that's simply unrealistic considering what we do. But we should have a low enough tolerance for defects that it makes no sense for us to use the word "quality" when talking about them.

"Quality" should be used as a measure of functional/aesthetic utility to our consumer, and not as a measure of defects. Really, it should just be assumed that defects are generally absent. This should just be implied in what it means to be a Professional.

So:

I hereby propose we as software professionals and businessmen stop using the word "quality" to mean a "measure of defects".

Well then, what word will we use? I polled Twitterverse with this question and received lots of great responses, but the group's choice as winner, courtesy of one Brian "Big Ball Of Mud" Foote, is this:
Shittiness.

Software with minimal defects has a "low degree of shittiness"; lots of defects means it has a "high degree of shittiness".

Of all the tweep responses though, overall my very favorite was from Lisa Crispin who said, "I have never liked measuring defects so it's hard to think about what to call it."

Nice, now that actually says it all. Something tells me that Lisa's company does not simply think of their testers as "the QA folk". There is hope!

3/22/2009

TDD: The Synergy


TDD. What does this stand for?

Test Driven Development.

Said another way: Development, driven by tests.

Notice, the acronym doesn't stand for test driven design. Not test driven analysis. Not test driven coding. Nope, not even test driven testing. It is, again, test driven development.

TDD is not a "task". It's not a thing we do in addition to doing design, or in addition to writing production code, or in addition to "writing" stories. Rather, TDD it is the way we design, the way we write code, the way we define a story. It is the way we do development.

When done well, TDD exists at root of nearly everything we do in our agile team - it is the team's minute-to-minute comforting heartbeat.

TDD means that "writing a story" equates to specifying in an automated acceptance/story test (most often using FitNesse, Selenium, WaTiR, or something similar) "what it will look like" for a story to be working once we've implemented it. How the new application feature monickered on the story card must behave for it to be DONE.

TDD means that "designing" equates to specifying in an automated unit/micro test (most often using a member of the xUnit family of tools) "what it will look like" for any particular object to work once we've implemented it. In other words, what the expected behavior of that object is.

TDD means that "coding" equates to letting that unit test tell us when we've written working production code. Possibly more importantly, it means that "coding" equates to letting those passing unit tests ensure that our object continues to work (satisfy it's expected behavior) while we mercilessly refactor that object to keep it super clean and expressive.

And, in case you didn't notice in the above assertions, it means that our development is driven by tests. This means that the test is written first. The existing [failing] test is what drives us to conjure up production code. The test is the only reason for us to write a line of code. It's the only way we know what code to write - the test is our specification. Yes, we can write production code first then try to write a unit test to verify it's implementation, but, in addition to the mechanics of that likely being extremely difficult and counter-productive, that's simply not TDD.

Make no mistake about it. True TDD, at the acceptance (Story/Service) test level, is an act of analysis. And true TDD, at the micro (unit/object) test level, is an act of design. In a single statement: True TDD is much less an act of verification (as the "test" part of the name might accidentally and incorrectly imply) as it is an act of specification.

In summary, TDD provides the fundamental synergy between and foundation for all of our development "tasks" that enables us to truly build the right software and to build the software right. It ensures quality2 - which, in the end, is the only true way for us to go fast and go fun.



** Upon further review, authors are changing the catchy phrase "ensures quality2" to the more appropriate phrase of "ensures high quality and low shittiness"
 
/* */