Fragmented integration tests – aka the questionable value zone

Fragmented integration tests – aka the questionable value zone

In TDD, different styles of tests can be applied to cover different levels in your code base. Two or three years ago, if you asked me what they were, I would probably have listed them as:

  • Highest granularity – unit tests, quick to run, drive low-level class design
  • Fragmented – integration tests, testing higher-level components and external dependencies (e.g. real SQL database, fake message bus)
  • Whole system at once – slow end-to-end tests, testing for story/feature acceptance at the UI or client API level

However, it has become increasingly clear that fragmented integration tests (somewhere in the middle between unit and full-blown end-to-end integration tests) don’t really provide the same value as their brothers.

They suffer all the disadvantages of both unit and end-to-end tests:

  • Like unit tests, they require setting up mocks/test doubles for collaborating modules
  • Like end-to-end tests, they have a high cost of maintaining external components like databases and integrated third party systems (setting them up, populating them with the right test data, reverting changes for next time etc)
  • Like unit tests, they are brittle and not friendly to refactoring
  • Like end-to-end tests, they are slow to run

… and, over the lifetime of the code base, the only real benefit they provide is slightly faster feedback of problems than end-to-end tests. Is it really worth keeping them?

NHibernate session management and WCF, redux

NHibernate session management and WCF, redux

It’s been nearly a year since I published my method for getting one NHibernate session per WCF operation using Castle’s NHibernate Facility and AutoTx AOP Facility — a method I developed for an application which was having serious session management issues (it was using one session per SQL statement). However, today I ripped it all out.

The method itself still works. There’s nothing wrong with it. As long as you’re only doing one session per WCF operation (or one session per ASP.NET MVC request for that matter), it works great. However, problems arise when you mix other session styles.

For example, our application has a series of long-running background threads for processing jobs on a queue (up to an hour each) — as well as synchronous WCF operations — all requiring NHibernate. In this case, the one-size-fits-all approach using AOP and the container simply couldn’t give us the control we needed over each session’s lifetime, so we removed the Facility from our Windsor container, and instead now do:

  • Register the ISessionFactory in the container, singleton scoped.
  • Inject ISessionFactory and call ISessionFactory.OpenSession(), ISession.BeginTransaction() and ITransaction.Commit() at outer boundaries of your application (e.g. WCF service implementations), and background jobs executing outside the context of a WCF operation.
  • Pass ISession down through your application as a parameter into any methods that access the database. Callees must not hold any reference to it, or try to manage its lifestyle (e.g. closing it, opening their own transactions etc).

(Note: all NHibernate calls are wrapped in a transaction and committed. Even if they are only SELECT statements, it’s still a good practice.)

It has more-or-less the same end effect as AutoTx facility and CallContext-scoped SessionManager, but with the added control of being able to explicitly manage session lifetimes in other situations. It’s a few more lines of code, but it’s also a good example of stop trying to hide your ORM, and just embrace the ISession directly. And a reminder that technical solutions are never infallible, no matter how elegant they might seem.

The Fat ViewModel

If someone asked you, what are the building blocks of MVVM, what would you say? Models, Views, and ViewModels, of course. It’s in the name. But really, there are two others:

  • Models
  • Views
  • ViewModels
  • Commands
  • Events

If Commands and Events aren’t strongly represented in your application, I’d say there is a strong chance it isn’t factored very well.

One problem I see quite often is the Fat ViewModel: a long, bloated class that violates SRP by presenting complex application Commands to the view, and implementing them too.

Symptoms

You can tell you have a Fat ViewModel if any of the following are true:

  • Instead of having a separate class for each Command, your ViewModel uses DelegateCommands (aka RelayCommands) to invoke methods on itself.
  • Your ViewModel has three properties, two commands, and is 300 lines long.
  • Your ViewModel has a large number of services injected into it.
  • Your ViewModel tests include assertions for both presentation and application behaviour.
  • Testing simple UI behaviour — e.g. a button should be disabled after it has been clicked — requires excessive mocking of dependencies.
  • Your ViewModel tests frequently call xyzCommand.Execute().
  • Commands cannot easily be re-used by other ViewModels. Your application is not modular.
  • ViewModels update their state directly, instead of listening for global application Events.

