XUnit.Net

Showing the 馃挄 for xunit.net and dotCover in Teamcity

Showing the 馃挄 for xunit.net and dotCover in Teamcity

I've been using teamcity as my CI server for about 6 or 7 years now. I've also been using xunit.net since it first appeared on codeplex.

I was also a long time user of nCover on teamcity for my code coverage. Following their change in direction after v3 which I didn't like, I sacrificed the trend functionality and switched to using dotCover around five years ago. I still miss trends though.. hint hint jetbrains!

Atrophy

However in all that time as xUnit.net usage has blossomed, Teamcity's native support for it in combination with dotCover has been non-existent, instead using nUnit only for shrink-wrapped integration. I'm sure there must be a pretty sizable user-base for native xunit functionality so it mystifies me why tickets like this are still not a priority for development.

There has been a meta-runner for xunit around for a while and a recent plugin competition produced an xunit plugin entry and there are a bunch of posts on the web offering dotnet executable runner solutions to setup xunit. All of these though have some limitations or do not include dotCover.

Ok so what now?

It's time to show some more 💕 to this super handy tooling m茅nage 脿 trois.
I wanted to tame a few of those limitations from the implementations out in the wild, so here's the highlights:

  • Support for local or remote nuget package feeds for those corporate-proxy worlds
  • Easy support for testing .net legacy activation libraries
  • Decent wildcard support for finding test libraries
  • Traits ...are just awesome, if you don't use them, you should start!
  • Test runner extensibility for all those edge-case scenarios when you need to pass an arg to the test runner
  • Full-fat filtering support

The future...

With new and awesome test runners like fixie I expect with a bit more work this meta-runner could be made runner agnostic but for now, this does everything I need.

Let me know how you get on and if you find any bugs/issues with it post them via the github gist.

Why no plugin?

Of course this would no doubt be cleaner as a plugin and I did consider trying to write one to enter the plugin competition, but I'm not a java native so I didn't :(

Update

The good folks Jetbrains have now merged this runner into the powerpack. You can get it here

Creating custom DataAnnotation tests

Recently I wanted to create some unit tests for the DataAnnotations on my domain model. After a bit of googling I found the following article on testing validation attributes which gave me a good start.

[Fact]
public void NameHasRequiredAttributeWithErrorMessage()  
{
  var type = typeof(Country);
  var methodinfo = type.GetProperty("Name");

  Assert.True(Attribute.IsDefined(methodinfo, typeof(RequiredAttribute)));
}

It works like a charm but after a few tests I got fed up violating DRY and I don鈥檛 like the magic string used for the property name, it鈥檚 not refactor friendly. so I created a method to refactor the tests down to one line.

[Fact]
public void NameHasRequiredAttribute()  
{
AssertDataAnnotation<Country>.ContainsAttribute<RequiredAttribute, string>(x => x.Name);  
}
public class AssertDataAnnotation<TType> : Assert where TType : class  
{
  public static void ContainsAttribute<TValidationAttribute, TProp>
(Expression<Func>TType, TProp>> expression)
where TValidationAttribute : ValidationAttribute  
  {
    var memberExpression = expression.Body as MemberExpression;
    if (memberExpression == null)
      throw new MissingMemberException("Property is invalid");

    var member = memberExpression.Member;
    if (member.MemberType != MemberTypes.Property)
      throw new MissingMemberException(member.DeclaringType.Name, member.Name);

    True(Attribute.IsDefined(member, typeof(TValidationAttribute)));
  }
}

It could still use some improvements though in the form of type inference to let the compiler work out the property type rather than having to pass it in but I haven鈥檛 figured that out yet. Overall it鈥檚 pretty useful though.

I鈥檒l look at extending the AssertDataAnnotation class above to validate ErrorMessages and perhaps how to test properties of the ValidationAttribute types passed in next I think.