views:

100

answers:

2

Many of our system tests are written in a BDD style, and we make decent use of inherited behaviours to minimise duplication, for example this might be a basic hierarchy for purchase tests.

class BehavesLikeSuccessfulPurchase
class BehavesLikePurchaseWithValidCreditCard : BehavesLikeSuccessfulPurchase

In this case the BehavesLikeSuccessfulPurchase defines common behaviours like the account statement should have a debit entry, and the BehavesLikePurchaseWithValidCreditCard class defines the test workflow for purchasing any type of product with a valid credit card, so the tests are small derived classes that simply supply the concrete product instance, e.g.

[Concern(typeof(Video))]
class WhenPurchasedWithValidCreditCard : BehavesLikePurchaseWithValidCreditCard

However, depending on the concrete product type we also need to have some additional checks, for example whenever a video is successfully purchased we want to check that it is added to the user's video library. Ideally this could be defined by another class and mixed in, using the hypothetical syntax:

class BehavesLikeSuccessfulVideoPurchase

[Concern(typeof(Video))]
class WhenPurchasedWithValidCreditCard : BehavesLikePurchaseWithValidCreditCard
    mixin BehavesLikeSuccessfulVideoPurchase
{
}

But of course C# doesn't support multiple inheritance or mixins so we end up writing a load of boiler-plate methods that forward calls to the additional behaviours, which needs to change every time that behaviour changes.

What we really need is a framework that has its own mechanism for supporting multiple behaviours from tests simply by supplying the type(s) of additional behaviours that should be observed. I've been looking at xUnit and the specification examples, and it looks like it would be possible to come up with some extensions to it that could do the trick, but is there anything already in existence?

A: 

Using Linfu you can do Mixins: http://www.codeproject.com/KB/cs/LinFuPart2.aspx

What I'm not sure about though, is if the BDD framework will play nicely with LinFu dynamic objects.

I haven't had a chance to use LinFu's Mixins myself, so would be interested in hearing how easy/complex they are when used in a moderately complex scenario and if there's any major drawbacks.

MVC-dot-net
+3  A: 

The Machine.Specifications project has this idea, where you can specify a class with the Behaviours attribute, and then in another class, specify

Behaves_like<SomePredefinedBehaviour> some_predefined_behaviour;

more than once in the specification, allowing you to inherit behaviour from as many classes as you like. The style takes a while to get used to when coming from a traditional unit testing background, but it does support the behaviour. If you download the project and look at the examples, you'll see one with behaviours.

Deeksy