Wednesday, November 19, 2008

Kanban-o-rama - Part 2

In part one I laid out the why and the how of our Kanban set up. In this part, a nice cell phone picture and some what it's done for us.

The Board



Here's our "borrowed" whiteboard. In stroke of genius from Mark, we drew the dividing lines with a Sharpie which makes them semi-permanent. One post-it note equals one work item, so for every post-it on the board there's a corresponding entry in our SharePoint work item list. Yellow post-its are regular priority items, purple tickets are high priority. (The stray colors are just strays...green == yellow, and fucia == purple.)

To the right of the names is where we start working with the tickets in the backlog column. It's sized to fit three tickets to help enforce our max three rule for that slot. Below that is the Blocked area, which isn't sized to scale of their respective max allowable tickets.

Moving to the right across the board is each developer's Work in Progress slot. Again, sized to enforce the max allowable items. This is where carried over our dotting strategy from the previous set-up: Yellow is domain understood, green is design understood and in dev, red is dev complete, blue is in production. (Though following this photo we have decided that blue will mean passed testing in staging, ready for production.)

At the bottom of the Work in Progress column is our Emergency slot. This is where our "drop everything" items end up. To our surprise, it hasn't been utilized as much as we thought it would.

To the right of the Work in Progress slot are our Ready for Test and Tested slots. These are the first real community slots on the board, and the honor system is in place for getting things tested. So far, so good on that.

The far right of the board is open space for notes, tracking what's gone into production, and blimp drawings.

What its done for us

So far the big win for us has been gaining focus on one item at a time. We still have some growing to do in this area, as the inevitable "How long would it take to do X?" questions come up daily, and you find yourself looking at code you weren't aware existed when you started the day. So, we're trying to push harder to keep the distractions down, and keep the focus switching lessened.

Another thing that moving to this system has allowed is that it's much eaiser to report up the chain of command what each person is working on. It's much easier to manage expectations on when something will be finished and when another item will be started. Also, when the, "Item Q has to be done right away," request comes in I can say which items are being worked and ask which one should be stopped to pick up Item Q. Now that I can better articulate what each guy is doing, these requests are more often becoming, "Oh, this can wait until one of those is finished."

We've been using this for about four weeks now, and have had a few discussions around it. The early returns from the dev team is that they like it quite a bit. The numbers reflect that it's working, too, as we've closed more tickets over the last four weeks than we had in any four week period since mid-July.

Sunday, November 16, 2008

Kanban-o-rama - Part 1

Our current project is much more of the maintenance variety than of the new development type. Originally we tried to apply our standard scrum-ish approach to it - feature cards, load sheets, 2 week iterations, etc. However, it became clear that working maintenance tickets wasn't going to fit that model. Our load sheets meant nothing after a while because they were just getting overloaded with work items that were un-estimated, but needed assigned to get worked. It also became increasingly difficult to track the status of an item. Due to the lack of information about some tickets, any developer would show multiple tickets being "worked" at any given time. Keeping track of that on prod push day wasn't very easy, either.

Enter the Kanban idea.

The idea was brought up after a Friday retrospective by fellow QSI guy, Alexei. Comrade, myself, and our PM had about an hour discussion around the idea, and the following Monday put it into action. I did some information gathering over the weekend, hit up a couple other Quick guys for some more information, "borrowed" a white board from an office in the building, and away we went.

Our setup

Our setup is pretty simple. You can have 1 item as "Work in Progress" at any one time. You can't work more than one item at a time. Focus on that item until complete, then pull an item from your backlog.

We set up the backlog not as a community backlog, but each developer has his own backlog. I know this isn't ideal, but it gives us one extra layer of control on the flow of which tickets go to which guy to fix them. (The system we're working on is pretty broad, and though I'd love to practice collective ownership of the whole thing across the whole team, that's just not practical.) The backlog can max out at 3 items, and the item you choose is your choice, unless there's a high priority item in your backlog. (Denoted by a purple ticket rather than the normal yellow.)

If your item becomes blocked, we have two blocked areas available to move the ticket into. The first is "Blocked, need more information." Tickets moved here are assigned back to the PM who will follow up with the user to get the information needed to complete the ticket.

The second blocked area is "Blocked, Internal" which is a horrible name...the creative juices just weren't flowing that day. Typically tickets get moved here when they're dependant on another work item to be completed prior to them being worked.

Our max tickets allowable in the Need More Info slot is 8, and the internal is 2. If we go over those counts, we stop and figure out what we need to do to move those tickets along.

Once a ticket is no longer blocked, it goes back into the developer's backlog that originally had it. If there's not room in the backlog when it comes unblocked, it will wait in the "Ready for Dev" queue that is maintained in SharePoint. All the tickets are tracked through SharePoint as well as on the board, but prior to hitting the board they're managed only in SharePoint.

Once a work item is completed, it moves to "Ready to Test." The rules of testing are you test a ticket you didn't complete, as we don't have dedicated QA resources available. When you complete an item and there's one available for test, take the time to test it before starting your next item. So far, using the honor system has worked well, though we do still have some testing to catch up on before we do our weekly prod push. (We've picked Tuesday, so there's some testing going on Monday afternoon.)

Following testing, the ticket moves to "Tested." There it sits until it's rolled out to production.

That's the standard flow we've been using, but we did open up an "Emergency" option. So far, we've only had three emergency items drop into that slot. When that happens, the developer chosen to work it stops the item he's currently working and switches gears to the emergency until it's complete.

I'll end part 1 here. Up next I'll show off some photos of our board and add some more details as to how its been working out for us.

Sunday, August 17, 2008

eRubyCon takeaways

