Ted’s Rants and Raves by Ted M. Young

January 8, 2012

Test-First Development vs. Test-Driven Development

Filed under: Testing, Agile, etc.

I was out having lunch with a colleague of mine and we had gotten onto the subject of TDD and how I missed doing it, even though I did test-first development where possible. He then asked me about the difference between TDD, test-driven development, and TFD, test-first development. For me, there’s a big difference, and one that I wanted to write about.

TDD Means Lots of Fast Cycles

First, some background. Up until I recently switched to a different team, I was on one of the product application teams at Guidewire Software, working on the BillingCenter insurance billing system. For architectural reasons that I won’t go into here, tests run slowly. For example, from the time I tell IDEA to start running the test and I get a success or failure result can be anywhere from 45 seconds to a couple of minutes, or even more. If you’re used to tests running quickly, which I define as completing in under 2 seconds, then you may not understand how long even 45 seconds is. Try this experiment next time you run a test: after you hit the “run” button, start a 45 second timer and force yourself to not touch the IDE or editor until the timer is done. 45 seconds is a long time to stare at the screen waiting, right? This is the difference between being able to do TDD and doing TFD.

TDD and TFD have one obvious thing in common: you write the test first, run it, watch it (hopefully!) fail, and then write production code to make it pass. Once the test passes, you may refactor, or do another cycle. You keep doing this until your story is done, or your timebox is over.

The difference is, in TDD you write very little code in each cycle, and your tests are pretty granular, which means that you may be cycling several, if not even dozens, times per minute. With TFD, you’re still writing the test before the code (so you get all of the “thinking from the caller’s point of view” benefits), but you’re spending more time each cycle writing code because the overhead of each cycle is so large. I mean, it’s huge: if you tried to take the small steps in TFD that you would do in TDD, you’d be 10-30x less productive! And that’s not even counting the breaks in context every time you’re sitting staring at the screen waiting for the test to complete. This means your tests are more complicated, the test fixtures are bigger, or you’re writing more than one test per cycle.

You can optimize the work by writing the code to make the test pass while you’re waiting for that test to run, but that’s a just a bandage over the problem. Not to mention what happens if the test ends up passing, when you thought it must fail, and you have to undo the code you wrote to understand why it passed when it shouldn’t have. This doesn’t happen often, but when it does, it’s frustrating.

TFD Means Fewer and Larger Steps

What’s interesting is that it’s exactly like working on large stories instead of small stories, i.e., breaking down the work into small pieces: batch sizes and inventory. In Lean Software development, you want to minimize work-in-progress (aka inventory, or things that are not yet Done), and Agile, in general, you want to get quick feedback on small pieces of work so that you know you’re heading in the desired direction. You also want to minimize hand-offs, where important context can be lost in the transfer.

By doing TFD, and taking larger steps—i.e., bigger batch sizes—you’re potentially writing more code than you need because for each cycle, you’re simply writing more production code (and usually more test code as well, increasing the inventory of untested tests). In TDD, you will likely end up with less code that meets the requirements of the story because for each test, you’re always writing the absolute minimum amount of code to pass that test and no more. Once the test passes, you stop writing more code and move on to the next test.

In terms of hand-offs, if you’re waiting more than 5-10 seconds for the test to finish, you’ve lost your context. This is no different then having to hand-off the context of what you were doing to someone else, except in this case, that someone else is you. If you’re pairing, you think you might not lose the context as quickly because you have your pair-partner to fall back on, but you’d be wrong. I can’t remember how many times my pair-partner and I looked at each other after a test failed, and said, “uhh, what were we doing?” Which likely means you’ll be making a mistake somewhere because you forgot something that turns out to be important.

I wish I had empirical evidence to back this up, but everyone I’ve ever talked to about this agrees that there’s a huge difference in the quality of the code when doing TDD vs. TFD (yes, this is certainly a biased sample!). No small part of it has to do with being able to stay in the Flow in TDD, that you simply can’t do in TFD.

TFD is What Happens When You’re Not Doing TDD

