Posted on November 27th, 2005

Just a short note to say that I’ve accepted an invitation to blog for Apress Publishers. It’ll be mostly on Agile tips and technologies, but I’ll still be doing good stuff here as well. I think they sent out invitations to the User Group owners which is how I ended up with one. Anyway, you can see all the blogging goodness here.

No Comments


Posted on November 23rd, 2005

I’ve been working more with FIT and FITnesse, especially the .NET port. I tried to locate a quick tutorial to get someone up and running on it with a very basic project, but couldn’t seem to come across one. Hopefully this will help you, or someone you love, get Fitnesse hooked into your .NET project for some Testing goodness.

Step 1 – Download and run Fitnesse

First, download the latest version of Fitnesse from http://www.fitnesse.org. The DotNet fitserver comes installed as part of the standard download.

Next, start the FIT server. Browse to it using ${browser.of.choice}. Create a page called MyFirstTest by appending MyFirstTest to your URL like: http://localhost:8080/MyFirstTest

Step 2 – Create a test page

Following the instructions from the DotNetFitServer page (http://www.fitnesse.org/FitNesse.DotNet.DotNetFitServer), edit your page and add the following lines:

!define COMMAND_PATTERN {%m %p}
!define TEST_RUNNER {dotnet\FitServer.exe}
!define PATH_SEPARATOR {;}

This hooks your wiki to the FitServer runner.

Now, add a test. We’ll use the normal division test. Add the following lines to your wiki page:

|Division| 
|numerator|denominator|quotient?|
|10       |2          |5        |
|12.6     |3          |4.2      |
|100      |4          |24       |

Now save it. It should look something like:

You’ll notice that you don’t see a “Test” button on the left hand side menu. This is because you need to tell Fitnesse this is a test page. Click on Properties, check “Test” under actions, and click “Save Properties”. You’ll now see the Test link show up on the left hand side menu. Click it! You should now see something like:

Which is Ok, because we haven’t defined an assembly. In fact, we haven’t done anything yet with .NET.

Step 3 – Create the .NET Class

So, our next step is to create a .NET project to run our code. Open Visual Studio.NET, and create a new class library project in a location that doesn’t have any spaces, like C:\FitnesseTutorial.

Once that is open, delete the Class1.cs file. Next, add a reference to the fit.dll which is in the dotnet directory of your fitnesse install location. For me, that is c:\fitnesse\dotnet\fit.dll. Now add a new class, Division, which inherits from fit.ColumnFixture. Notice that is the same name as the first row from the table we put in our wiki. Your class should look like:

public class Division : fit.ColumnFixture
{
  public double numerator = 0.0;
  public double denominator = 0.0;

  public double quotient()
  {
    return 1.0;
  }
}

Save and build that project.

Step 4 – Hook Fitnesse to the .NET Class

Now we have to get the wiki to “see” our class. This is accomplished with the !path line, so edit your wiki page and add the line:

!path C:\FitnesseTutorial\bin\Debug\FitnesseTutorial.dll

and save it. Now try running your test again. You should see something like:

Yay! Do a dance, or a jig. This means you have everything hooked up properly. If you are running into problems make sure:

  • You don’t have a namespace
  • You’ve specified the full path to your output dll
  • Your class extended fit.ColumnFixture

Step 5 – Get to Green

Now that you are here, modify your class to let this test pass:

public class Division : fit.ColumnFixture
{
  public double numerator = 0.0;
  public double denominator = 0.0;

  public double quotient()
  {
    return numerator/denominator;
  }
}

Assuming everything has worked up to this point, you should now see the following:

And that’s it! You’ve now succesfully modified a Fitnesse page to use the DotNet fit server and talk to a project you created. Now, go forth and get busy with those customer tests!

48 Comments


Posted on November 19th, 2005

After some prodding by the group, I’ve got a Wiki for the Charlotte Java User’s Group up and running at http://wiki.charjug.org. I’ve also transferred over John Currier’s excellent list of Java employers in Charlotte (be sure to check out his awesome SchemaSpy tool for databases).

Now I suppose I should get a site up for the CharlotteXP User’s Group ;)

No Comments


Posted on November 17th, 2005

I was going through trying to figure out how to get the version number of our built assemblies from NAnt. We specify them using AssemblyInfo.cs, so the GetVersion tasks weren’t working for me. I found a post by Michael Flanakin which outlined his way of pulling the version number from a file.