I had the pleasure of attending eRubyCon here in Columbus Aug. 15-17. This is the second year for the event organized by Joe O'Brien, and the first year I got to attend. Josh Holmes has put up great reviews of the sessions up on his blog.

Since I don't really want to repeat Josh, what were my takeaways from the event?

First, that I still need to get more involved in Ruby. This is just a cool language that allows you to do so much as a developer. The allure of RSpec aside, it just reads well and makes sense. So, a couple things came to mind as near term goals. First, I need to start with some simple scripts for everyday tasks, and write them in Ruby. Second, I'm going to try to wire up IronRuby to test some of my C# hobby code. Doubt I want to drag that one into the office just yet. Those two items should get the ball rolling for me.

Second, and I think the larger takeaway for me, was that the .Net community was almost totally missing. I noticed this in two areas, there were very few .Net developers in attendance, and most of the topics only recognized that Ruby people were converting from Java. There was a lot of Java venom being tossed around for that reason, but the opposite of love isn't necessarily hate. It's apathy. The .Netters took it on the chin in the apathy department.

What can we in the .Net space do about this? First and foremost, get out there and see what else is going on. There is a lot of software not written on a Microsoft platform, what can you learn from them? I'm not saying learn something top to bottom, but get ideas from others. In the end, language doesn't matter as we're all trying to solve people problems, and the better armed you are to solve those problems, the better off we are as a whole.

Before I lay all this at the feet of the .Net community, those outside the Microsoft environment have a little responsibility here, as well. When Michael Letterle and Josh Holmes were up to give the IronRuby, Silverlight double header the room cleared a good bit. For the same reason the .Net folks should look outside their comfort zone, maybe others should take the chance to look inside the big blue monster to see what's happening.

I'm well aware of time constraints and family and "I'm already learning seven other things!" and a reading list that's growing faster than it's shrinking. But, instead of hitting your fourth Day of .Net in a row, take in a Ruby or Python conference. Or, if you're already at a Ruby conference, stick around and see what IronRuby is bringing to the Microsoft and Ruby communities.

One of my favorite terms of late is Jim Holmes's "Specializing Generalist." Looking inside or outside the Microsoft space, as the case may be, will add to the Generalist side of the equation. And, who knows, may change what you decide to be a Specialist in.

Wednesday, July 9, 2008

TDD Starting to Sink In

Back in late March, I blogged about my issues getting going with TDD. At the time I was nearing the end of a project where I had attempted some unit testing, but had not done it up front. I was looking forward to a clean slate to get some more work on TDDing up my code.

That opportunity somewhat presented itself, though I was moving on to an established team, which presents its own challenges. However, this team, or a good portion of it, was practicing TDD. So, plenty of example code out there. Not only that, I ended up sitting about 3 feet from world renowned TDD zealot, Steve Harman. Steve is a great teacher, and only yelled at me a few times. (And I only cried the one time...)

That helped on the professional side of things, but even in my own hobby coding I started writing more and more tests before the code. I've been presenting on ASP.Net MVC at a few places recently, and the sample code I use there was written all TDD style. (And is presented test first.) Well, almost all of it...somebody wrote his repository wrong, and the updates didn't work so well. I have some refactoring to do.

So, here I am 3 months later, where do I stand on the points I brought up back in March?

1. I tend to wrestle a lot with when to layout some of the framework and when to just breakdown and write the tests.

This one became pretty easy when Steve introduced some BDD (Behavior Driven Design/Development) style grammar to our testing. This one shift in thinking opened up my ability to get the requirements into unit tests, and get them green quicker. In a nutshell, thinking along the lines of, "When X condition is present, then Y should happen," and naming the classes and test methods with that type of grammar took me well beyond wondering when to write the tests.

2. A recent project found our team working with a pile of generated tests.

Generated tests are a thing of the past. This is a non-issue at this point.

3. When to mock?

Again, a healthy dose of Steve helped here a lot. Also, Rhino Mocks 3.5 was released with the Arrange, Act, Assert syntax, and that cleared up a lot in the mocking area. No more record and playback blocks, and lots of lambdas to stub out that which you want doing the dirty work.

The answer to the original question finally became clear: Get the hard stuff out of the way with mocks. Beyond that, get the stuff that you're not testing out of the way with mocks. The AAA syntax made that pretty easy.

4. Is this test trivial, or needed?

OK, I still have a bit of trouble here. Not as much as before, but occasionally I find myself writing a test, looking at it, and going, "Gee, I'm testing the setter of that property...that had BETTER work!"

5. I still have large holes in what I test.

Again, still having trouble here. Even with the good TDD practices in place at the most recent project, I found myself frustrated and writing the code and screen testing it rather than writing my unit tests up front. I did have a deadline that I was up against, but cutting the unit tests is never the right solution. I fell back to an old habit, one I've been working pretty diligently on breaking.

In the March blog entry, this referred to unit testing my javascript. Well, ending up on a Webforms project pretty much ended my worries about getting my javascript tested.

So, with those steps behind me, what do I want to focus on now? Well, I can still improve on numbers 4 and 5 above, but I think those two will be continuous improvements. I'm going to continue down the BDD-ish path. It's not pure BDD, but it got me over the hump, and I like the syntax. But overall, I'm just going to keep going at getting the tests written up front. Focus more on the red, green, refactor as much as I can. I'm seeing the benefits, just need to get those old habits kicked.

Tuesday, June 17, 2008

The Summer Tour of Timbo

The summer speaking tour is about to get underway, fresh off the heels of my successful spring tour. (Successful after the QSI Tech Night unit-test-a-palooza fun.)

