Wednesday, October 29, 2008

Focusing on Functional



kick it on DotNetKicks.com
I have been toying with functional programming a bit lately. I have been using lambdas and Linq when it has made sense in my code. I downloaded the F# compiler tools and mucked around with it a tiny bit. I read a few blogs that talk about functional programming concepts, etc. I have enjoyed reading the elegance of the paradigm, but never really got into it much.

But then I sat in on an "Open Space" session where Scott Guthrie was talking. Most of it strayed from the standard "Open Space" format and was more of a Q&A, but I guess this happens sometimes when big names show up. Anyways, one thing he said really stuck with me. It may not be a new idea, but it really resonated with me... I just hadn't thought about it this way before.

He said that in functional programming, you are declaring WHAT you want to do, instead of HOW you want to do it. In other words, in a functional language, you might describe a pattern to select from a collection (WHAT). In a more procedural language, you would do the same thing with a "foreach" loop (HOW).

This distinction isn't just semantic. It is extremely important for parallel programming. A loop is very hard to run in parallel since the compiler has a difficult time determining side effects. When you describe what you want done in a functional language, your compiler/framework CAN add parallelism. You let your tools figure out how to do the work in a parallel way.

It became clear to me that I need to take functional programming more seriously. Our hardware is no longer increasing in speed. Instead, the number of processors increase our computing power. If we can't figure out how to spread the work over multiple workers, we will never be able to take advantage of that power.

Functional languages have the potential to execute in parallel much more than procedural languages. I am making a promise to myself that I will become much more proficient in the functional paradigm. It seems to be the responsible thing to do.

Monday, October 27, 2008

The Excitement that is C# 4.0



kick it on DotNetKicks.com
I just got back from the “Future of C#” talk at PDC by Anders Hejlsberg. This was a truly inspiring talk for a geek like me. C# is evolving into a much more dynamic language. I have always been a believer of strong typing… except when I’m not… and I have been wishing for something more dynamic (such as Duck Typing). In C# 4.0, we will be seeing some significant dynamic features.

In reality, the thing that has kept me away from using languages such as IronPython and IronRuby is their interoperability with strongly typed languages. I really believe in the concept of “The right language for the job”, but I hate the idea of sticking to that one language for the entire project. With the dynamic capabilities in C#, it will be MUCH easier to talk to Python or Ruby code. If I need to implement something really loosely (like a calculation engine), I will be able to jump into something loose. Then, when I want to work with that code in my more strongly typed environment, I will have that ability. The “Right Language for the Job” paradigm has just become much finer grained.

So here are the details.

Dynamic Keyword
First and foremost is the dynamic keyword. This is kind of like using the object keyword, but you are saying that all of your binding will be at runtime. You will loose your intelisense, of course, but you will now be able to call into methods that have not been previously defined.

The neat thing about this is that you can make your statically defined classes be dynamic by implementing the IDynamicObject interface, which allows you to have access to the late binding calls.

Named and Optional Parameters
Next is something that C++ has and C# has needed for a long time – Optional Parameters. You can set defaults in your method declaration and the caller doesn’t need to specify the parameters. In addition, you can name the parameters in the method calls. This is really great for readability… especially when you are passing a bool into a method that you have no idea what it does.

Better COM Interoperability
These previous features (Optional and Named Parameters) are really useful to add to the new COM Interoperability features. Basically, pairing the dynamic and parameter features, talking to COM controls looks very natural.

Covariants and Contravariants
Finally, but certainly not least, we are getting covariance and contravariance. This is something that has bugged me since I have started with C#. Currently, if a method takes IEnumerable<BaseType>, you can’t pass IEnumerable<DerivedType>. I Hate having to convert the derived set to a base set just to pass it in. In C# 4.0, this will be fixed.

Looking Forward
In future version of C#, we will start to see hooks into the compiler. This will open the door for Domain Specific Languages (DSL) and Meta Programming. We will also see the C# compiler as an embedded service within .NET. This means that we can run Eval(“doSomething()”). It also means that we can start to think about embedding C# as a scripting language for our application… much like Javascript in the HTML DOM.

I am hoping to see C# 4.0 soon. Better yet, I am hoping to see C# 4.0 in the bits we get tomorrow!

PDC -- Microsoft Azure



PDC has commenced. Herds of people flocked to the keynote where the topic was infrastructure. It may not be the most sexy of topics, but it is certainly the way that Microsoft is moving with their business plan. Specifically, they talked about their new cloud OS dubbed “Microsoft Azure”. Azure is going to be a scalable infrastructure for hosting cloud applications.

One of the most interesting parts of this talk for me was the actual coding demo. They have included an embedded Azure simulator for debugging. It will let you develop your cloud app in your IDE without uploading it to their servers.

Another important aspect of Azure is the ability to easily add more resources to your application. Whether it be ASP.NET or Silverlight, you will be able to run your app from their Azure cloud server and scale the resources as you see fit. Need to add resources for the Christmas season? No problem. In January, you can just reduce the resources assigned.