That gave me an idea to just load the assembly dynamically and pull it out of the assembly info. Here’s what I’m using, suggestions are always welcome.

       name="build.assembly.filename"
    value="C:\MyProject\bin\Debug\MyProject.dll"/>
  
    name="getversion"
    description="Get the version number from the assembly">
    
    
  

7 Comments


Posted on November 16th, 2005

Kelly Anderson recently sent over a layout manager for C# that models the Boxes and Glue method from TeX. For those of you not aware of that, the general concept as I understand it is having a UI made up of boxes that can resize dynamically and stay in relative position to each other based on “glue” between them. Apparently to fully grasp it you should be able to natively understand $y^3\alpha_x \to \beta$ (which looks a whole lot easier to read then y3ax ® b).

The layout manager is available under a Berkley License from http://www.cornetdesign.com/files/gm.zip

Anyway, the code came because of a discussion we’ve been having on the TDD and TFUI lists about Test-Driving GUI development, and what aspects should actually be tested. Of course, we all agree that one should use a healthy dose of MVP and push as much business and presentation logic to the presenter as possible. But what do you do with the views?

Well, first we should start with some options. Let’s assume we have a C# Winforms app. It looks like:

Ok, so it’s ugly. It happens to be the Example app Kelly sent me. Anyway, we’ll say that it has logic that when a user clicks on Button1, and then Button2, it displays a message telling them they won.

Otherwise, it hides the button before the last one they clicked:

Ok, so the business logic is (theoretically) easy enough to test. But what about the view itself, the thing that made the (not-so)pretty pictures above?

Well, our options to test that the layout is working would be:

  • Manually look at it
  • Do screen shots and use an image comparison utility to compare them
  • Use something like NUnitForms to verify the controls are present (but maybe not the layout)
  • Don’t. It’s too simple to break

Well, as the above list implies, maybe there is more to testing the view than the layout. For example, one of the keys to having robust NUnitAsp tests is to only test for the existance of things that need to be there and basically trying to keep your tests as small as possible so that you don’t have these large, fragile tests.

Kelly’s hypothesis, as I understood it, was that by using a layout manager you could test the layout of the controls, and know that they sized themselves correctly. So, perhaps one is not quite at 100% confidence that the tests are going to be able to validate everything is kosher, but by verifying the presence and layout of the controls, one can be fairly confident in making changes, with maybe some minor manual testing just to get the initial verification level up.

I decided to test this out with the layout manager. Using the above game I created, I decided that it needed a new feature where the buttons switched positions. Basically the last button, instead of hiding, would switch positions with the button the user just clicked. So if we had:

3|4

2|1

and the user clicked on buttons 1 and then 3, it would end up with:

1|4

2|3

and if they then clicked on button 4, it would swap positions again:

1|3

2|4

Well, now it looks like we have some tests! The first test I want to write is:

[Test]
public void Button2IsLeftOfButton1()
{

}

Let’s see what the Layout Manager Kelly sent over has to offer. Well, his LayoutContainerBase has a GetAlignment() that returns a ContentAlignment object, which happens to be an enum with things like BottomCenter and TopRight. My plan is to use that to verify that two controls are next to each other. The logic will be that controls on the same row can be left/right of each other, and controls on the same column can be top/bottom of each other. Let’s finish out that test:

[Test]
public void Button2IsLeftOfButton1()
{
  ContentAlignment button1Alignment = gridLayoutPanel1.GetAlignment(button1);
  ContentAlignment button2Alignment = gridLayoutPanel1.GetAlignment(button2);
  Assert.IsTrue(ControlIsLeftOfControl(button2Alignment, button1Alignment));
}

private bool ControlIsLeftOfControl(ContentAlignment control1, ContentAlignment control2)
{
  return false;
}

Ok, so we get the Red Bar. This should be easy enough, right? Let’s see, a little implementation here:

private bool ControlIsLeftOfControl(ContentAlignment control1, ContentAlignment control2)
{
  string possibleLeftControl = control1.ToString();
  string possibleRightControl = control2.ToString();
  int leftControlRow = GetRowFromControlString(possibleLeftControl);
  int rightControlRow = GetRowFromControlString(possibleRightControl);
  int leftControlColumn = GetColumnFromControlString(possibleLeftControl);
  int rightControlColumn = GetColumnFromControlString(possibleRightControl);

  return leftControlRow == rightControlRow && leftControlColumn < rightControlColumn;
}