We'll be kicking off the summer tour in Cincinnati next Tuesday (6/24) at the June CINNUG meeting. I'll be presenting on the ASP.Net MVC framework, why it's cool, why you should be using it now, and how it will do simple household chores for you - walking the dog, doing the laundry, and cleaning the bathroom. (It doesn't do windows, though.)

Fresh off the evening in Cincinnati, I'll be heading to Dayton the very next evening to present the same riveting and engaging presentation to the good people of the Dayton .Net Developers Group. Fellow Quickie Jim Holmes helps run the Dayton bunch, so I expect heckling in Dayton.

Following the quick bang-bang trip across south western Ohio, I'm off for a few weeks before I head below the Mason-Dixon line to speak to the Memphis .Net User Group on July 24. "Memphis?!?!" you saying. Jeff introduced me to Colin Neller, president of MNUG, when I was in Vegas for Mix, and he invited me down after I expressed a little interest in getting out to do some speaking. My topic in Memphis is as yet undecided. Colin has a poll up in the MNUG forums for either an MVC deep dive or my Evangelizing the Pragmatic Programmer talk. Can't wait to see the results. It's 50/50 at the moment, so if you're in the Memphis area get your vote in...you could be the deciding vote!

That ends my scheduled trips at the moment, who knows what I'll rope myself into as August comes along.

Monday, June 9, 2008

How I got started programming

I got called out by Jeff in his post on the same subject. I believe this idea can be traced back to Michael, and it's a pretty good idea. It's nice to see how our friends and colleagues have progressed.

Fair warning, this could get long winded. I am, after all, talking about my favorite subject...me. :)

How old were you when you started programming?
I think I was 12 when I first wrote some kind of program. Christmas of my 7th grade year, Ma and Pa Wingfield bought an Apple IIe, along with a couple games. However, I quickly got bored with the games and wanted to make that machine do the stuff I wanted. I talked mom into springing for the 128k upgrade card, and I got down to writing some BASIC programs.

Between the 7th and 8th grade, mom actually sent me to Ohio State to "Computer Camp." It was like Code Mash '83. A bunch of 12-14 year olds on OSU's campus for a week writing code. Oddly enough, at the time I was an "Apple Guy" because that's what we had at home, but all the machines at the camp were IBM's. So, I basically just focused on the BASIC code, and not all the screwy graphics stuff that only worked on the IBMs.