Deployment is another important aspect of the Azure system. It is very easy to deploy your application to their servers via a single upload. Because I am here at PDC, I will have access to the Azure server today. I think I will go sign up now!

Thursday, October 23, 2008

My Year With TDD



kick it on DotNetKicks.com

It's been over a year now since I have been developing using TDD (Test Driven Development) as my primary development practice. I wanted to reflect on what it has done for me professionally. In reality, the past year has been great for my professional career in many ways.

I started out in August of 2007 with what I THOUGHT was TDD. Sure, I wrote my tests before my code, but the philosophy behind it wasn't enough to be effective. It wasn't until I went to Boston for a 3-day seminar on TDD taught by Rob Myers of NetObjectives that I really understood the power and relevance of TDD. His challenge was simple -- Try it completely for 30 days. If you don't find the value in it, then move along and look for something else.

So, this is what I did. I spent 30 days practicing TDD the way Rob taught us. I followed the following algorithm:

usb-cross

  1. Write a test
  2. Watch it fail
  3. Write the MINIMUM necessary to make it pass
  4. Watch it go green
  5. Refactor if necessary
  6. Repeat

To be honest, it was a real exercise in self control. I wanted to take shortcuts. I wanted to write some behavior while I was there, and write the tests afterwards. But I promised myself that I would stick through it and write all of my new code in this way.

The benefits were immediate and profound. My methods were smaller. My classes were cohesive. My design is more extensible. My code was more readable. My classes were not tightly coupled. My units were testable, and my tests ran fast. It was amazing how quickly the prophecies of TDD came true.

After a year of this practice, I can honestly state that my code has less bugs. Moreover, when a bug is found in my code, I am able to write a new test immediately (due to the heightened testability of the code) that exercises the bug. Fixes happen quickly and I have a great deal of confidence that my fix doesn't break something else. I certainly can't say that about my legacy non-TDD code.

It is funny. I often feel like a born-again evangelical when it comes to TDD. Like a wide-eyed Christian who is eager to spread "the good news" every time somebody has a personal problem, I am quick to suggest TDD whenever I hear somebody talk about a coding problem. I am not the first (nor the last) to liken TDD to religion. It is fitting:

"For Kent Beck so loved the developers, that he gave his most precious tool (TDD), that whosoever believeth in it should not write legacy code, but have everlasting code." -- Agile 3:16

All kidding aside, TDD has really changed my professional life. In the past year, I have met many colleagues who share my beliefs and there is a real community out there. I have become so passionate about the topic that I am even giving public talks on testing and TDD. Without TDD, I would probably be stuck on the plateau where I sat -- stagnant and stale. TDD was the kick in the ass I needed to grow as a developer.

Looking back, I couldn't be happier with my experience in Rob's class. He taught me what I was doing wrong, and helped me do it right. It takes someone who really KNOWS TDD to teach it to someone who doesn't. I would recommend this experience to any developer in a heartbeat.

Amen

Saturday, October 18, 2008

GUI Testing Resources



So, I just gave my GUI Testing in .NET talk for the first time. I think it went pretty well. If you have any feedback, please feel free to comment or email me. I'd love to hear how to make the talk better.

I am providing the demo code and the talk slides. I have a few more posts on GUI Testing .NET apps that I wrote over the past few weeks. Please feel free to read what I have to say!

Presentation Slides
Demo Code

Tuesday, October 14, 2008

Build Your Own Spy Utility



kick it on DotNetKicks.com
In support of my talk on Saturday, I wanted to publish another little bit of code that I have found extremely useful. There are a lot of spy utilities out there: Spy++, ManagedSpy, UISpy, etc. They all work OK, but I have found on many occasions that I wanted my spy utility to do X, Y or Z.

So, I built my own spy utility. Start with this form, and add any spy functionality that you need to it. Here is the code:
using System.Drawing;
using System.Windows.Forms;
namespace RecipeBox.Tests.GUI_Tests
{
public class Spy : Form
{
readonly SplitContainer _splitContainer = new SplitContainer {Dock = DockStyle.Fill};
readonly TreeView _controlTree = new TreeView {Dock = DockStyle.Fill};
readonly PropertyGrid _properties = new PropertyGrid {Dock = DockStyle.Fill};

public Spy()
{
Size = new Size(640, 480);

_splitContainer.Panel1.Controls.Add(_controlTree);
_splitContainer.Panel2.Controls.Add(_properties);
Controls.Add(_splitContainer);

_controlTree.NodeMouseClick += (sender, e) => _properties.SelectedObject = e.Node.Tag;
}

public Spy(Control rootControl) : this()
{
_controlTree.Nodes.Add(GetTreeNode(rootControl));
}

private static TreeNode GetTreeNode(Control control)
{
var node = new TreeNode(control + " (" + control.Name + ")") {Tag = control};

foreach (Control childControl in control.Controls)
node.Nodes.Add(GetTreeNode(childControl));

return node;
}
}
}
And here is how you might use the custom spy:
[Test, Explicit]
public void Spy_On_TestForm()
{
var testForm = new TestForm();
testForm.Show();

var spy = new Spy(testForm);
spy.Show();

while (true)
Application.DoEvents();
}
And this is what it looks like:


Getting Your NUnit Tests to Run as STA



As a follow-up to my recent post on my Winforms Automation Extensisons post, I realized that I forgot to mention a very important detail.

In many cases, WinForms require to be executed in a Single Threaded Apartment (STA). I write all of my tests in the TestDriven.NET test runner, which runs in the STA by default, but NUnit does not. Resharper also uses the NUnit test runner, so it also runs in MTA by default.

To tell NUnit to run in the STA (and therefore, Resharper), you need to add some data to your app.config file. If you do not already have one, create a file in your test assembly called app.config. Add the following XML:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="NUnit">
<section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
</sectionGroup>
</configSections>
<NUnit>
<TestRunner>
<add key="ApartmentState" value="STA" />
</TestRunner>
</NUnit>
</configuration>
Presto! Tests will run in the STA from now on.

Sunday, October 12, 2008

Winforms Automation Extensions



kick it on DotNetKicks.com
In preparation for my talk next Saturday, I am publishing the code that I use to help drive my WinForms application via NUnit tests. The idea is simple -- instantiate the form and use extension methods on the controls to find the controls and drive from there.

This is a preliminary release. I will update this file as I find more functionality s needed. It turns out that you don't need much (besides some creativity) to automate WinForms UIs. This set of extension methods will help you get started.

Download WAX -- Winforms Automation Extensions

To run your forms in NUnit, you just need create/show it in the setup and close it in the teardown:
[SetUp]
public void SetUp()
{
_testForm = new FormToTest();
_testForm.Show();
}

[TearDown]
public void TearDown()
{
_testForm.Close();
}


Here is an example of finding a button by name, clicking on it and validating that the app changed the text of the label:
[Test]
public void Test_That_Button_Click_Changes_Text()
{
var button = _testForm.FindByName<Button>("Button1");
var label = _testForm.FindByName<Label>("Label1");

button.SimulateClick();

Assert.That(label.Text, Is.EqualTo("Hello World"));
}
Note that the FindByName method is just a specialization of the Find method. The Find method takes a delegate you can use to find your controls using any method you wish. For instance, say you want to find a control with a known tag:
[Test]
public void Test_Find_With_Custom_Filter()
{
var l1 = _testForm.Find<Control>(target => (target.Tag as string) == "FindTag");

Assert.That(l1.Name, Is.EqualTo("ListBox1"));
}
In my experience, driving the controls directly is the easiest way to automate the UI. For instance, if you have a list control that you want to set, you might write code like this:
[Test]
public void Test_Setting_ListBox()
{
var listBox = _testForm.FindByName<ListBox>("ListBox1");
listBox.SelectedIndex = 1;

Assert.That(listBox.SelectedItem.ToString(), Is.EqualTo("The Test"));
}
If you have any questions or thoughts about this code, please contact me. I want to grow this code over time, and feedback is very welcome.

Monday, October 6, 2008

I'm speechless...



Are you going to PDC in a few weeks? Looking forward to the free hard drive with "all the bits?" Then THIS is for you...

Saturday, October 4, 2008

UI Automation Not Fit for Command!



kick it on DotNetKicks.com
I have been spending a lot of time exploring automation testing frameworks that can be driven using NUnit. I am exploring the following:
I am finding that the "Roll Your Own" method is the most versatile method. I will write about this method later. Today, I feel like a more negative tone. I will say it now:

Microsoft's UI Automation Framework is NOT fit for command.

Don't get me wrong... there are a lot of easy-to-use systems in .NET. BUT, I find the Code DOM easier to use than the UI Automation tools. If you have ever used the Code DOM, you know that I am saying a lot with this.

Here are my issues with the UI Automation Framework:
  • UI Spy Doesn't Ship with Visual Studio 2008. If you want UI Spy, you need to download the SDK for Windows Vista. Don't try to use this framework without it. You will fail.
  • The UI Spy tool is buggy and crashy and slow. Did I mention that this tool is essential?
  • As much as I research it, I can't figure out how to do the first two things I tried to do: Click on a LinkLabel and enter text into a RichTextBox. I know how to click on a button and enter text into a TextBox, but the more complicated versions of this are too difficult, aparently.
  • The API is terribly difficult to write AND read. Not intuitive at all!
  • Finding controls using the NameProperty doesn't use the "Name" property. It uses the "Text" property. If you want to search for a control using the "Name" property, you need to use AutomationIdProperty. Did I mention that the API is awful? This is why you need the UI Spy tool.
  • The framework itself is slow
  • You need a separate thread to catch modal dialogs. Have you ever tried to write tests that utilize multiple threads?
These are the problems I have run into with just a few hours of use. I need to mention that NUnit Forms, Ranorex and "Roll Your Own" tests were all easier to write/read/execute with the same level of effort.

Sorry, Microsoft. This framework has failed.