One lesson here is that if you’re not always doing TDD, it’s all too easy for the codebase to get to the point where it’s no longer possible to do TDD. Once you’re there, it can be extremely expensive to get back to the point of being able to do TDD, which may not even be feasible. In our situation, getting our tests to the point where we can do TDD is a huge amount of effort, one that will likely require several people 18-24 months of work. Is it worthwhile? Absolutely. Unfortunately, because it’s hard to express the quality and productivity difference between TFD and TDD, it’s not deemed an “all hands on deck” crisis, so it won’t get done soon and, in fact, may never get done (because we’re constrained by the number of good Java developers we can hire), i.e., we may simply move to a different platform first.

February 24, 2011

Sometimes it IS a Hardware Problem

Filed under: Problem Solving

Yesterday, one of the developers on my team was having a lot of trouble loading a project into IntelliJ IDEA. It would either just hang halfway through indexing the project, or would claim that it ran out of memory (even after allocating 1500MB to the Java heap) while trying to index. The usual remedies, i.e., deleting the index directories, restarting the machine, updating to the latest version (she was on 10.0.1, so she upgraded to 10.0.2), didn’t work. The strange thing was, another project (of similar size and complexity) loaded fine. We pored through the thread dumps and log files and nothing jumped out, other than it seemed to be in the process of reading files, but taking a really long time in doing so. I looked at the activity of the virus scanner (another typical culprit of slowness), but it was quiet and not doing any I/O.

Her machine has a super-fast SSD as the primary drive (where the cache of indices and source code are), so it should be really, really fast, and it usually was. At this point I had remembered hearing something about another developer having a problem with their SSD, so my theory changed from a software problem to a hardware problem. I looked around a bit at the disk management console (Windows 7), but didn’t see anything obvious that would show me error logs from the drive.

I could have done some searching around for that information, but it seemed easier to suggest a test: check out the entire project code to a different drive, and see how well it works. The result? It worked fine, no problems loading or indexing the project. Now we can have the SSD replaced and see if it’s the drive itself, or the controller, but it’s clear it’s a hardware problem. For now, at least, she can work around the problem.

You might be wondering why I bothered writing about this little incident. It’s not that I expect this to help anyone having the same problem, or at least that’s not my main goal, but I’m fascinated by how people troubleshoot and solve problems and by writing this I’m hoping to get in the practice of staying aware of how I solve problems.

How did I think to suspect the SSD? Was it because I had heard a tidbit about another SSD failure? I don’t think so, because I think I had a “feeling” that it was a hard drive problem before I remembered the SSD failure tidbit. What exactly was that “feeling”? It was connections being made. I’m pretty sure my early computer experiences with hardware (I was the “hardware” guy in college and built dozens of PC systems from parts) helped, but it’s hard for me to tell.

January 29, 2011

YAWBATT - Yet Another Web-Based Agile Tracking Tool

Filed under: General Rant

Sometimes I wonder why I bother looking at web-based agile “tracking” tools. At my company (Guidewire Software—we’re hiring!), we are pretty happy with the combination of a physical story wall using StikkiClips and index cards, with colored tape dividing the wall into the different states (To-Do, In Test, Done-Done, etc.) and, in some cases, swimlanes (feature A, feature B, tech debt, misc., etc.). It’s easy to see at a glance what’s going on, where bottlenecks are, move cards, pull cards to prioritize and estimate, etc.

Maybe it’s the computer geek in me that is always looking for some tool that will magically make my life easier. For example, today someone in one of my LinkedIn discussion groups mentioned yet another agile tracking tool called AgileBench. I went over to the web site, took a look at the video, wasn’t terribly impressed, but it was easy to set up a test project and try it out (always a big plus!). Here’s what I wrote:

I took a look at AgileBench and it seems quite simplistic. Unless I missed it (which would be a big strike against the usability), it doesn’t appear that I can change the states that a story could be in. What if my process doesn’t use the same states? In fact, what if, after a retrospective, we discover that we need an additional state? With my story wall and index cards, I can change this in a couple of minutes (in fact, I just did this yesterday—I added a new state column that we discovered we needed).