How did you get started in programming?
Through High School, I did very little programming. Females and football were my main focus, and after graduating I was off to OSU to get an Ag Econ degree. While at OSU I did take a beginning programming course, and it was one of the few courses I enjoyed. (Didn't take the hint, though.) In it, we were writing PASCAL on Macs...back to the Apple. (The irony is getting thick, here.)

After that class at OSU I let my programming gene slip again, and didn't really take it back up until I got a 486 in '93. After getting that, and with the web boom right around the corner, HTML and javascript were intriguing, so I hobbied around with them for a while. Then, got serious and went to Franklin to work on getting a CS degree. That's when it all started to come together and I figured out I really was a computer guy at heart. (At FU I did most work on a UNIX system...no Apple this time, but no PC, either.)

What was your first language?
As noted above my first language was BASIC on the Apple. Lots of GOTOs in my code, too. Nothing brought my 128k expansion card to it's knees quicker than a nice infinite GOTO loop.

What was the first real program you wrote?
This is kind of a two parter for me. The first large program I got working was a Stock Market simulator I copied out of a magazine. I made a few minor tweaks to it to make the stocks move faster and change the companies that were traded.

But, the first real program I wrote from scratch was a farming simulator when I was in the 8th grade for the IIe. I grew up on a grain farm, and decided to write a simulator for planting, harvesting, and trading grain. I titled the program "Appleculture" which I thought was pretty snappy. The most difficult part of the game to program was the random number stuff to make the grain prices move, but not move too much. And to make them trend up or down, not taking huge jumps in the opposite direction it took the turn before. It got pretty involved. It also had a banking portion to it, so I guess I was staring my "line of business app" future square in the face there and didn't even know it.

What languages have you used since you started programming?
Hmmm...BASIC, PASCAL, C++, Java, VB 5, HTML, Javascript, ASP, VBScript, PHP, C#, VB.Net, Ruby (just getting started on that one)

What was your first professional programming gig?
First professional programming gig was at a small lighting manufacturing company near the airport back in about 1997, I believe. I was brought in to build the website, oversee the computer systems, and do some other things around the building. Turned out the guy that owned the company wasn't all that good at delegating, so it ended up being more of a production manager position than web position. I did get the website launched before I left, and it was still the web site up until about 18 months ago. (Which is really kind of sad.)

If you knew then what you know now, would you have started programming?
Yes. If I knew then what I know now, I would have started focusing on programming much sooner. My real programming life didn't start until I was about 26 or so, even though I was writing random grain price generators when I was 13.

If there is one thing you learned along the way that you would tell new developers, what would it be?
I'll have to follow the crowd and say soft skills is a big one. Everything is a people problem, so to solve those problems you've got to deal with people. If you think fixing the problem is locking yourself in an office or hunkering down in a cube for endless hours typing away, you're mistaken.

Secondly - can't narrow this one to just one - and I read this in somebody else's post and heard it from Brian Prince, get a mentor or mentors. After leaving the small manufacturing place I've been lucky enough to have at least one person at each company that's been a mentor to me. At Quick it seems I'm surrounded by mentors. In this chosen career you're always learning, if you're not always learning YOU are the problem.

What's the most fun you've ever had ... programming?
Not sure I can narrow down a "most fun" time, but my most satisfying time was working on the MCCH project for the Attorney General's office. Simplified explanation, this was the web interface for the Amber Alert system in Ohio. My email address is still in the db for all Amber alerts in the state, and seeing, "Alert canceled, child recovered," come into the inbox always makes me feel good.

Jeff called me out, so I'll pass along the call outs. Like to hear the stories of...

Jim Holmes

Greg Finzer

Phil Jordan

Steve Horn

Matt Casto

Sunday, April 27, 2008

So much to blog about...but I'm on VACATION!

I've got so much I should be writing about. Considering I just spoke at Central Ohio Day of .Net and at Cincinnati Financial's .Net User Group just over a week ago, there are a couple of wrap ups due there. Also have a little jQuery with MVC that I'd like to blog up. Actually, I should have a few more MVC posts coming out.

HOWEVER!

Tomorrow at 7:10am I get to fly to Orlando with my youngest for a trip he doesn't know about yet. Big surprise for the five year old will hit tomorrow morning.

With my Blackjack II loaded and ready to go, there will be tweets from The World, I'm sure. I tried to get Windows Live to accept photos, but couldn't get it to work. The emails all bounce back and the photos never appear. So, Google to the rescue, and I've got a mobile blog all ready to go, complete with a before picture of the unsuspecting Alex.

So, this short trip to see what Mickey and Donald are up to will be used as a moblie computing experiment. OK, maybe not so much an experiment as three days in my favorite vacation spot with my son and my still fairly new found mobile universe. Should be a lot of fun.

Saturday, April 5, 2008

Video on ye ol Blackjack II

Got a short trip coming up soon which will involve me and my youngest, Alex, hopping on a plane for a couple of hours. Being tech-ish, and wanting to pack light, I figured I'd get a couple of episodes of Spongebob from iTunes, and we'd have one entertained 5 year old via my Nano.

But, the Nano has one small screen. And, hey, look at that...the screen on my Blackjack is about TWICE as big! Light bulbs go off everywhere...

Went something like this...

- Blackjack runs Windows, and has windows media player. I've got a ton of .avi movies, let's load one up!

[Failure]

- OK, it's a stripped down version of media player, we'll just convert that sucker to a .wmv file and we'll be in business!! Google up a video converter and find Prism. Free, and does the trick. So, about 90 minutes later...30 minutes for the conversion, 60 minutes for Vista to kindly copy it to my Blackjack...we're pressing play on the Blackjack.

[Failure]

- Mother puss bucket...in a moment of weakness, I email fellow BJII noob Harman. I figured his newly bestowed MVP status has given him great powers over all things Microsoft. It did, "Email Keith Elder, he's the mobile wizard."

- I email The Elder, who promptly replies with, "Yikes, that's the one thing I've never tried on my phone!" Keith did direct me to another converter, Pocket DVD Wizard. This one is $25 with a free trial, which I snagged as it will give me 5 minutes of a movie converted to the format I need.

- Fire up Pocket DVD Wizard, which asks what device I'll be using. Select Samsung, and the secret is revealed: The file type needs to be .3gp. With the conversion complete, I copy 5 minutes of Toy Story to the Blackjack, and...

[Success!!]

- Short lived success, though, as it will only play in a tiny window. Flipping it to full screen makes it very pixelated and choppy. The window it plays in is smaller than that of the Nano, so back to square one.

Well, back to square 1.5. We're now converting a couple of those .avi files to .mp4 for the Nano. I figure the 4GB Nano will get us to and from Orlando, keep Alex occupied, and I'll use my Blackjack as an mp3 player for myself.

Assuming I can get that to work...

Oh, and Alex has no idea about the trip, it's a big surprise for him. Don't tell him!

Sunday, March 30, 2008

TDD growing pains

I've understood and attempted to follow TDD practices for a while. The initial understanding of it was pretty tough, and very, VERY sporadically put into practice. After all, it's a pretty big shift in thinking when you first encounter it. "Write tests? For code that's not there?? Wow, that's fantastic!!"

So, over time I've gotten much better at the whole TDD thing. Or so I had thought.

Wednesday, mid-presentation, my lack of patience with the system outed me. I had written my tests, passed my tests, changed my code, changed it a little more, and then went to present it. Wow did I get smacked in the head by not running the tests after each change. (Continuous integration for a small demo app didn't really enter my mind. I have a hard time firing up CI at home since there's not much to I, but maybe I should join Mr. Donaldson in doing so.) So, big time lesson learned there.

The flip side to that bit of a stumble was the amount of time TDD saved me on my current project at work. I had written a number of unit tests to cover some business logic, and a few integration tests. A couple of defects came in showing that I needed to change a number of my dates to nullable objects. Not a difficult change, but not totally trivial, either. Made the changes, ran the tests. Oops...more changes, ran the tests. The whole change over was done, tested, and passing within 15 minutes.

A few pitfalls I've fallen into while traveling down the path towards TDD enlightenment:

1. I tend to wrestle a lot with when to layout some of the framework and when to just breakdown and write the tests. The main reason I wrestle with this one is that the good ol' crutch of intellisense sure comes in handy for test writing if you've framed your code out some. (When writing Ruby code in e, this doesn't seem to be as much of an issue for me.)

2. A recent project found our team working with a pile of generated tests. With the ever present deadline looming larger and larger, we decided to go with the generated tests as they appeared to be "good enough." They were good at the start, but as the code base grew, and our tests with it, we started looking at our CI build taking up to an hour. There's a big red flag. Dug into the code, very few unit tests were generated, but a pile of integration tests were. Takes a while for nHibernate to do its thing 4,316 times. (We've since started cleaning that up, build is back to a more reasonable, but still outrageous half-an-hour now...)

3. When to mock? I'm hip to the whole mocking thing, but identifying the right time to do so is still giving me troubles. I'm sure I'll get there with practice, just need some more practice.

4. Is this test trivial, or needed? In a previous post I mentioned viewing code coverage the other way around, seeing what's uncovered rather than covered. I don't see 100% coverage, er I mean, 0% uncovered as attainable in the web projects I usually work on, but where do you draw the line? If you end up falling over on a piece of untested code, I guess it wasn't trivial.

5. I still have large holes in what I test. Just about all of my javascript code is completely untested. I know there are frameworks available to help me with that, but I haven't gotten down and dug into them.

So, short term I'm going to keep the ears pinned back and keep moving forward with the testing first. May as well get a home build server set up, and keep digging on mocking as much as I can. Gonna have to investigate Moq, as well. Also, time to get that javascript tested. With as much AJAX as we're cranking out, this is quickly becoming a priority.

Tech Night - Getting Started with MVC

First of all, thanks to all those who attended TechNight this past week at QSI HQ. That was by far the largest crowd I'd seen gather for TechNight, much bigger than the 10 people that came in September when I presented on ASP.Net AJAX. With Quick having the much larger training center now, I hope this trend continues.

The Snag

During post-presentation discussions, I finally arrived at why the test failed. Short version: I'm an idiot.

Long version: I went with the whole TDD approach to the presentation to show how MVC was more testable. It is a great way to show some of the advantages of MVC. It is if you continue to run those tests as you refactor your code.

What I did was stop at red, green, refactor. I didn't try for more green following an additional refactoring. I had written and passed my product controller tests, where the big test failure happened in the presentation, before I had added my model code to the product controller. That's a pretty big change, and clearly the tests caught that change...in front of an audience, rather than in the comfort of my own home.

So, my protests of, "These passed at home!" were correct, because I only ran them once. Like I said, idiocy.

In the end we got it working for purposes of the demo, and I owe Mel, Steve, Steve, Kris and many others who shouted advice a big thanks for helping me over the hurdle. However, the demo ended up testing what I didn't need or want to test: That LINQ was doing what it said. I had wanted to add one more test prior to the demo that hit an in memory collection of products, that would have solved my problem with the connection string and been a much better test of the controller code.

Here is a link to the code and slides: Getting Started With MVC

That resisdes in a SVN repository on Google Code (thanks Steve), and will get updated as I update the presentation. Clearly I have a couple of tests to add, some data issues to clear up, and will probalby change the slides some as it progresses. Keep an eye on it in the near future for updates, CODoDN will be here before I know it.

Wednesday, March 12, 2008

Is code coverage worth bragging about?

I'm a hockey fan, have been for a while. In being a hockey fan, I've had a number of statistical discussions around the sport. Second only to baseball fans in statsville, hockey fans love their numbers. One major discussion took place around shots on goal. That semi-subjective stat that tells a team how many times the goalie got between them and a goal. I've seen teams put 40 shots on net and lose to a team that got 18 because 3 of the 18 went in and only 1 of the 40. After the game, you lost, but hey...you put 40 shots on that guy! You certainly didn't lose for a lack of trying.

So, over in the software world, I'm now wondering if Code Coverage is our shots on goal stat. You get over beers and start talking with peers and hear...

Bob: "I've got 40% code coverage!"

Terry: "Bah, that's nothing, we hit 55% this afternoon!"

James: "You both suck, we've got 70% coverage and are almost through UAT!"

Here's what's missing in that discussion...Bob is 60% uncovered, Terry is 45% uncovered, and James has 30% of his code waiting to spring something on him in the next few days of UAT. In essence, they've each got a number of shots on goal, but how many are in the net? Are we focused on the wrong side of the equation?

The goal of 100% code coverage is a tough one, unless you're Joe O'Brien. (See: Testing Mandatory, CodeMash 08) In my life in ASP.Net, getting 1% coverage on a code behind file would be worth a round of beers.

But, are we focused on the wrong goal? Clearly, increasing your code coverage is decreasing uncovered code. But, if your goal is 75% coverage and you reach that goal, do you stop? Maybe shifting our focus to code uncoverage will close that gap.

Don't be happy with those 40 shots on goal...

Tuesday, March 11, 2008

Mix08 Recap

My recap of Mix08 has to start with a big thank you to Jeff Blankenburg, and the small company he works for based in Redmond, WA. Jeff got me a ticket to Mix (QSI got me the plane ticket and hotel stay), then once I got there he got Colin Neller, who runs the Memphis user group, and myself tickets to the Blue Man Group. Then when the White Death hit Columbus and our flight home got cancelled, Jeff put us up in his room for the night because he was staying one more evening. (Oh, and he loaned me $40 at the craps table…but he told me the juice is running on that.) If your DE is to drive more interest, JB is doing a good job getting me around the Microsoft community.

Second big thank you is going to go to Steve Harman. Steve and I both work for Quick, and roomed together while at Mix. (That’s the rest of the “us” that Jeff put up courtesy of the Blizzard of ’08.) Steve has a number of contacts in the community, and he introduced me to everybody he knew, and some he didn’t know. (And after our interesting trip home, Steve and I didn't kill each other, and we're still speaking.)

So, with Jeff and Steve leading the way, easily the biggest part of Mix for me was the people I met. There were a number of sessions I didn’t go to as I stayed in the Open Spaces/Sandbox area to just talk with people. So, I may have missed a Silverlight session, but I got to spend about 35 minutes talking to Phil Haack about the ASP.Net MVC framework. The guy writing that framework has to be a pretty solid source of information. Later I watched the Steve Balmer keynote with Rob Conery. Rob shared a lot of what his general development practices are, and what tools he uses. (I didn’t luck out and have beers with ScottGu like Steve did, though.)

I did get to a few sessions, though. The highlight one for me was Scott Hanselman’s talk on the ASP.Net MVC framework. Since I’ll be doing one of those myself on March 26th, figured I better watch Scott to get some materials to borrow…er, I mean get ideas. I also got to see Nikhil Kothari talk about ASP.Net AJAX apps moving forward, which was pretty cool for me since I got a lot of information from Nikhil back when I was picking up on what was then ATLAS. One of the better sessions was a panel discussion on Open Source and where it’s headed. The panel consisted of Mike Schroepfer (Mozilla), Rob Conery (Microsoft), Andi Gutmans (Zend), Miguel de Icaza (Novell, Moonlight), Sam Ramji (Microsoft). They took questions which started the discussions, which got heated at times, but raised some great points. In hindsight, I wish I’d had found another panel discussion to go to.

All the sessions, including the keynotes (the Guy Kawasaki, Steve Ballmer keynote should not be missed) are available online now at http://sessions.visitmix.com in a number of formats. All that information is great, so in the end I really won’t miss any sessions I wanted to see, but the opportunities to meet the people I met aren’t available online. Here’s looking forward to Mix09 already.

Saturday, March 8, 2008

Tim and Steve's (not so) Excellent Adventure

After a wonderful trip to Mix08 in Vegas (update coming soon), Mr. Harman and myself were to have flown to home last night. However, the White Death didn't allow that, but thankfully Jeff had room for us. So, an extra night in Vegas, and rebooked plane rides for the next morning which would at least get us to Chicago. We left Chicago, with the lovely Mrs. Wingfield providing updates from home, hoping that we had a flight waiting for us at Midway that would take us home.

We got to Midway, I fired up my phone, text message from Wendy: "Your flight has been cancelled." So, a quick call to her with confirmation numbers and a hope that she could get through before we got off the plane. She did, but we had to go to the counter anyway. There our options were presented as: Stay in Chicago until Monday, or go somewhere else and try and get home. As much fun as two nights in Chicago sounded after four days in Vegas, we were ready to come home...so off to Indy!

Once in Indy, we got a rental car (a Grand Prix for you scoring at home) and have made it to a Holiday Inn about 30 miles east of Indianapolis. The hope is tomorrow the snow is cleared off I-70 and we can get back to Columbus.

If not, we have our very own version of Planes, Trains, and Automobiles..."THOSE AREN'T TWO PILLOWS!!!"

UPDATE: Tim and Steve's excellent adventure came to an end yesterday (Sunday the 10th) around noon. We made the drive in from Indy pretty easily. There were a number of cars in the ditch, mostly four wheel drives. Theory was the driver thought he/she was invincible and learned four wheel drive does not mean four wheel stop. The hairiest part of the journey was navigating German Village streets.

Saturday, February 23, 2008

Don't hide behind a catch block

"Pragmatic Programmer tip #32: Crash Early."


I've been recently tasked with some refactoring items. Like any project that's longer than 8 weeks, you'll dig into some code and find yourself going, "What was I thinking with THIS?" Or, if the project's a bit longer, you wonder if you came up with this gem (and no, not a Ruby gem) or if somebody else on the team left this odor in the code.

The code smell of this particular blog post is the abuse of the try/catch block. I've stumbled across a few uses of the try/catch programatically, or worse, using an empty catch block to hide an issue you're not sure how to deal with.

Right off the top will go with the empty catch block. I encountered a few of these while refactoring, and had to wonder why we were hiding behind the empty catch block. Crash early, but when you crash sweep that under the rug and move on? That's not good. If you need a catch block, then isn't there something you should be catching? Take the following for an example:


That's a pretty simple little conversion function, with the dreaded empty catch block in there. It's there not because of the TryParse, which is going to give you a false if it fails its own try, but because applying ToString to a null object is going to throw an object error. Rather than the empty catch, why not a null check on o? Then you know what you're dealing with rather than not caring and returning 0 for anything you're not expecting. To me, this is a classic garbage in, garbage out scenario. You pass in a null or an object that can't be converted to a an int and you get a 0.

Next up was a bit of sheer genius, and throwing my hands up when dealing with nHibernate. Rather than find out what was going on, I resorted to using a try/catch procedurally to handle the issue. Here's a bit of code that shows my brilliant solution:


The issue there turned out to be that we were using the load method from nHibernate rather than the get, so I didn't have null object to check. I had an actual proxy object full of null properties. My solution, duck behind the catch block and make it bend to my will. If the load found something, the id check would pass and I'm doing an update. If the resulting object error from the property check threw, then I'm dealing with a new object, time for an insert.

In this case my ignorance of nHibernate's dealing with objects was the problem, but ignorance is no excuse. Using the try/catch in this manner was a hack with Paul Bunyan's ax. It got me moving foward, but was a bad solution.

The final empty catch falls in the same lines, where ignorance of what was available to us wasn't found until much later. This empty catch block example was saving us from a null reference error in a nullable data type in a data bind method.



Getting rid of this empty catch may have been the easiest of the three, because nullable data types carry a "HasValue" property that tells you, well, if they have a value. The refactored code looked like:


Using the HasValue property, we can refactor this one down to the always elegant ternary operator. We know what value we have or don't have and can cleanly bind our data to what's in this case a grid column.

If you're going to fail early, don't hide the failure. Figure out what it is and write the correct code for it. The try/catch is there to help you handle exceptions, not to hide them and move on.

Thursday, February 21, 2008

Does Your Project Have a Junk Drawer?

Everybody's kitchen has a junk drawer. You know, the drawer where the tape, scissors, small jar of screws, various measuring items, and those clacker balls on a string that your mom is hiding from you. (Well, the ones my mom was hiding from me.) If you've got something in the house, and you're not sure where it goes, you fire it into the junk drawer. Oddly enough, you also find many useful items by looking in the junk drawer first when tackling something around the house.

However, I've found on a few recent projects that we're falling into the Junk Drawer model a bit. Look around your project, do you have file named "Utilities?" Maybe one called "GlobalMethods?" Or the very popular "ProjectHelper?" If so, there's a good chance you're throwing all kinds of things into the junk drawer. Could be a static class library, a little something in the App_Code directory in an ASP.Net project, or even a javascript file. Or, better yet, all three!

Now, don't misunderstand me, utility classes can be helpful. If you've got a series of string manipulations you need for a project, then a static stringUtils file makes perfect sense. Maybe a constants file for things that don't fit in an enum. As long as they are well defined and don't creep outside the scope of what you're trying to accomplish, I think they can be very helpful.

But, the junk drawer file that contains string manipulations, constants, get user name methods, some validation methods, a few odd conversion methods, a couple more string methods, and a few methods only called from your test project is not much of an asset to your project.

From a usage aspect, how do you tell other team members where your constants live? If they're scattered about your utility file, suddenly you're going to the same file for some string methods and your constants representing a product group. Or worse, your team gets so used to hitting your helper file that everything starts collecting there. Before you know it, you're looking at a maintenance nightmare with a couple thousand lines of code that should live in a number of more logical places.

Look around your projects, if you find a junk drawer take the time to refactor that thing out of there. Get all the files where they belong. You could end up with a utility file or two, but most likely you'll find you can move a number of methods right to the class that's using them because it's the only class that's using them. Turns out our friend YAGNI contributes many "global utility" functions to our projects.

Keep the junk drawer in your kitchen, though. Where else are you going to keep your SpongeBob commemorative Krusty Krab stamp?

How an AJAX guy would pack

At the request of (soon to be former) boss, Brian H. Prince, I've been tasked with explaining how an AJAX guy would pack. Even though this AJAX guy isn't involved in the moving because he's been off site for almost a year, I'll play along...

The first problem an AJAX guy is faced with when preparing to pack are the vast array of box options available to him. All the boxes appear to be roughly the same size, they are just slightly different colors of brown. There is one box that appears to be bigger, so it will hold more for the big move, but upon opening the box you see that a lot of space inside is taken up by an inner, un-openable box with "Update Panel" stamped on it. So, in the end, all the boxes hold roughly the same amount of stuff.

So, after picking a box, AJAX Packing Guy (or Gal) - henceforth referred to as APG - gets down to improving the packing user experience. APG opens up three boxes, puts one item in each box, then goes about cleaning their desk. At some point during the desk cleaning they notice that all three boxes are now full. They seal those up, and open three more boxes, then back to cleaning the desk. Oh, look at that...those three are now full, too!

Once all the items are packed away, APG uses their powers to make each box shrink and fade at the same time...only to reverse the process at the new site and have the packed boxes reappear by fading back in and growing back to normal size.

What happened to the APG who picked the larger box, you wonder? Well, the "Update Panel" carton inside looked to be very helpful at first, but once APG opened more than once box and set them to working, the update panels started running into each other, and reopening packed boxes, and taking apart boxes that had been put together. Eventually they got everything packed, and APG had to do very little in the way of opening boxes, but it took a while.

Friday, January 11, 2008

CodeMash: Feeling The Vibe.

I had originally set out to cover my travels through CodeMash similar to my post from Day 1. Give a recap of my morning, afternoon, etc. However, it soon became clear that keeping up with what I was hearing and doing was going to be tough, and that I wasn't going to have the time to sit down and enter it. On top of that, it feels like giving a couple sentences to somebody's 1:15 presentation gives them a disservice for the work they put into it.

Then I read Scott Hanselman's entry on his day at CodeMash, and I couldn't agree more with his point about "The Vibe" of the conference. Scott made a great contribution to The Vibe with his great keynote followed by just wandering the halls and jumping into conversations. A few of us were lucky enough to have him jump into our conversation before he discovered Rock Band. What's odd is it was kind of the "CodeMash Way" to have Scott drop in and say, "So, what are you guys talking about?" It just seemed normal, and the conversation didn't miss a beat.

The "CodeMash Way" is that everybody wants to learn something from everybody else. Nobody's language or approach is any better or worse than the person you're talking with, both of you are trying to learn something from the other. It's at its most evident when you look around the room during a presentation. Josh Holmes was giving a talk on Microsoft's DLR, and in the back of the room Joe O'Brien is taking it all in...and helping Josh along with some of the dynamic language benefits. The flip side is Josh was in the back of the room for Joe's talk on testing in Ruby the day before. The aforementioned Scott Hanselman was sitting along the wall for Dustin Campbell's presentation on F#. (And Scott's phone rang twice...that's two rounds of donuts, Mr. Hanselman.)

Suddenly the community isn't defined as the Ruby community, the .Net community, or the Java community...we're one big problem solving community exploring what weapons we can add to the arsenal to solve those problems. What .Net or Java guy heard Joe say, "I have 100% code coverage in Ruby at all times," and didn't have their jaw hit the floor? (Probably more than one since he asked the room what their coverage was and got answers ranging from "code coverage?" to 25% to 80%.)

I added a little to The Vibe, giving some advice on ASP.Net AJAX in the hallway (and thinking next year I should offer up a talk titled, "The Update Panel Sucks"), but for the most part I just soaked up all I could soak up. I went to Ruby discussions, saw plenty of Java code, and my only .Net sessions were on F# (where I was lost about 8 minutes after, "Hi, I'm Dustin Campbell" - functional programming not my bag) and Josh Holmes's talk on the DLR.

The best place to dig The Vibe is in the hallways, the open spaces, and the "Ask the Experts" sessions. I got the chance to meet and talk to Sara Ford in the hallway, but only because Jim Weirich had stolen the experts room to give his 10 things about Ruby talk, which I was attending.

The amount of Ruby I learned in there pales in comparison to the informal sessions many of us had with Jim. I really lucked out here. It started with CodeMash committee member and speaker, aspiring member of the Blue Man Group, Rock Band star, agile aficionado, and all around great guy Brian Prince walking up to Jim at the QSI sponsored Meet and Greet and asking what Aaron and I needed to do to get started in Ruby. That started an hour long discussion that many people walked up and joined. The next day at lunch, a few of us were sitting at a table eating when Jim walked by and recognized us from the night before, so he joined us. More opportunity to soak up what he had to offer. (I later commented to Brian, "Jim walks by and you learn something.") This isn't meant to be the Jim Weirich love-fest, he's a nice guy and all, but more along the lines of the "accidental" things that happen at CodeMash to add to The Vibe.

Compared to last year, I think The Vibe took on a much bigger feel this year. Maybe that's me moving out of my comfort zone at sessions, but mostly I noticed it outside the sessions while walking around. The informality of CodeMash builds The Vibe, but the people attending and speaking dropping our "barriers" is what takes The Vibe to a fever pitch. I'm already looking forward to next year's edition.

Of Note: I didn't win an iPod this year, like last year. I didn't win an Xbox or Wii, either. I did win a book...ON RUBY!!! Woo-Hoo!!

Thursday, January 10, 2008

CodeMash Day 1 Morning

CodeMash has started out with a bang for me, as I missed the first half of Neal Ford's Keynote on Software Engineering and Polygot Programming because I thought it started at 9 rather than the actual starting time of 8. The best part was I didn't oversleep, I was up in plenty of time, just didn't put my reading comprehension skills to work to read the start time of the keynote.

So, the last half of Neal's talk was excellent. (Referencing ORMs as programming's "Vietnam" was fun to witness.)

