
For those of you who in the U.S. who are changing your clocks back an hour tonight, and even for those of you who aren’t, be sure to change the batteries in your smoke and carbon monoxide detectors.
If you don’t have a smoke detector, you can purchase them pretty cheaply at any store like Wal-mart. Generally most fire departments provide them for free if purchasing them is a financial burden.
Be safe! ;)
As I mentioned in an earlier post, I’ve been helping some fine developers port over FIT from Java to C#. The SpreadsheetRunner is part of that, but there are other core ones that SpreadsheetRunner inherits from, namely CustomRunner and MakeParse. Since I could find the existing unit tests for those I gave it the ol’ try of porting those first.
Here were my steps:
1) Open the file in Eclipse (or Wordpad, depending on my mood)
2) Create a class with the same name in VS.NET
3) Copy everything between the class declarations from the Java class to the C# class
4) change static finals to consts
5) remove any throws BlahException
And build. And except for some minor tweaks (like the Java standard using lowercase first letters for method names vs C#’s uppercase) it pretty much worked. Yes, I had to stub some classes (like PrintWriter).
Actually, the funny thing was that I stubbed the classes and couldn’t figure out why my NUnit tests were failing with expected: <"Blah\nBlahBlah"> but was: <"Blah\n\r\nBlahBlah"> which I first chalked up to an MS encoding problem. But then I realized that in my stub PrintWriter I had done:
public void print(string msg)
{
if(writer == null)
{
Console.WriteLine(msg);
}
else
{
writer.WriteLine(msg);
}
}
Instead of:
public void print(string msg)
{
if(writer == null)
{
Console.WriteLine(msg);
}
else
{
writer.Write(msg);
}
}
So, *I* was adding in the extra line break. Once I caught that, All greens for the TestMakeParse tests! Progress is in hand.
Speaking of silly things, today I was working on a WinForm app. I had a task to fix an issue where our window that tells the user that something is downloading wasn’t defaulting the focus back to the Ok button once the download was finished. Basically we have an Ok and Cancel button, and only the Cancel button is enabled while the stuff is downloading. When it finishes, we reenable the Ok button so the user can continue on. “Simple enough fix,” I thought to myself, “I’ll just focus it!” So I tried:
buttonOK.Focus();
Hmmm, nope. lessee, how about:
buttonOK.Select();?
Ok, not that either. Google, Google, Google…ah, how about:
this.ActiveControl.buttonOK?
Sigh. Fine. I’ll just pull the cancel button off:
buttonCancel.Visible = false;
Which meant that if the user hit Enter, at least they would continue. It still didn’t put the dotted outline focus indicator over the Ok button though. I finally stumbled across the solution. Since I only had two buttons, and Ok was TabIndex 1 and Cancel was TabIndex 2, I used SelectedNextControl:
SelectNextControl(
Control ctrl,
bool forward,
bool tabStopOnly,
bool nested,
bool wrap
);
Nice. At least it worked. Another card in the finished stack.
Last week a renewed interest came up on the Fitnesse list about getting a .NET port running. Several people had started various bits, and all decided to try to come together to get it running. As part of that, I threw in my hat and got assigned to get FolderRunner (meaning SpreadsheetRunner) working. Basically this allows one to run FIT against a Spreadsheet. It uses Poi to parse the spreadsheet and figure out what is test and what is content.
The thought was that in .NET this would be much easier, since, after all, Excel *is* a Microsoft product. I decided to keep a running log of my efforts to get this to work, TDD style.
Once I had my environment setup, I created two projects. SpreadsheetReader and SpreadsheetReaderTests. I got to work right away making sure I could find the file:
[TestFixture]
public class SpreadsheetRunnerTests
{
public const string TEST_SPREADSHEET = @"C:\SpreadsheeRunner\test.xls";
[Test]
public void ThisShouldWork()
{
Assert.IsTrue(true);
}
[Test]
public void TestSpreadsheetShouldExist()
{
SpreadsheetReader.SpreadsheetReader reader =
new SpreadsheetReader.SpreadsheetReader();
reader.LoadSpreadsheet(TEST_SPREADSHEET);
Assert.AreEqual(TEST_SPREADSHEET, reader.SpreadsheetFileName);
}
}
This of course wouldn’t compile. So I added the SpreadsheetRunner classes:
public class SpreadsheetReader
{
private string spreadsheetFileName = String.Empty;
public SpreadsheetReader(){}
public void LoadSpreadsheet(string filename)
{
if(File.Exists(filename))
{
FileInfo fileInfo = new FileInfo(filename);
spreadsheetFileName = fileInfo.FullName;
}
else
{
throw new FileNotFoundException();
}
}
public string SpreadsheetFileName
{
get{return spreadsheetFileName;}
}
}
Ok, green bars all the way around. Time to get to some real work. The Excel file I’m using came straight from the FitLibrary’s test source. I figured the next easiest step would be to just read in the text from the first column of the first row. From the test spreadsheet, that text should read “Calculate the discount with Fit:”.

Simple enough, really. But how does one open Excel from C#?
I had done some preliminary research, and remembered seeing something like Application.Excel(). But my intellisense didn’t seem to “sense” that, so to Google I went. The first article I stumbled across was “How to Open and Read an Excel Spreadsheet into a ListView in .NET.” Aha. I have to add the Excel Object Library from the Com references. However, the article said it was 9.0, and mine had 11.0:

I added it anyway. I then set up my test:
public const string TEST_SPREADSHEET_ROW1_COL1_TEXT = "Calculate the discount with Fit:";
[Test]
public void RowOneColumnOneShouldContainText()
{
string row1Column1Text = reader.GetTextFor(1,1);
Assert.AreEqual(TEST_SPREADSHEET_ROW1_COL1_TEXT, row1Column1Text);
}
Which didn’t compile, so I added some code to my SpreadsheetRunner:
public string GetTextFor(int row, int column)
{
return "Calculate the discount with Fit:";
}
Ok, green bar. But now I have to make this pass for real. Looking at the article, the first thing they do is private Excel.Application ExcelObj = new Excel.Application();. I try that, but Intellisense tells me Excel.Application is an interface. There is an Excel.ApplicationClass which looks promising, and I spike down that road for a bit with very little luck. I do some googling and find that ApplicationClass was the right thing to use, and that it has a Workbooks.Open() method that looks like (wait for it…):
WorkBooks.open(string Filename,
object UpdateLinks,
object ReadOnly,
object Format,
object Password,
object WriteResPassword,
object ReadOnlyRecommend,
object Origin,
object Delimiter,
object Editable,
object Notify,
object Converter,
object AddToMru,
object Local,
object CorruptLoad )
I look back at my article, and it seems like I’ve caught back up to it. It says I can get the sheets by using something like Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1);. So I give that a shot. But then I see my first mistake. Excel doesn’t think of the columns as 1-n, it thinks of them as A-Z. Actually, it thinks of row/columns as A1 for column A of row 1. I change the GetTextFor method signature to account for this. So let’s see if we can get some text:
public string GetTextFor(int row, string column)
{
Excel.Application excelApp = new Excel.ApplicationClass();
try
{
excelApp.Visible = false;
Excel.Workbook excelWorkbook = excelApp.Workbooks.Open(spreadsheetFileName,
0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "",
true, false, 0, true, false, false);
Excel.Sheets sheets = excelWorkbook.Worksheets;
Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1);
Excel.Range range = worksheet.get_Range(column + row.ToString(),
column + row.ToString());
return (string)range.Text;
}
finally
{
excelApp.Quit();
}
return string.Empty;
}
You’ll notice the try/catch block. I found that if I didn’t make sure I called Quit() the app would hang around in memory, and since I set it’s visibilty to false, I couldn’t close it without going to the Task Manager. So, I hit run and:

Never felt so good to get a green bar!
Now that the hard part is out of the way (actually loading the app and reading from it), the next step is to begin going through the FIT tests and getting them to work here. But not tonight, I like to end on a good note, and this is a fine spot for that!
On the XP list, Dominic Williams wrote in with:
I don’t want to give the impression of dodging your questions, so I’ll contribute what I can below. However, are you or your boss assuming that if XP or Agile has been done before in a similar company, it is somehow less risky for you to try, and you can apply some of the same recipes? I think those assumptions are very wrong. I don’t think you should even consider adopting a new methodology if you don’t want to take risks, and above all if you are not prepared to go through the difficult and long process of finding /your own way/ of doing agile development. Just slapping someone else’s XP or Agile onto your company won’t work.
This struck home with me. Lots of people I’ve run across, and several I’ve seen post to the XP and other lists, are looking for safe ways to do XP. “We don’t have enough time to do TDD.” “If the pairs just get stuck in a corner no one will learn anything.” Etc, etc.
XP, Extreme Programming, has a very intriguing word in it. No, not programming. Extreme. Extreme is defined as:
- Most remote in any direction; outermost or farthest: the extreme edge of the field.
- Being in or attaining the greatest or highest degree; very intense: extreme pleasure; extreme pain.
- Extending far beyond the norm: an extreme conservative. See synonyms at excessive.
- Of the greatest severity; drastic: took extreme measures to conserve fuel.
- Sports.
- Very dangerous or difficult: extreme rafting.
- Participating or tending to participate in a very dangerous or difficult sport: an extreme skier.
- Archaic. Final; last.
While the second one seems more related, I like the third definition. “Extending far beyond the norm.” Extreme programming to me is stating that you are tired of the norm, you want more, you want better.
Let me emphasize. You are tired of the norm. To be tired of the norm, and to go past that means going some place that most don’t or aren’t going. This means risk. You might find out your team can’t self-manage. That they cheat to get around the CI server by not checking in their code. That they have lots of tests like:
public void TestWidgetAInitializesWidgetB(){ Assert.IsTrue(true); }
So what’s on the other side? What do you see as the end goal for XP? It works best when you have a goal in mind. For example, at my work I see XP as helping to resolve central issues around project visibility and quality. We already deliver prototypes and build off of that (for good or bad), so short iterations isn’t as big of a concern to be.
I think about bungee jumping. First, you had the crazy people who tied cords to bridges and jumped. Then, you had others who saw that, but wanted to be more sure and so used really good cords. Others wanted to do it, but didn’t want to jump off a bridge. Next thing you know you have bungee jumping at a fair over a big inflatable cushion in case something happens. And if it does, you know a lawsuit is going to happen. People want the experience without the risk of blazing the trail to get it.
So, now it is rare to see much about bungee jumping. But people still are pushing it. Bungee jumping from hot air balloons. That kind of stuff. They keep growing, keep learning and keep taking risks to acheive that goal.
So what’s a company to do? You want better software, you hear about this XP thing being the wave of the future, but it all sounds so scary. No BDUF? Two week iterations? Pairs switching projects? Letting the customer be able to run any release?!
Start with your problem. Why aren’t you delivering better software giving more value to your customers? Poor software? Vague requirements? Changing requirements? Poor project management? In those cases look at the XP practices. Ask around. See what could help. Maybe TDD helps improve the quality of your code. Maybe a CI server resolves issues around deployments. Maybe planning games help smooth out the changes in requirements. Take a small risk, and work with it. Manage it. Box it in. Maybe try another. See how it goes.
Once you’ve done that, ask yourself, “Can we now make the jump?”. XP is as much about a culture change as it is process change. Individuals and interactions over processes and tools. Working software over comprehensive documentation. Customer collaboration over contract negotiation. Responding to change over following a plan. Scary terms, ones that maybe your company doesn’t have the culture to do. If you can’t say, “This seems to be working, let’s do it” then I would say that you don’t have the culture to be an XP organization. And that’s not a bad thing, if it is working for you.
I live with the fact every day I’m not going to be an Extreme BMX guy. I admire those who do it, I try out bits and pieces (say, on a video game from the safety of my couch). But I know I’m not the kind of person who is going to do that. I still consider myself a good person. You can still consider your organization as a good organization.
We’re just not Extreme.
We’ve finally finished the move into our new offices at work. Friday was an absolute madhouse. We cut off the servers at noon, packed them up in my truck and carted them over to the new space while the movers ripped down all the cubes and loaded the boxes. The new server room is a gem – real racks, overhead cable management, cross-connect patch bays, just great. We got all the servers up in just over 3 hours – about how long it took them to get the T-1 up (that should have taken about 15 minutes).
Went in today and helped move in some of the rest of the stuff and got my cube setup. It’s a nicer office, not much more room. The down side is that somehow no one bothered to think about the fact that we are a software development company and therefore need *lots* of space for whiteboards. I have two in my cubicle alone. Unfortunately they didn’t give us enough wall space to do that here, so I had to fashion a wall out of my big whiteboard attached to a bookshelf I had built. Strange, but works.
In other news, turns out I *won’t* be going to Vegas. Which hopefully Brady will be able to get all of the DB info from them so it all goes smoothly. Things aren’t good at work right now. I don’t have as much hope that I’ll be able to get XP working there – I just don’t think we can push a culture change to make it happen. We have some top-notch devs who believe in it, and that’s the angle I am going to approach it from. It’s really quite frustrating – not to mention being told that management doesn’t trust the dev team, nor thinks they can write good code, and that the only reason we will be able to get anything done is for them to sit at our cube over our shoulder watching what we’re doing.
I mean, really. I could see a bunch of monkey programmers they were paying whatever for. Or even a team that only had one rock-star developer. Neither of which is us. We have a team of incredibly smart, hard-working, committed developers. Possibly one of the best teams I’ve ever worked with (second only to Wachovia – of course we did pull over half of the team from there anyway). Wow! I just realized that ex-Wachovians make up a majority of the team with Keith leaving. Crazy.
Bah. Enough of work for this weekend. I’m working on a PostNuke module, so should head back to that. Maybe I’ll feel better after wafting through some nutty PHP code.
Recently, Ken Boucher brought up a term on the Maverick Software newsgroup: Serviceability. He defined it as such:
What’s serviceable?
Serviceable is the Holy Grail as found in Indiana Jones and the
Last Crusade. It’s meatball surgery from M*A*S*H 4077. It’s
a picnic table. It’s breakfast at 8pm in the kind of diner that
you just can’t find anymore because they don’t make diners
that like anymore.Serviceable isn’t sloppy any more than it’s precise. It may not
be fancy but it delivers every time. You probably can’t but it
anymore but your grandparents still have one in the tool box or
in the kitchen. (My parent’s stove is in it’s 30’s and still works
perfectly).It’s a Louisville Slugger. The kind of unspoken solidness that
reputations are built off of.Serviceable doesn’t come from TDD or refactoring or NLP.
They’re just tools. And when the tools become more important
than the product it shows. It’s what happens when the customer
comes first. Not XP. Not UML. Not racking your mind trying to
find the phrase that will let you enter the zen state of no-mind.
It’s just rolling up your sleeves and delivering to the customer.Serviceable. Maybe it’s not the best word, but it’s the kind
of word a craftsman would use.
Indeed. But what really is serviceable, and can it fit in with software development? From the dictionary:
1. Ready for service; usable: serviceable equipment.
2. Able to give long service; durable: a heavy, serviceable fabric.
So, code would be serviceable when it was “done”, meaning it was ready to be used by the customer. Also when it was able to give long service. So what does it mean to give long service? If you had to repair the VW bug engine every week, is it still serviceable? Let’s see what else is out there…
From a Thesaurus:
1. In a condition to be used: employable, usable, utilizable. See used/unused.
2. Serving or capable of serving a useful purpose: functional, handy, practicable, practical, useful, utilitarian. See used/unused.
I like the second one. “Capable of serving a useful purpose.” As J.B. Rainsberger once put it (and I believe he got it from Mary Poppendieck), code that doesn’t deliver value to our customers is just inventory. Inventory isn’t serviceable. Interesting. What else?
From WordNet:
Meaning #1: ready for service or able to give long service
Antonym: unserviceable (meaning #1)Meaning #2: having a beneficial use
Meaning #3: intended or able to serve a purpose without elaboration
2 and 3 are both interesting. Again the beneficial use definition. Something is serviceable when it is useful. 3 is especially interesting, “without elaboration”. Elaboration? “The process of working out in detail by labor and study.” Ah. So, maybe not just useful code, but code that doesn’t require labor and study to understand how to use. Sounds like we’re getting somewhere. Clear, useful code.
From Wikipedia:
In civil engineering, serviceability refers to the conditions under which a building is still considered useful. Should these limit states be exceeded, a structure that is still structurally sound would be considered unfit. For example, a highrise building could sway severely and cause the occupants to be sick (much like sea sickness), yet be perfectly sound structurally and in no danger of collapsing. This building is obviously no longer fit for human occupation, yet since it is in no danger of collapse, the structure would be considered as having exceeded serviceability limit states.
Which I think fits in with the other defintions. Something that may meet all the requirements, but doesn’t give value isn’t serviceable. The building in the example, though it met all of the specs laid out by the customer, and people could indeed live there, didn’t ultimately give value to the customer because they wouldn’t be able to make any money off the building.
A very interesting thought indeed.