Instead, if you extract Commands into separate classes, that publish their results via Events, you will benefit by having:

  • Skinny and light ViewModels.
  • Commands that can be developed and tested in isolation.
  • Commands that encapsulate and mask complex logic.
  • Separation of presentation logic (ViewModels) from application logic (Commands).
  • A catalog of clearly defined and reusable Commands that be composed into new ViewModels.

Whither DelegateCommand?

From the cases I have seen, I have no doubt that DelegateCommands are the primary cause of Fat ViewModels — they encourage developers to implement Commands using local ViewModel methods, which results in poorly-factored code. For this reason, I consider DelegateCommands to be in the same bad code smell category as ServiceLocator: as an anti-pattern, with few legitimate uses. (One is when the Command is entirely self-contained within the ViewModel (i.e. does not collaborate with any other object), the other when genuinely delegating to another object. But in that case, the other object should probably be a Command anyway.)

IIS vs a Windows Service: some important considerations

Can’t decide whether to host your WCF service in IIS or a Windows Service? Consider the additional steps you’ll need to perform, explain, troubleshoot, and write documentation for if you follow the IIS route:

  • Ensure IIS is installed.
  • Run aspnet_regiis -i to install .NET ISAPI module.
  • Run ServiceModelReg –i to install handlers for *.svc file types.
  • Creating, starting a new App Pool running as a domain account.
  • Set your Application to use the new App Pool instead of DefaultAppPool.

Plus, EITHER: (II6/Server 2003)

  • Ensure the .NET 2.0 Web Service Extension is enabled.
  • Add the domain account to local IIS_WPG group.
  • (If required) cscript.exe adsutil.vbs set W3SVC/AppPools/Enable32BitAppOnWin64 “true”

OR: (IIS7/Server 2008)

  • Ensure IIS6 Compatibility components are installed so *.vdproj installers can run.
  • Add the domain account to local IIS_IUSRS group.
  • (If required) set Enable 32-Bit Applications = true

If you are working in an environment like ours with developers in London, servers in Germany, and the ops team in India, where getting server access is harder than getting an appointment with the pope, I’d recommend sticking with Windows Services unless you really need IIS.

How to lose customers through bad UX

I just got a strange validation bug, trying to buy something on eBay UK:

After about eight attempts (trying different browsers, local/international phone number prefixes etc), I emailed them to report it, and find out maybe if I am doing something wrong. Here is their response:

Hello Richard. My name is Elma from PayPal customer service.

I reviewed your account carefully to check why you are unable to use your card and saw that you were trying to pay a £555.00 GBP transaction with your credit card. It appears that this particular payment cannot be funded by a credit card because of our security model.

I would like to assure you that there is nothing wrong with your credit card or your PayPal account. As part of our commitment to protect you and all our customers, we review all transactions that go through us. This payment got declined because we detected that it might not be safe for you to use your credit card for this transaction. Don’t worry. I assure you that it’s just for this particular transaction. You can still use your credit card for your future transactions.

This is amazing. PayPal are reporting a permanent, this-form-will-never-work-so-don’t-bother-filling-it-out problem to users as an input validation error. And how do users react to validation errors? They double check their details and type them in again. And again. And again, until they’ve gone slightly mad, spending hours scrutinizing every pixel in every digit in their credit card and telephone number for mistakes.

In the end, it wasn’t until I contacted PayPal directly (hint: their feedback form is not exactly easy to find) that I was told my credit card would never work for this particular purchase, and the whole thing was a waste of time. (I wonder how many customers they lost who didn’t bother to fill out a bug report?)

If you are writing software like this, you have BIG problems.

Reactive Extensions and Prism: LINQ to your Event Aggregator

A lot of people have been talking about the Reactive Extensions for .NET, a flash new library from Devlabs which lets you do LINQ to .NET events just like you can with collections. My team at work has started using it pretty heavily, and today I wrote an adapter that allows you to use Rx over events published on the event aggregator in a Prism/Composite WPF application.

Here’s an example of using it in an imaginary chat client, to filter incoming messages from a particular person:

public class ConversationViewModel : IDisposable{    public IContact Friend { get; private set; }    public ObservableCollection<IMessage> Messages { get; private set; }    public ConversationViewModel(IContact friend,         IEventAggregator eventAggregator)    {        // Interested only in messages sent by the person we are talking to.        var messageReceivedEvents = eventAggregator            .GetEvent<MessageReceived>()            .AsObservable()            .Where(msg => msg.Sender.Equals(Friend));        eventSubscription = messageReceivedEvents.Connect();        messageReceivedEvents.Subscribe(msg => Messages.Add(msg));    }        // We will keep receiving messages until the subscription is disposed.    IDisposable eventSubscription;}

It was a good exercise that helped me understand a bit more about how Rx works, and illustrates how easy it is to integrate with callback-based event systems (e.g. your favourite message bus).

You can grab the code here: CompositePresentationEventExtensions.cs

Update Jun 16 2010: Added finalizer to CompositePresentationEventSubscription.

Update Feb 9 2012: Fixed bug found by Ariel Ben Horesh where keepSubscriberReferenceAlive needed to be true.

One NHibernate session per WCF operation, the easy way

This week I’ve been working on a brownfield Castle-powered WCF service that was creating a separate NHibernate session on every call to a repository object.

Abusing NHibernate like this was playing all sorts of hell for our app (e.g. TransientObjectExceptions), and prevented us from using transactions that matched with a logical unit of work, so I set about refactoring it.

Goals

  • One session per WCF operation
  • One transaction per WCF operation
  • Direct access to ISession in my services
  • Rely on Castle facilities as much as possible
  • No hand-rolled code to plug everything together

There are a plethora of blog posts out there to tackle this problem, but most of them require lots of hand-rolled code. Here are a couple of good ones — they both create a custom WCF context extension to hold the NHibernate session, and initialize/dispose it via WCF behaviours:

  • NHibernate Session Per Request Using Castles WcfFacility
  • NHibernate’s ISession, scoped for a single WCF-call

These work well, but actually, there is a much simpler way that only requires the NHibernate and WCF Integration facilities.

Option one: manual Session.BeginTransaction() / Commit()

The easiest way to do this is to register NHibernate’s ISession in the container, with a per WCF operation lifestyle:

windsor.AddFacility<WcfFacility>();
windsor.AddFacility("nhibernate"new NHibernateFacility(...));
windsor.Register(
    Component.For<ISession>().LifeStyle.PerWcfOperation()
        .UsingFactoryMethod(x => windsor.Resolve<ISessionManager>().OpenSession()),
    Component.For<MyWcfService>().LifeStyle.PerWcfOperation()));

If you want a transaction, you have to manually open and commit it. (You don’t need to worry about anything else because NHibernate’s ITransaction rolls back automatically on dispose):

[ServiceBehavior]
public class MyWcfService : IMyWcfService
{
    readonly ISession session;
    public MyWcfService(ISession session)
    {
        this.session = session;
    }
    public void DoSomething()
    {
        using (var tx = session.BeginTransaction())
        {
            // do stuff
            session.Save(...);
            tx.Commit();
        }
    }
}

(Note of course we are using WindsorServiceHostFactory so Castle acts as a factory for our WCF services. And disclaimer: I am not advocating putting data access and persistence directly in your WCF services here; in reality ISession would more likely be injected into query objects and repositories each with a per WCF operation lifestyle (you can use this to check for lifestyle conflicts). It is just an example for this post.)

Anyway, that’s pretty good, and allows a great deal of control. But developers must remember to use a transaction, or remember to flush the session, or else changes won’t be saved to the database. How about some help from Castle here?

Option two: automatic [Transaction] wrapper

Castle’s Automatic Transaction Facility allows you to decorate methods as [Transaction] and it will automatically wrap a transaction around it. IoC registration becomes simpler:

windsor.AddFacility<WcfFacility>();
windsor.AddFacility("nhibernate"new NHibernateFacility(...));
windsor.AddFacility<TransactionFacility>();
windsor.Register(
    Component.For<MyWcfService>().LifeStyle.PerWcfOperation()));

And using it:

[ServiceBehavior, Transactional]
public class MyWcfService : IMyWcfService
{
    readonly ISessionManager sessionManager;
    public MyWcfService(ISessionManager sessionManager)
    {
        this.sessionManager = sessionManager;
    }
    [Transaction]
    public virtual void DoSomething()
    {
        // do stuff
        sessionManager.OpenSession.Save(...);
    }
}

What are we doing here?

  • We decorate methods with [Transaction] (remember to make them virtual!) instead of manually opening/closing transactions. I put this attribute on the service method itself, but you could put it anywhere — for example on a CQRS command handler, or domain event handler etc. Of course this requires that the class with the [Transactional] attribute is instantiated via Windsor so it can proxy it.
  • Nothing in the NHibernateFacility needs to be registered per WCF operation lifestyle. I believe this is because NHibernateFacility uses the CallContextSessionStore by default, which in a WCF service happens to be scoped to the duration of a WCF operation.
  • Callers must not dispose the session — that will be done by castle after the transaction is commited. To discourage this I am using it as a method chain — sessionManager.OpenSession().Save() etc.
  • Inject ISessionManager, not ISession. The reason for this is related to transactions: NHibernateFacility must construct the session after the transaction is opened, otherwise it won’t know to enlist it. (NHibernateFacility knows about ITransactionManger, but ITransactionManager doesn’t know about NHibernateFacility). If your service depends on ISession, Castle will construct the session when MyWcfService and its dependencies are resolved (time of object creation) before the transaction has started (time of method dispatch). Using ISessionManager allows you to lazily construct the session after the transaction is opened.
  • In fact, for this reason, ISession is not registered in the container at all — it is only accessible via ISessionManager (which is automatically registered by the NHibernate Integration Facility).

This gives us an NHibernate session per WCF operation, with automatic transaction support, without the need for any additional code.

Update: there is one situation where this doesn’t work — if your WCF service returns a stream that invokes NHibernate, or otherwise causes NHibernate to load after the end of the method, this doesn’t work. A workaround for these methods is simply to omit the [Transaction] attribute (hopefully you’re following CQS and not writing the DB in your query!).

Powershell to recursively strip C# regions from files

Here’s a super quick little powershell snippet to strip regions out of all C# files in a directory tree. Useful for legacy code where people hide long blocks in regions rather than encapsulate it into smaller methods/objects.

dir -recurse -filter *.cs $src | foreach ($_) {    $file = $_.fullname    echo $file    (get-content $file) | where {$_ -notmatch "^.*#(end)?region.*$" } | out-file $file}

Run this in your solution folder and support the movement against C# regions!

Watch out for weaselly recruitment agents

wea·sel·ly (adj.)
Resembling or suggestive of a weasel.

Yesterday, Parcelforce called me at work to say they tried to deliver a package for me the day before, but couldn’t because I wasn’t around to sign for it.

I wasn’t expecting anything, but I like getting parcels, and thought maybe it was some long-forgotten internet purchase finally shipped. They wanted to arrange redelivery that afternoon, and asked for a couple of names of people who could sign for it just in case I was out (it was around 11am and I knew I would be stepping out briefly for lunch).

But twenty four hours later nothing has arrived. I think it was actually a recruitment agent, and the colleauges I gave as co-signatures will be getting some annoying calls soon 🙁

Exception handling no-nos

Just spotted this in a project I’m working on:

public static string GetExceptionAsString(this Exception exception){        return string.Format("Exception message: {0}. " + Environment.NewLine +                "StackTrace: {1}. {2}", exception.Message, exception.StackTrace,                GetAnyInnerExceptionsAsString(exception));}

Writing code like this should be a shooting offense.

But wait, there’s more! Check out its usage:

try{        ...}catch (Exception ex){        log.InfoFormat("Error occured:{0}.", ex.GetExceptionAsString());}

Agh!

Code like this demonstrates a complete misunderstanding of CLR exception basics — inner exceptions and formatting — and also log4net. All that hand-rolled formatting could simply be replaced with:

  • GetExceptionAsString() -> Exception.ToString()
  • ILog.InfoFormat(format, args) -> ILog.Info(message, exception)