Following the keynote, I headed off to Testing Mandatory, a session given by Joe O'Brien about testing in Ruby. Solid session, and makes me want to learn Ruby that much more. Joe kind of shoots from the hip, but the message gets through. The biggest message was how easy testing is in Ruby, that it's built in from the beginning. He also provided a good idea on how to learn Ruby: Take one of the libraries and write unit tests for it.

The last morning session I headed to Intro to Castle with Jay Wren. Jay's pretty accomplished in Castle, so knows the material well. However, from my headbanging with Castle during my current project with trying to wedge it in our existing code base gave me all the intro that Jay was laying out. He did go more into MonoRail, so that was good, but I'm guessing my first trip into MVC land on ASP.Net will be with Microsoft's release of the same.

Tuesday, January 1, 2008

A little CodeMash love

Coming up in a few days will be CodeMash at the Kalahari Resort in Sandusky, OH. Having been to a few conferences, I consider this one a "don't miss." And here's why...

1. It's an indoor waterpark...nerds in speedos!

2. The collection of speakers and topics is second to none. This isn't your, "JAVA OR DIE!!!" meeting, just as its not, "Bill Gates cured my brother-in-law's limp," type show, either. It's a gathering of people passionate about their chosen field, wanting to share that passion, and get information on areas outside their comfort zone.