a little more there:

private int GetRowFromControlString(string str)
{
  if(str.IndexOf("Bottom") > -1)
  {
    return 0;
  }
  else if(str.IndexOf("Middle") > -1)
  {
    return 1;
  }
  else if(str.IndexOf("Top") > -1)
  {
    return 2;
  }

  return -1;
}

private int GetColumnFromControlString(string str)
{
  if(str.IndexOf("Left") > -1)
  {
    return 0;
  }
  else if(str.IndexOf("Center") > -1)
  {
    return 1;
  }
  else if(str.IndexOf("Right") > -1)
  {
    return 2;
  }

  return -1;
}

and voila! Red Bar! ;) (Smacks self on head). Where’s a pair partner where you need it. More importantly, where are the tests for all that crazy logic?!

Ok, let’s back up. Let’s see if this is doing what I want. Let’s start by testing the same row and same column. I definately need to extract those out into methods:

[Test]
public void TestFakeControlStringAlignmentShouldBeOnSameRow()
{
  string fakeControl1Alignment = "BottomLeft";
  string fakeControl2Alignment = "BottomRight";
  Assert.IsTrue(ControlStringsAreOnSameRow(fakeControl1Alignment, fakeControl2Alignment), "Controls not on same row");
}

private bool ControlStringsAreOnSameRow(string control1, string control2)
{
  int leftControlRow = GetRowFromControlString(control1);
  int rightControlRow = GetRowFromControlString(control2);
  return leftControlRow == rightControlR
ow;
}

Ok that got me a green bar for that test. Now, lets see about that left/right thing:

[Test]
public void TestFakeControlStringAlignment1ShouldBeLeftOfAlignment2()
{
  string fakeControl1Alignment = "BottomLeft";
  string fakeControl2Alignment = "BottomRight";
  int control1Column = GetColumnFromControlString(fakeControl1Alignment);
  int control2Column = GetColumnFromControlString(fakeControl2Alignment);
  Assert.IsTrue(control1Column < control2Column, "Control 1 not left of (less than) Control 2");
}

And green bar for that test as well! I’m on the edge of using the debugger, which means something is *way* too complicated here. Time to step back for a second. And yep, there it is. I’m making the assumption that control1.ToString() for a ContentAlignment will give me something like “BottomRow”. Which, my guess is, it isn’t. Let’s just check and see:

[Test]
public void Button1ContentAlignmentToStringIsInARow()
{
  ContentAlignment button1Alignment = gridLayoutPanel1.GetAlignment(button1);
  Assert.IsTrue(GetRowFromControlString(button1Alignment.ToString()) > -1,
    String.Format("Content Alignment string '{0}' not in a row"), button1Alignment.ToString());
}

Which green bars. I even cheated and Console.WriteLined it out, and sure enough, it’s TopLeft. Wait! TopLeft? On the screen shot I have it’s on the bottom right! And imagine that, I started with too coarse a test and sure enough it bit me. So, let’s do:

[Test]
public void Button1ContentAlignmentShouldBeBottomRight()
{
  ContentAlignment button1Alignment = gridLayoutPanel1.GetAlignment(button1);
  Assert.AreEqual("BottomRight", button1Alignment.ToString(),
    String.Format("Button1 alignment '' is incorrect", button1Alignment.ToString()));
}

[Test]
public void Button2ContentAlignmentShouldBeBottomLeft()
{
  ContentAlignment button2Alignment = gridLayoutPanel1.GetAlignment(button2);
  Assert.AreEqual("BottomLeft", button2Alignment.ToString(),
    String.Format("Button2 alignment '' is incorrect", button2Alignment.ToString()));
}

Which fail saying that Button1 is at TopLeft, and Button2 is at MiddleCenter. And looking at the property windows, it appears to be some default thing, as Buttons 3 and 4 are also at TopLeft.

Well, I guess the layout manager isn’t quite as straightforward as I thought. But it taught me a heck of a lesson. When you try to leap too far ahead, it can bite you hard. In this case, Nearly 2 and a half hours of work for not putting in one test. I think I’ll sleep on this some more and give it a try over the weekend.

1 Comment


Posted on November 16th, 2005

I guess one can never hit the big time until you make it into a Dilbert Cartoon. So, I guess that means XP/Agile has made it.