To me, AgileBench falls under the “simplistic” fallacy: that supplying very little functionality is the way to make things simple. Not only can I not change the states that a story can be in, there are other basic assumptions that I can’t change: how stories are estimated (we use T-shirt sizing, Small, Medium, Large), the fact that multiple people can work on a story (not just one), and that (using the only Story template) that I want my acceptance criteria in the story (I don’t).

Finally, it seems very strange to me that I have to “manually” start an iteration. Why would I not want it to automatically start when the start date of the iteration comes around? Also, the tool allows me to put stories into the “in progress” state for iterations that haven’t yet started.

Fundamentally, any new “agile” tracking tool that comes on the scene has to be compelling. It has to offer something that existing tools (AgileZen, Pivotal Tracker, etc.) don’t support. Most importantly, it has to provide an easy way for me to import my stories from other systems (or even from a spreadsheet or XML file).

It amazes me that new SaaS tools generally make it hard to import work done in other tools. Even if I did like some new online tool, without a way to pull in all the stories we’ve created, I wouldn’t bother.

April 6, 2010

Using Innovation Games® in an Iteration Retrospective

Filed under: Rave, Agile, etc.

One thing I love about using Twitter is the incredible variety of ideas and things to try that come my way on a daily basis. For example, yesterday Luke Hohmann (of Innovation Games® fame) tweeted:

lukehohmann: @mglacey you can also use #innovgames for your retrospectives - I'm posting on this tonight - stay tuned