3. The Kalahari sells alcohol. Consider the alcohol induced war stories: "I had to deal with a five part composite primary key that allowed nulls!" It can only get better from there...

4. Keynoters that include Neal Ford (who also gave a keynote last year), Scott Hanselman, and Brian Goetz.

5. Breakout sessions with Neal Ford, Brian Goetz, Bruce Eckel, and Brian Prince! (Yes, I know, "one of these things is not like the others," but he has a direct impact on my paycheck.)

6. Conference food!!

If one or more of those six items hasn't piqued your interest then how about adding them all up: Brian Prince in a speedo delivering a presentation on Agile Development with a beer in one hand and a ham or turkey sandwich in the other.

Now that your interest has waned, fear not that won't happen. (And that direct impact on my paycheck is likely negative, now...)

Seriously, this is a good conference. If your looking for a "bang for your buck" type deal, then it's tough to beat CodeMash. I've been to pricier conferences and gotten much less out of them, mainly because much less was available. Last year's highlights for me were two breakout sessions with Scott Guthrie following his keynote and a session with Neal Ford on how to be a better overall developer. (Additionally, I had a strange urge to attend Burning Man...)

I came away last year being a little upset with myself for focusing too much in my .Net comfort zone, something I'm going to avoid this year. There are a couple of .Net sessions I want to see to learn some of the newer features, and one on Castle that I want to see. Beyond my comfort zone, there are a few Python sessions that I think I'll check-out. Oh, and I'll be in attendance at anything being presented by Neal Ford.

If you're planning on attending, look me up and say hi. I have a nullable composite key story to share with you. And, I don't own a speedo.

Yet.

Oh goody, the Fox portion of Bowl season begins...

8PM pre-game show.

8:30PM game start.

8:51 PM game actually sees a kick-off.

Only three more of these to go until things rightfully go back to ESPN, ABC, or CBS next fall...