(Thanks to Dale Emery for pointing it out on the XP list)

No Comments


Posted on November 11th, 2005

Interesting little trick I came across today. I had a list of values that looked like:

Compare time: 0.109375s
Compare time: 0.015625s
Compare time: 0.03125s
Compare time: 0.015625s
Compare time: 0.03125s
Compare time: 0.015625s

I wanted to add up all the values, and didn’t have access to a Linux box (where I could just run awk in a while loop), nor do I have Python installed on here.

So, I opened up the list in notepad, replaced all the “Compare time: ” with an empty string. Then, something told me to try replacing the trailing “s” with a plus sign, and pasting it into the windows Calculator window. I tried it with just the first two:

0.109375+
0.015625

and sure enough, it worked. So I copied the entire list, and pasted it into the Calculator window, and viola! I had my answer. For once, a nice surprise in a GUI!

1 Comment


Posted on November 10th, 2005

Yes, yes, Oh my gosh, it’s so cool that now the world has brought up Web 2.0 and AJAX we’ll finally be able to have full-fledged apps from the browser. Whoop de doo.

Please. I mean, first, AJAX isn’t all that new. Yes, it is now gaining support in mainstream browsers, but it didn’t just appear last week. Don’t get me wrong, people do some great stuff with it. I use Google Maps just about daily. It’s not the technology itself that annoys me. It’s stuff like this:

What new features will AJAX bring to Web applications?

Farris: AJAX enables advanced features like drag ‘n drop, dropdown menus and faster performance capabilities, which are now making their way into Web applications. These kinds of capabilities represent a significant leap in the advancement of Web apps. More than just creature comforts, they represent a major step forward in terms of usability, productivity and application functionality.

Before AJAX, Web apps would have to work around the lack of something like drag ‘n drop with check boxes and multiple clicks, resulting in multiple steps that quickly become laborious and time-consuming for users.

Uh, no. Maybe before DHTML. Definately before Javascript. AJAX is Asynchronus XML. This means that its purpose is to allow you to fire off a call and not have to wait around for the response, which you can then parse when you get it back.

Not that I’m the first to notice this. But this particular article was such an amazing amount of misinformation it was silly.

Now back to your regularly scheduled agile blog. ;)

No Comments


Posted on November 4th, 2005

Recently, I got an email from someone who was trying to figure out how they should go about testing a private void class. They had an existing legacy app they were trying to get under test, and just weren’t sure how to approach it. The methods looked like:

private void menuItem15_Click(object sender, System.EventArgs e)
{
  Fdialog = new FontDialog();
  Fdialog.Font = rtbDisplay.Font;
  if(Fdialog.ShowDialog()!= DialogResult.Cancel )
  {
    rtbDisplay.Font = Fdialog.Font;
  }
}

which is one of the harder classes to test – an event handler that creates a UI widget, and sets some other UI widget.

So, how does one go about testing something like this? Well, first we start by asking what it is we want to test. In the above snippet, you have two seperate things going on. One, when a user clicks a certain menu item, they are asked what Font they want to change to. Two, when a user selects a Font from a specific dialog, the font of their display element should change.

My first suggestion was simply to manually test this. Click the button, choose a font from the display, and see if the display font changes. Conversely, click the button, choose cancel from the dialog, and make sure the display font doesn’t change.

And while that’s all well and good, it doesn’t answer the question of how we could test this in an automated fashion. First and foremost, we need to get this into a single-responsibilty harness so we can test the actions independently. Fairly simple, just extract method from the event handler:

private void menuItem15_Click(object sender, System.EventArgs e)
{
  rtbDisplay.Font = GetFontFromUserSelection(rtbDisplay.Font);
}

public Font GetFontFromUserSelection(Font defaultFont)
{
  Fdialog = new FontDialog();
  Fdialog.Font = defaultFont);
  if(Fdialog.ShowDialog()!= DialogResult.Cancel )
  {
    return Fdialog.Font;
  }

  return defaultFont;
}

That doesn’t really buy us a lot though, because even if we called GetFontFromUserSelection from a test, we’d have to deal with a UI element. So, the next step is to handle only having the UI element called when we want to. To do that, I’m going to inject the control that GetFont should use. To do that, I’m going to choose to have GetFont act on an interface. So, now we have:

public interface IFontDialog
{
  DialogResult ShowDialog();
  Font Font{get; set;}
}