And I thought, well, we’re having our iteration retrospective the next day, so maybe we’ll do an innovation game. I read Luke’s blog post (at http://innovationgames.com/2010/04/using-innovation-games-for-retrospectives/), but knew I didn’t have the time to prepare for that particular game. I then saw another tweet from Luke:

lukehohmann: @gerrykirk Also, check out http://innovationgames.com/2010/01/using-speed-boat-for-process-improvement/

Which discusses using the Speed Boat game (http://innovationgames.com/speed-boat/) for process improvement. I read it and thought that it was something I could pull off without too much preparation. When I got into the office the day of the retrospective, I pulled the copy of Innovation Games off of my personal shelf and read through both the Speed Boat game as well as the customized version (on page 131) and saw that the customized Speed Boat would fit my needs.

In the “you can never have too many office supplies” category, I was looking for some index cards that people would write their “anchors” (or “barnacles” in the customized version) on when I came across my brightly-color index cards and I thought: instead of a boat, I’ll use a car! Then I’ll use the traffic-light-colored cards, i.e., green, yellow, and bright pink (well, as close to red as I had) to indicate which things blocked people’s productivity (pink), which slowed people down (yellow), and which made them go or go faster (green). I was quite impressed with myself.

Before the retrospective started, I drew a car on the whiteboard and put up small pieces of blue tape in preparation for people sticking cards to the whiteboard. I then handed out pens to everyone along with one each of the red, yellow, and green index cards (mainly because I didn’t have enough to provide more than one per person!). I then left the room for a pit stop. When I came back I found that they had made a slight modification to my drawing of the car because apparently it was too symmetrical and they couldn’t tell which was the front and which was the back. I found this amusing, but I mention it here because sometimes if you simply leave people alone, they start doing unexpected (and potentially really useful) things. I wonder what would’ve happened if I had said “OK, you guys do the retrospective, I need to make an urgent call”.

After fixing up the car drawing a bit more, I held up the index cards and explained what we were going to do: everyone will write one thing per card that made the project go on a green card, things that slowed them down on a yellow card, and things that blocked or really interfered on a red card. I then had to explain it again (and used examples) because either I mumbled, the words I used weren’t clear, or people were blinded by the bright-colors of the cards. (Seems like I need to be more careful about how I give instructions as this wasn’t the first time I’ve had people give me questioning looks after I’ve provided instructions).

I told them that after they’ve written a card or two to come up to the whiteboard and paste the card anywhere they wanted. After a little while of people thinking and writing one or two people came up, and then everyone started taping cards up. A few people asked me “where should I put the card” and I told them “wherever you’d like”. I said this because I didn’t really know what rules I could define that’d be helpful and I was much more interested in the rules that would emerge. One person noted during the hubbub how nobody was taping cards on top of the drawing of the car, and nobody ever did.

After the activity slowed and then stopped, I asked for three volunteers and had them go up to the board and organize the cards in some way, but how to organize it was up to them. I had only three people do this instead of everyone because I wanted the order to converge more quickly than it might otherwise converge with 20 people at the board. Next time I’ll experiment with everyone because I think it’d be interesting, but I was already doing enough flying by the seat of my pants!

Speed Car Retrospective Results

I had the three volunteers explain their organization and then led the team through the “clumps” or clusters of cards: I would read a card or two from the clump until we felt we said everything we could (and yes, perhaps we talked more about some than necessary) and had some good, solid discussions. The clumps lent structure to the conversations and the cards provided some solid context and detail. Just like a story card is a token for conversation, the traffic-light-cards were tokens for discussions. It also looked like the car was driving through a fruit stand, according to one of the folks—maybe we’ll use fruit next time?

Success!

There seemed to be a higher level of energy and engagement than in other retrospectives, but whether it was because of the “Speed Car” game or because we were in a different conference room than normal, I’m not sure, but I think the game definitely had something to do with it. I would definitely do it again, perhaps with some twists about arranging the cards, or allowing more than one card per person. Which reminds me, I need to stock up on more office supplies!

March 23, 2010

Adopting Agile at Guidewire Software

Filed under: General Rant

I’ve linked to this on mailing lists and mentioned it on Twitter, but forgot to make a blog entry for it!

As part of Guidewire Software’s recruiting effort, and to generally get ourselves to be better known, we created this short (6 minute) documentary about how I helped Guidewire become more Agile.

Here’s the link to the video: Agile Development at Guidewire

February 22, 2010

Creating Simple Live Templates in IntelliJ IDEA

Filed under: IntelliJ IDEA, Testing

I often use the Live Templates feature in IntelliJ IDEA, but since the documentation leaves out the “built-in” variables (or at least hides them very effectively), and I’m always forgetting what they are, I figured I’d document them here so that I could find it again. If it proves useful to you, all the better!

In Live Templates, you can use variables that represent content to be inserted when the live template is “executed” or played-back. There are two built-in variables, i.e., ones that don’t require you to further define, that I use often: the first is $END$, which will place the cursor at that location when the live template has finished. For example, I use this live template for creating JUnit test methods:

@Test
public void $END$() {
}
which, when expanded, will result in the creation of a test method and the cursor will be in the right place for you to give the test method a name. If you were using the 3.x version of JUnit, your template might be defined as:
public void test$END$() {
}
since that version of JUnit doesn’t use annotations and requires the name of your method to begin with “test”.

The second built-in variable that gets used often in the “surround with” live templates is $SELECTION$. For example, I often want to write a test that asserts that some variable is zero, so I’d create a template like this:

assertThat($SELECTION$)
    .as($END$)
    .isZero();

which turns

amount

(if it’s selected/highlighted) into:

assertThat(amount)
    .as(|)
    .isZero();

Here, the | character represents where the cursor ends after the template is executed.

There’s a whole lot you can do with defining your own variables in Live Templates, but that’s a blog entry for another day.

February 11, 2010

My first ScreenCast: Writing Fluent APIs in Java, Episode 1: Comparing Dates Fluently

Here’s my first screencast, comments and feedback are most welcome!

Writing Fluent APIs in Java, Episode 1: Comparing Dates Fluently from Ted M. Young on Vimeo.

In this episode, you’ll see how a fluent API in Java for comparing two dates is created from scratch in a test-driven manner.

Demonstrated by Ted M. Young (http://www.tedmyoung.com).

December 1, 2009

How To Do Your Best in a Technical Interview, Part III: Questions I’d Like To Hear

Been a bit busy lately, but here’s the final installment of the trilogy…

There are three categories of questions I’d like to hear from a candidate:

  1. About the company itself: products, finances, market, etc.

  2. About the culture: work-life balance, level of formality, number of meetings, etc.

  3. About the development process: roles, requirements, testing, state of the code base, etc.

The first one is important, because you’d like the company to be around for a while. Hopefully you’ve done some initial research about the company before you walk in the door.

The next two categories require some thought. Think for a minute: what would your ideal day be like at work? Would it be sitting at your desk at 7pm, debugging through some hairy code, trying to get a build out the door for the next day’s demo to users (or management)? Most people will probably not choose that scenario as an ideal day, though there are those who are quite attracted to that kind of pressure and love living on the edge in that way.

Not me.

After going through many years of being a consultant, founding or co-founding three companies (four if you count the one I co-founded with my father), working for a consulting company, and then working for some “real” companies (eBay, Google, etc.), I’ve gotten to the point where I know a lot about what I want in a company’s culture and development process. No company is perfect, but I’ve learned through lots of experience (i.e., mistakes) what environment works well for who I am.

That’s the key: not every environment (i.e., company) works for everyone (as great as Google can be, it simply wasn’t for me). For example, do you like lots of alone time to think and write your code? Or do you prefer throwing ideas (and code) back and forth with other developers. Do you like gnarly algorithmic problems or squeezing performance out of every SQL call? Or maybe you prefer working with users/customers/interaction designers to come up with interfaces for an application?

Or do you just want a job?

If that’s you, and you’re pretty good at what you do, there are lots of places where it’s easy to just have a job. But make sure that’s what you’re happy with, because if you just want a job, you can be sure that the people around you just want a job as well, but don’t be surprised if you find that you care more about things like quality and craftsmanship and good tests than they do. After all, it’s just a job.

Some other questions to think about asking when you’re diving into the development process:

  • How would you like to get requirements, i.e., in what form? On paper? As a mockup or prototype? Lots of whiteboard discussions?

  • Do you want things like Continuous Integration? How about bug tracking?

  • Do you care how available the people who define the requirements (product managers, owners, customer proxies, etc.) are?

  • How about testing: how much is done by an official QA group and how much is done by developers?

  • How complex is the code base? What’s the test coverage?

  • Would you rather deal with a single active development branch, branch per feature, etc.?

  • How does the team decide what to work on? Is it assigned by a manager or do developers pick what to work on?

One last area to think about is how much will you learn by working at the company? And that’s not just limited to their training budget, but it’s about who are the other people you’d be working with? Are they learners and teachers (i.e., do they like sharing their knowledge)? Or maybe the company’s in an area you’d like to know more about, such as finance or consumer-oriented software. Perhaps the non-developers you’d be working with sound interesting.

I could go on and on, but hopefully you understand that it’s less about the questions and more about what gives you satisfaction and joy in what you do. Figure out what questions you need to ask so that you’re as happy as you can be, because (and here’s where I sound like my dad) life is too short to spend a significant part of your life in some company that is a bad fit for you.

November 22, 2009

How To Do Your Best in a Technical Interview, Part II: Questions

After I wrote yesterday’s blog, I knew I’d forgotten something, but forgot what it was that I actually forgot (I believe that’s first-order forgetting). Now I remembered (actually I remembered during this morning’s run): questions. Not my questions (as the interviewer), but your questions (as the candidate). Maybe it’s inexperience, but since we (Guidewire Software; we’re hiring!—plug, plug) have mainly been hiring senior (as in experienced and skilled, not older) people, I’m amazed that I don’t get asked in-depth questions about our development process, or even about the day-in-the-life of an employee at my company. After all, you should be interviewing the company just as much as they’re interviewing you. After all, you can’t just assume that it’s a great place to work, right? I’ve made that assumption in the past, and I’m too old to put up with certain practices, such as lengthy code reviews before checking code in (I’d prefer to pair program).

So, what are some good questions to ask? I’ll supply some of the questions I used to ask when interviewing (as a candidate) and those I would like to hear in a future blog entry, but I’d rather you give some thought to the kinds of questions you should come in with. Think about what you’d want your day to be like as an employee of the company, then ask questions relative to that ideal. Obviously you’ll never find an ideal workplace, but it’s up to you to find out on which axes the company is not ideal and whether you can live with that for the next 3-5 years.

The Best Question I’ve Never Heard

OK, I’ll give you one great question that I have yet to be asked (and this is after doing 12+ years of interviewing!): how many people have you referred to the company and how many of those have been hired? My answer would be 5. That will tell you a lot about how me, the interviewer, likes the company, more than a typical question I get, i.e., how long have you worked at Guidewire. There’s a world of difference between me working somewhere for a period of time and being willing to ask people I know and respect to work at the same place.

November 21, 2009

How To Do Your Best in a Technical Interview

I’ve been meaning to write this post for a while, but after some frustrating interviews, I was motivated to finally put it down into words.



We’ve been interviewing a lot lately at my company (Guidewire Software, in case you’re interested) and I’d like to offer some tips on how to do your best. Note that I’m not going to tell you "how to succeed" or "how to get the job", because that will depend on your talent and skills. What I can tell you are the things that will allow you to make the most out of those talents and skills.

1. Communicate. In fact, over-communicate. If I’m interviewing you, tell me why you’re doing what you’re doing. Don’t make me guess. Don’t make me ask.

You may be the best darn programmer around, but if you’re thinking quietly and writing on the whiteboard in total silence, and then you make a mistake (and you will!), I won’t be able to help you. Just like in school where the motto "show your work" helps you get at least partial credit, if you just showed the answer it becomes either Pass or Fail—not where you want to be. So, if you tell me what you’re going to do and why and lead me through your thinking, then I’ll be much more willing to give you some hints or help and I’m definitely going to get a better sense of how you solve problems than if you keep your thoughts inside. As an "Introvert" (on the Myers-Briggs scale), I know that this can be hard, but if you can’t do it in an interview, then how do I know you can do it on the job?

1A. Verify assumptions.

This is the "be a good listener" part of communication. Repeat back what you think you’ve heard from me and make sure that agrees with what I said. For example, saying "so some other code will instantiate my object and I don’t have to worry about that, right?" is a good thing to do, because that may be completely wrong, but at least you found out before you started.

2. Admit when you don’t know something.

It’s much better for you to say "Y’know, I’m not really familiar with X" or "I don’t know Y" than to try and fake it or muddle through. If you admit you don’t know something, it’s unlikely I’ll hold it against you (unless you say "I don’t know Java" when the position clearly requires Java and you have Java on your resume). But if you push on through when it’s clear that you don’t really know it, I’ll be concerned that you’ll do the same thing on the job and not ask for help and therefore make serious mistakes.

3. Admit when you’ve gone in the wrong direction.

Similar to #2 above, but I’ve seen interviewees bomb when they keep pressing forward with a solution that’s not working or won’t work and they know it. If you’ve followed #1, I probably wouldn’t have let you go down that road so far.

4. Check your work.

I’m amazed (or dismayed) at the number of folks who write a bunch of code on a whiteboard and don’t read through it to see if they missed anything. Take a few minutes to read through your code and make sure there’s at least not anything obviously wrong. Pretend you’re the computer and execute your code.

5. Know how to write tests.

Seriously. In Java, main() methods with System.out.println()s are not tests (this isn’t 1996, y’know). One test for your code is not enough. 3 tests for 4 different classes is not enough. Naming a test "testValidation1" and "testValidation2" is going to make me wonder about how you name things (whiteboarding is a bit different, which I’ll talk about in a bit). In an interview I won’t push you to do TDD, but you have to know how you would test your code, since that’s as much part of the job as writing the code in the first place.

6. Know how to whiteboard.

Don’t write out every single little thing on a whiteboard. It’s perfectly fine to say "and then I just do more of the same here" or "normally I’d give this a name such as testWhenUserLoginFailsAnAuditLogEntryIsCreated, but I’ll just write testLoginFails". Time is of the essence in an interview and you don’t have time to write compilable code. As long as you’re following tip #1 and communicate well, you can take a lot of shortcuts on the whiteboard.

There are other things, but if you follow these tips, especially #1, the rest is up to your ability to actually program.

Get free blog up and running in minutes with Blogsome
Theme designed by Jay of onefinejay.com