TeamCity + XUnit: Not all tests executed

Running unit test on a TeamCity is usually not a big problem but a couple of days ago I noticed I very strange behaviour.

The number of tests executed on the build server was much smaller than the number of tests running on my local machine but TeamCity did not report any errors. After digging into the build log, I noticed this exception in the log files:
System.Runtime.Serialization.SerializationException: Unable to find assembly 'FakeItEasy, Version=, Culture=neutral, PublicKeyToken=eff28e2146d5fd2c'.

The only noticeable difference between the execution on TeamCity and my local machine was that locally I used the ReSharper test runner and on the build server xunit.console.exe was used to run the test.

When trying to run the tests with xunit.console.exe on my local machine I could reproduce the error.

For some unclear reason, XUnit was not able to load the FakeItEasy assembly that was located in the bin folder of the test assembly. The only workaround I found was to copy the FakeItEasy assembly to the folder of xunit.console.exe. After doing this, the number of tests on my local machine and on TeamCity matched again.

This is not really a satisfying solution, but I couldn’t find a better solution. Did someone find a proper solution for this problem?

JSON.NET attributes and RavenDB

RavenDB becomes more and more popular among .NET developer. The simple to use C# Api makes it a good choice for many project that require a fast persistence layer.

The JSON that is stored, can be customize using JSON.NET attributes. But sometimes you annotate your data POCOs and nothing happens e.g.

  • You put [JsonIgnore] on a property but it still appears in the created JSON

The reason is simple: The RavenDB team decided to put a copy of JSON.NET in the RavenDB dll and only the attributes from this “special” namespace are used for the JSON handling. So if you want to customize the JSON in the database, always use attributes from theĀ Raven.Imports.Newtonsoft.Json namespace.

error CS0012: The type ‘IEnumerable’ is defined in an assembly that is not referenced.

I was setting up a new build server for a .NET project as I have done several times before. It was a TeamCity build server but that is not important for this problem. When trying to build my solution I got this error:

error CS0012: The type 'IEnumerable<>' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

Locally the solution compiled just fine. After some research I found some hints that installing the Targeting Pack for my .NET Framework version solves the problem.

I downloaded and installed the target pack for .NET 4.6 from here. Immediately the problem was solved and the solution compiled without any problems.

It compiled locally because the missing DLL that is installed by the Targeting Pack is also installed by Visual Studio. This is just another reason to think about the “no Visual Studio on the build server” rule.

XmlSerializer – Check if property was present in XML

Recently I was parsing a large amount of XML files using the XmlSerializer class. While implementing the parser I came across a requirement where I had to check if a given property was null because it was specified as null or because the value was not present in the XML.

At first this caused me some headache because accessing the underlying XML file violates the abstraction provided by the serializer. Luckily, I recognised that the generated entity class (generated from XSD.exe) contains a lot of properties with the name <PropertyName>Specified. This is a very neat feature of the XmlSerializer. If you add a property with that name scheme it automatically sets the property to true when the corresponding element is present in the XML.

The property could look like this:

public bool MyPropertySpecified { get; set; }

Note: XmlIgnore is necessary to avoid having the artificial property serialised into XML when using the XmlSerializer to write XML. More details on the behaviour can be found in the class documentation here.