Which we now subclass FontDialog so we can have it implement our interface:

public class MyFontDialog : FontDialog, IFontDialog
{

}

with those classes created, we can now do:

private void menuItem15_Click(object sender, System.EventArgs e)
{
  rtbDisplay.Font = GetFontFromUserSelection(rtbDisplay.Font, new MyFontDialog());
}

public Font GetFontFromUserSelection(Font defaultFont, IFontDialog fontDialog)
{
  fontDialog.Font = defaultFont);
  if(fontDialog.ShowDialog()!= DialogResult.Cancel )
  {
    return fontDialog.Font;
  }

  return defaultFont;
}

Up to this point, the app should still work exactly as it did before. Unfortunately, because we don’t have any tests in place, we can’t know, but I’d be willing to bet on it (and I’m not much of a betting man).

So, now we have a nice seam where we can pass our own FontDialog and see just what happens. So, let’s create a FontDialog we have a little more control over:

public class MockFontDialog : IFontDialog
{
  public MockFontDialog() {}

  public Font userFont;
  public Font MOCK_SELECTED_FONT = new Font("Times New Roman", 14);

  public DialogResult ShowDialog()
  {
    return DialogResult.OK;
  }

  public Font Font
  {
    get{return MOCK_SELECTED_FONT;}
    set{userFont = value;}
  }
}

Based on that, we can now write our first test:

[Test]
public void UserSelectionOfANewFontShouldReturnTimesNewRoman()
{
  Font defaultFont = new Font("Arial", 16);
  Font expectedFont = new Font("Times New Roman", 14");
  MockFontDialog fontDialog = new MockFontDialog();

  MyForm form = new MyForm();
  Assert.AreEqual(expectedFont, form.GetFontFromUserSelection(defaultFont, fontDialog));
}

And, our second, which I’m going to just call the event handler directly:

[Test]
public void UserSelectionOfANewFontShouldChangeTheDisplayFont()
{
  Font defaultFont = new Font("Arial", 16);
  Font expectedFont = new Font("Times New Roman", 14");
  MockFontDialog fontDialog = new MockFontDialog();

  MyForm form = new MyForm();
  form.menuItem15_Click(null, null);
  Assert.AreEqual(expectedFont, form.Display.Font);
}

Which fails! That’s because, even though we can inject a MockFontDialog into the GetFontFromUserSelection method, we don’t have a way of injecting it into the form.

There’s a couple of things we could do here. We could inject the FontDialog into the Form itself. Or, we could have the form ask what FontDialog it should use, say, from a Factory method:

private void menuItem15_Click(object sender, System.EventArgs e)
{
  IFontDialog fontDialog = FontDialogFactory.GetFontDialog();
  rtbDisplay.Font =
    GetFontFromUserSelection(rtbDisplay.Font, fontDialog);
}

We can then use the Factory to return the appropriate object based on whether we are testing. It’s not ideal, but such is the case when you are dealing with legacy code. I’ll use a configuration setting here to determine it:

public class FontDialogFactory
{
  public static IFontDialog GetFontDialog()
  {
    bool weAreTesting =
      bool.Parse(ConfigurationSettings.AppSettings["testing"]);

    if(weAreTesting)
    {
      return new MockFontDialog();
    }
    else
    {
      return new MyFontDialog();
    }
  }
}

And there you have it. A way to test what is going on with UI elements using a sprinkling of mocks and a touch of dependency injection. Not pretty, but if you need to get your UI elements under test, this might be one option for you. Ideally your business and presentation logic would actually delegate to a presenter which you could then mock much easier (known as the Model-View Presenter pattern).

So, in summary. To test an “untestable” method, y
ou have to inject some sort of a seam. Whether it be a variable inside whose results you can test, a side-effect you can check, or extracting a method and injecting mocks, getting a seam in the method is the most vital part to getting it under test.

6 Comments


Posted on November 2nd, 2005

I was excited to come across Nokia’s new open source site. Combining that with their recent announcement to be on board with Eclipse, and it just goes to show how much I love that platform.

I’ve heard rumors that they are going to be releasing a way to build apps in C# for their Symbian phones. Don’t know if that will pan out, but would be very interesting, and almost definately would cause my employer to start moving away from J2ME and Java in general (not that we do much now – sadly we seem stuck that the Microsoft way is the only way).

No Comments