# Saturday, January 24, 2009

Update: Resharper 4.5 beta is out, and it natively supports MsTest.

Update: I updated this plugin to work with ReSharper 4.5

Chances are, if you have ReSharper you're using the built in ReSharper test runner. The Resharper test runner is pretty frictionless assuming you're using one of the open source testing frameworks like NUnit.

If you're stuck using MSTest for some reason, like in my unfortunate case my company has standardized on it... then you're pretty much stuck using the MSTest runner, which really sucks for numerous reasons.

The MSTest runner likes to muck around with vsdmi and testconfig files (or something like that, I can't remember) and is pretty slow. Up until VS 2008 it was almost completely useless for TDD.

Its almost usable in VS 2008, but I still hate the test failure reports. I can't just scan a bunch of grouped tests to see which one's failed and why. To really see why, I have to open a new test report tab in VS. Even more annoyingly, MSTest refuses to find my resource satellite assemblies without additional hoop jumping. I like to call that friction.

After finally having enough of this I decided to create my own MSTest ReSharper 4 plugin (Apache 2.0 license). It was actually quite easy to hook into the ReSharper test infrastructure, especially since JetBrains gives you most of the code to do it in the form of a csUnit plugin. A few deletes and edits later, and I have a functional MSTest plugin.

image

Not only does it work, it works better. My satellite assemblies are found right out of the gate, reports are inline with the runner, and for a moment I almost lapse back into mistakingly typing NUnit attributes.

image

Now mind you, its not perfect, but it works really well for my needs. Some gotchas, or differences between the standard MSTest runner and my plugin:

  • TestContext is always null, the runner doesn't provide that. Unit tests shouldn't need it anyway.
  • AssemblyInitialize is not honored, much like like TestDriven.NET. I get around this using a static initializer in my base class test fixture (I need this for some slow integration tests if you're wondering).
  • MSTest seems to create a new test fixture instance between each test run, this plugin only creates a single instance of the fixture. Generally this shouldn't be a problem if your TestInitialize method is written correctly.

Binaries and source are available on my Google Code web site. To install, just drop the DLL into the ReSharper bin\plugins folder and restart VS 2008. Happy testing!

Saturday, January 24, 2009 2:29:37 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [5]  | 
# Tuesday, January 13, 2009
Because I keep forgetting, and writing is supposed to help you remember things...

./etc$ sudo gedit environment

Tuesday, January 13, 2009 2:16:19 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Monday, December 22, 2008

I've been playing around with Grails on my Ubuntu box for the past week and really like the ability to do fast web development while still retaining all the power that the JVM provides.  Unfortunately, it also comes with the baggage of Java, which became pretty apparent once I needed to map a date time object.

Since I still have a day job, and I don't see us switching from .NET anytime soon, I thought I would spend a little time with ASP.NET MVC and IronPython to see where things are. I was able to find a sample MVC sample application on CodePlex which made use of IronPython in the views and the global.asax. The one feature I really wanted support for was writing controllers in python, apparently that's in the works but not currently supported.  Not much python in the sample, but pretty neat to know it works.

... Well actually at some point it probably did.  I'm using the first beta release of ASP.NET and some things have changed since the IronPython sample came out.  Needless to say, the sample no longer works, I get an HttpParseException with the message "HtmlHelper' object has no attribute 'ActionLink'"

Pretty strange message huh?  In C# I can find this method no problem. Long story short, IronPython can't use extension methods like C# can.

At some point the MVC team moved the HtmlHelper.ActionLink method from System.Web.Mvc to Microsoft.Web.Mvc.  The latter is the ASP.NET futures assembly, which provides a bunch of extension methods that they may add to the System DLL at a later date.

Monday, December 22, 2008 7:34:35 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, December 15, 2008

Today I start platform rehab, and this time I'm serious about getting clean. I'm writing this blog post from my laptop, yes my laptop, running Ubuntu 8.10. You don't get serious about dumping Windows until you take the plunge of installing Linux on your laptop. If you're like me, your laptop is your primary development box.

To my surprise, even my el-cheap-o laptop was absolutely painless to install Linux on. I suspect that maybe, just maybe, that even my 65 year old mom could do it. Even the wireless works connecting to the commuter trains free wifi. The only slightly difficult part was setting up my development environment, and that was mostly because I'm not super familiar with the OS or tooling, all of which are my problems.

Why did I switch? To people who use Linux already this is a rhetorical question, but for me the reason was pretty simple: Linux is free and good. I generally don't play games anymore, especially on my laptop. I don't really use MS Office too much, and Open Office is more than OK for my needs. Firefox is just as good on Linux as Windows.

More importantly though, Linux is the gateway to the backbone of the Internet. You don't build a web company on a proprietary per license platform when you have equivalent or better alternatives for free; after all Microsoft is dead. This speaks directly to competitive advantage and more importantly to a company's bottom line. I'm cheap. Startups, if their going to be successful, should be cheap.

Now back to GRails for me.

Monday, December 15, 2008 4:46:26 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
# Tuesday, December 09, 2008

First of all let me say that I love IoC containers.  I love them not because they are trendy, or that they help testability, or that they allow me to use AOP. No, the real reason I love IoC containers is because they let me be lazy.

When I'm designing a class I don't need to worry about how I get can get a dependency.  The container allows me to worry about that later, by separating construction from logic.  Think about that for a second. Every time we use the new keyword we're explicitly creating a dependency between implementations.  Sometimes this isn't a big deal, but if we have a dependency that itself has 10 other dependencies this can get out of hand real quick.

Containers are smart, they know which implementations fulfill which contracts.  Somewhere on application startup we just tell the container what contracts and what implementations we have and it figures out the dependencies for us. If we have a FooService that requires an IBarRepository implementation, the container will automatically new up a class that implements IBarRepository and give it to FooService on creation.

Things get a bit less academic and a bit more troublesome when we try to implement a container with ASP.NET.  Normally we would want the container to new up our page instance and provide any dependencies it my have, but with ASP.NET we don't get the chance to have the container create the page instances with all of its required dependencies.  We could create our own page handler factory to do this, but that's a lot of work to do right.

Sprint.NET has its own page handler factory which works very well, but the last I checked, Spring.NET configuration is very verbose and requires that each page that needs the container to construct it be registered with the container. It works, but I prefer convention over configuration.

My favorite .NET container is Windsor because it allows me to do more with less work (configuration), but unfortunately there's no built in way to use Windsor in a truly IoC way with ASP.NET.  The only supported way is to get a reference to the container and ask the container to resolve an instance of something, which directly makes your page dependant upon the container, and generally just adds noise where its not needed; you would see calls like this all over:

IFooService service = Container.Resolve<IFooService>();

Rather than explicitly asking the container for a service instance, I would much rather have the container inject any required dependencies into my page instance when it gets constructed.  The problem is how do we do this with Windsor?

Windsor AspNetModule

The approach I've taken is to create an http module that will inject dependencies into a page just after instantiation using setter injection.  This means that the container will inject any dependencies that my page may have using public property setters.  Constructor injection would be better, but IMO its not worth the effort of having to create my own page handler factory, here we can rely on the tried and true ASP.NET infrastructure.  Perhaps someday I'll change my mind, but for now this is acceptable.

Since I plan on using this container with a large amount of legacy code that doesn't use dependency injection I want to make the use of the container somewhat explicit.  I don't want to waste cycles scanning over a page that doesn't need any dependencies injected.  To enforce this, I make the pages that require injection declare so using a class level attribute.  Here's a succinct example with one dependency:

[UsesInjection]
public partial class CustomerDetail : Page
{
    public ICustomerRepository CustomerRepository { get; set; }

    protected void Page_Load(object sender, EventArgs e)
    {
        customerGrid.DataSource = CustomerRepository.GetAll();
        customerGrid.DataBind();
    }
}

When the module sees the current handler with the UsesInjection attribute it scans the class for public setter properties and tries to resolve any dependencies by type. If an instance is registered with that type in the container, the module tries to set the property. Here an ICustomerRepository instance gets injected. All of this happens before the page lifecycle begins, so its safe to use these dependencies on page init or page load.

If more explicit control is required, we can change the module's behavior by changing the class level UsesInjection attribute.

[UsesInjection(For.ExplicitProperties)]
public partial class CustomerDetail : Page
{
    private ICustomerRepository customerRepository;

    [RequiredDependency]
    public ICustomerRepository CustomerRepository
    {
        get { return customerRepository; }
        set { customerRepository = value; }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        customerGrid.DataSource = CustomerRepository.GetAll();
        customerGrid.DataBind();
    }
}

The For.ExplicitProperties does two things:

  1. Optimizes the scanning process to only consider explicitly tagged properties (the default behavior considers all public settable properties).
  2. An exception will be thrown if a dependency couldn't be found in the container to inject. This makes is pretty evident if you forget to register a dependency with the container.

With the page level code in place we then need to setup our container and register our components. This is easily accomplished by implementing Castle.Windsor.IContainerAccessor in our global.asax and creating a static container with the registered components our web application needs to run.  Here we register to use an in memory customer repository implementation.

public class Global : System.Web.HttpApplication, IContainerAccessor
{
    private readonly IWindsorContainer container = new WindsorContainer();

    public Global()
    {
        container.Register(
            Component.For<ICustomerRepository>()
                .ImplementedBy<InMemoryCustomerRepository>());
    }

    public IWindsorContainer Container
    {
        get { return container; }
    }
}

We do this in the global.asax because we share the container between all requests, and thus only want one instance of it. Also, the IContainerAcessor is used as a service locator which is required by the AspNetWindsor http module to find your container instance which it will use to resolve dependencies.

The very last thing we need to do is register the AspNetWindsor http module in our web.config, just like any other module.

<add name="WindsorModule" type="Sneal.AspNetWindsorIntegration.AspNetDependencyBuilderModule, Sneal.AspNetWindsorIntegration"/>

From here on out, all ASP.NET requests get intercepted by this module and "enriched" by the container as long as they are tagged with the UsesInjection page level attribute.

The code is available under the Apache 2 license in my SVN repository here on Google Code.  A compiled binary is also available for download.

.NET | IoC
Tuesday, December 09, 2008 7:26:26 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, November 28, 2008

My friend Ray and I were talking about the growing mobile development market the other day, which got me looking into mobile development again, but this time for fully featured (and connected) phones.

For sure the biggest player at this point is the iPhone, which has even surpassed sales of the once popular and much cheaper Razor.  Now if I only had a Mac Book Pro and an iPhone...  At least 2grand to get started developing.  Then there's the fact that I would have to learn Objective-C along with Apple's proprietary runtime library. 

I did learn a little Objective-C last night "From C++ to Objective-C", which compares C++ and Objective-C syntax, and then installed the Objective-C  NeXTStep libraries and compiler for gcc. 

What a pain, the Objective-C syntax is so foreign to me, but there's a lot of features I do like about the language, especially compared to C++.  The shortened header declarations, single inheritance, interfaces (protocols), reflection, garbage collection, and message based calling.  There's definitely a lot of dynamic runtime flexibility here for something that is a superset of C.

On the other hand I've been looking at Android development... which looks to be so much easier, at least for me.  You can develop on Windows or Linux using Java and Eclipse.  Wait, I've already done this!  I've already created a J2ME app for my Razor and my Palm.  The barrier for entry, at least from my point of view is much lower.

Now, does that mean iPhone development is worse?  No, its probably more lucrative, especially at this point.  The one remaining question I have, is Android or iPhone development in demand in the Seattle market where I live?

Friday, November 28, 2008 5:04:25 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Sunday, November 23, 2008

I was going to do some quick coding this morning on a project.  Haha...  2 hours later I still haven't started to write any code.  Why?  Visual Studio 2008 updates which I needed to be able to open the solution and be productive.

  1. Installed the TFS client, which took a while.
  2. Installed VS 2008 SP1.
  3. I had to reinstall VS 2008 checking the "Unit Testing Tools" checkbox (see image).
  4. Upgraded ReSharper 4.0 to 4.1
  5. Installed the VS 2008 SP1 hotfix (KB958502) to add JScript intellisense support from "-vsdoc.js" files.

Number 3 was a bit strange.  I opened the solution only to find VS complaining about an unsupported project type.  I guess when I initially installed VS 2008 I figured I would never be using MSTest.  If only that were still true.

image

I installed KB958502 to get intellisense specifically for JQuery, since there is now a -vsdoc.js file available on the JQuery site.

You know, it seems like VS 2008 isn't all that far behind VS 2005 in regards to the number of installation steps/packages required to get a usable environment (at least for this project).

Sunday, November 23, 2008 7:58:20 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
# Tuesday, November 11, 2008

The other day I asked a coworker whether one our proprietary GUI based tools had a command line interface, to which he replied no.  I said that's cool, we don't really need one to run the tool headless from the command line anyway.  Command lines are antiquated.

Before the days of Windows command shells were the only way to run applications.  Command lines allow us to pipe input and output, batch programs, and otherwise automate repetitive tasks.  In *nix-land they are especially sharp tools.  However they are not without their own problems, foremost in my mind is argument processing.  Using a command line version of an application can be a pain, especially for any non-trivial app. 

If you look at any serious application that allows automation, they have their own automation framework.  Office allows you to write VBA, .NET, and also exposes a COM automation interface.  Maya has its own scripting language (Mel script, guess what Mel stand for) embedded in it along with the ability to run C++ plugins.  Now I bet you're thinking, yes big applications use automation frameworks and scripting languages, but I don't have that kind of time to invest in my little app.  Good, me neither.

In recent years Microsoft has provided less heavy handed approaches to consuming .NET assemblies. There are a couple different approaches that I can think of to use our .NET objects from the command line without writing a console application: Windows PowerShell and the DLR. 

PowerShell is more geared towads sysadmins, as such I like to use the DLR, more specifically IronPython.  Python is a very easy language to pickup, widespread (at least in the *nix world), and powerful.  I like to think of IronPython as C# without all the typing (OK, I stole that from Boo, but remember Boo syntax is based on Python).  Both have one important ability which we will need, the ability to use .NET assemblies and types from the command line (or script).

As an example I have a .NET library assembly that will run JSUnit tests, however I now need a way to run these unattended from the command line as part of a BVT.  Instead of writing a command line app for it I decide to write a quick little IronPython script which behaves very much like a console application.

import clr
import sys

clr.AddReferenceToFile("Sneal.JsUnitUtils.dll")
from Sneal.JsUnitUtils import *
from Sneal.JsUnitUtils.Browsers import *
from System.Collections.Generic import List
from System.IO import Path

# usage
if sys.argv.Count < 3:
	print "Usage: ipy IPJsUnit.py c:\source\mywebroot jsunittest1.html jsunittest2.html"
	sys.exit(False)

# command line params
webRootDirectory = sys.argv[1]

testFiles = List[str]()
for arg in sys.argv[2:]:
	testFiles.Add(Path.Combine(webRootDirectory, arg))

# create an execute test runner
mgr = JsUnitTestRunnerFactory()
runner = mgr.CreateRunner(testFiles, webRootDirectory, With.InternetExplorer)
success = runner.RunAllTests()

# print all results
if not success:
	print "Test run failed."
	for error in runner.Errors:
		print error.TestPage
		print error.FunctionName
		print error.Timing
		print error.Message
else:
	print "Yay!  All tests passed."

You'll notice that the application in fact takes two+ command line parameters, the webroot and the test files.  The advantage of this script over a console application from my point of view is:

  1. Less code to write.
  2. Documentation by example.
  3. Starting script for an end user to modify to their needs.

Number 3 I think is particularly important.  Within a minute or two an end user can modify this script to their needs and desires.  They could hardcode the arguments if they wanted, or pass additional arguments without the headache of launching Visual Studio and recompiling a console application.  Almost anyone with a text editor could modify this and quickly get on with their life.

Here instead of a well meaning (but over-complicated) console application, its been replaced with just enough glue to bootstrap us into business.  Gluing components together is what scripting languages are good at, so lets take them into consideration instead of always reaching for another console app.

Tuesday, November 11, 2008 2:20:47 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [4]  |