At the moment I’m using excellent service from Microsoft: hosted TFS. The service is still in the preview (15 July 2013) and some features are in beta, but it works pretty smoothly already. One of the things I had to learn is how to use TFS as a build server. I’ve used to nice TeamCity with almost drag-and-drop build steps and simple configuration management. TFS is using XAML definition file to drive the build process. The default template that comes with any project is pretty much covers everything you might need when you start, but it is very complex and when you try looking on the XAML diagram, you might want to run away – it’s that big and complex. That’s what I did first time I looked on the XAML processes. Run away and installed TeamCity.

Now I’ve decided to give it another go. I’ve started from enabling nUnit tests on build server. By default TFS only works with MSTest. To enable nUnit, you need to add nUnit assemblies and nUnit to MSTest adapter to your source control. The process is perfectly described in this post by Ajay Majgaonkar. I’ve also seen the description of the process in some Microsoft documentation, but have lost the link.

And this works fine, I got my nUnit tests to be executed in the build server. But I had some wicked integration tests that depend on Azure Storage Emulator running. That perfectly works on local machine, but on the build server there is no emulator, and there is no chance of starting the azure emulator on Microsoft build server. So I decided to ignore these tests for build server, but still run these on localhost. The plan was to create a category for tests and ignore that category on the build server.

So how do I ignore the test category in DefaultTemplate.xaml?? I poked about the settings for build definition and “Test Case Filter”. That was a start. But what do you write there? Turns out you can use a syntax for ignoring test cases. And that syntax is not easy to find. Took me a while before I put the right search terms into Google. Here is the full description for the syntax

I’ll copy that here in case the web-page goes down:

Operators supported are:

= (equals)
!= (not equals)
~ (contains or substring only for string values)
& (and)
| (or)
( ) (paranthesis for grouping) 

Expresssion can be created using these operators as any valid logical condition. & (and) has higher precedence over | (or) while evaluating expression.

E.g.

"TestCategory=NAR|Priority=1" 
"Owner=vikram&TestCategory!=UI" 
"FullyQualifiedName~NameSpace.Class"         
"(TestCategory!=UI&(Priority=1|Priority=2))|(TestCategory=UI&Priority=1)" 
"Priority~1" // Invalid as priority is int not string

Properties supported by MSTest adapter for filtering are

Name=<TestMethodDisplayNameName>
FullyQualifiedName=<FullyQualifiedTestMethodName>
Priority=<PriorityAttributeValue>
TestCategory=<TestCategoryAttributeValue>
ClassName=<ClassName> (Valid only for unit tests for Windows store apps, currently not available for classic MSTest)

So to ignore a category I had to set TestCaseFilter to TestCategory!=CategoryToBeIgnored. Something like this:

Set Test Case Filter to "TestCategory!=CategoryToIgnore"

And that worked. Now I need to figure out how to ignore test-assemblies from test-coverage analysis… but that’s for the next post.

  • Daz

    How would you go about excluding more than one test category from a test run.

    The following doesn’t seem to work:
    TestCategory!=CategoryToBeIgnored|TestCategory!=CategoryToBeIgnored

    • According to samples this should work: “(TestCategory!=Cat1)|(TestCategory=Cat2)” However, I have not tried this and have no way to try it – I don’t run my build servers on TFS anymore.

    • Don Perkins

      @Daz: it’s a logic problem. You need an “and” instead of an “or” in this case. Try:

      TestCategory != IgnoreMe & TestCategory != IgnoreMeToo

      Because:

      Assuming you are trying to run a test category of “IgnoreMe”, the math works out to:

      IgnoreMe != IgnoreMe & IgnoreMe != IgnoreMeToo ==> false (don’t run the test)

      IgnoreMe != Ignoreme | IgnoreMe != IgnoreMeToo ==> true (run the test)

      “Or” lets more things through. In fact, an equation where you have:

      x != y OR x != z

      reduces to a tautology… the result is ALWAYS true!