Turning Visual Studio MSTEST code coverage files into Xml
(This applies to Visual Studio 2005, but I would expect your experience in Visual Studio 2008 would be about the same)
Background
Starting with Visual Studio 2005, Visual Studio has had a built-in testing suite called MSTEST. While it has its shortcomings, it does a tolerable job of running tests and a really good job of generating code coverage results. Note that (sadly) the code coverage is only available in the Team Editions of Visual Studio, so you won’t see it in the Standard or Professional versions.
While Visual Studio code coverage is fantastic in the IDE, sometimes you want your code coverage results in something a little more portable (like XML). This is handy for integrating your code coverage results into a continuous integration server like JetBrains TeamCity or Thoughtworks CruiseControl.NET.
This is doable, but not exactly straightforward. The rest of this post will walk you through the process for turning Visual Studio code coverage results into XML.
The data.coverage file
When you start poking around Visual Studio’s code coverage, the first things you’ll notice is that Visual Studio spits out a data.coverage file every time you do a test run with code coverage enabled. You’ll find this file buried very deeply inside your “TestResults” folder.
Using your solution folder as the base, you’ll find each individual data.coverage file in folders something like this: (\TestResults\[USERNAME]_[MACHINE-NAME] [DATE AND TIME]\In\[MACHINE-NAME]). Nice and simple.
You can open this file directly in the IDE to see code coverage results from the test run, but it is binary so you can’t read it yourself or turn it into anything that a continuous integration server will understand. That’s the bad news.
The good news is that Visual Studio has a DLL that can read the file, and help you turn it into Xml. This DLL is Microsoft.VisualStudio.Coverage.Analysis.dll. I found mine in “C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies”
Turning data.coverage into Xml
With this DLL, you can write a really simple console app that will turn any data.coverage file into XML. Here’s the code for such a program.
1: using System;
2: using System.Collections.Generic;
3: using System.Data;
4: using System.Text;
5: using Microsoft.VisualStudio.CodeCoverage;
6:
7: namespace TurnCoverageFileIntoXml
8: {
9: class Program
10: {
11: static void Main(string[] args)
12: {
13: string file = args[0];
14: string path = args[1];
15: string output = args[2];
16:
17: CoverageInfoManager.ExePath = path;
18: CoverageInfoManager.SymPath = path;
19: CoverageInfo coverage =
20: CoverageInfoManager.CreateInfoFromFile(file);
21:
22: DataSet data = coverage.BuildDataSet(null);
23: data.WriteXml(output);
24: }
25: }
26: }
This simple console app takes in three arguments:
- The complete file path to the data.coverage file to process
- The complete file path to the folder where all the code lives.
- The file path to the XML file you want created.
As you can see, we’re referencing the Microsoft.VisualStudio.CodeCoverage namespace. This lets us use the CoverageInfoManager and CoverageInfo classes.
The first thing to do is to the set the executable path and symbol path using the CoverageInfo Manager. This path will be another deeply nested path that lives under your Visual Studio solution folder. This is the folder that Visual Studio uses to store all of your assemblies, symbols, and configuration files that are used to execute the test run.
Using your solution folder as the base, you’ll find the executables and symbols in folders something like this: (\TestResults\[USERNAME]_[MACHINE-NAME] [DATE AND TIME]\Out\).
After you have a configured CoverageInfoManager, you can use that to read in the data.coverage file and create a strongly-typed dataset. Once you have the strongly-typed dataset, you can write out the XML.
Doing something useful with the Xml
The Xml that you get out of data.coverage is plentiful and has everything you could want to know about your code coverage. From here, what you do with it up will depend on your needs. If you just want something simple, here’s a XSLT stylesheet that will pull out the names of the assemblies under test and their code coverage numbers.
1: <xsl:stylesheet version="1.0"
2: xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
3: <xsl:output method="xml" indent="yes" />
4:
5: <xsl:template match="/CoverageDSPriv">
6: <coverage>
7: <xsl:apply-templates select="//Module" />
8: </coverage>
9: </xsl:template>
10:
11: <xsl:template match="//Module">
12: <xsl:variable name="covered"
13: select="number(LinesCovered)" />
14: <xsl:variable name="not_covered"
15: select="number(LinesNotCovered)" />
16: <xsl:variable name="total"
17: select="$covered + $not_covered" />
18: <xsl:variable name="percent"
19: select="$covered div $total * 100" />
20:
21: <module>
22: <name>
23: <xsl:value-of select="ModuleName" />
24: </name>
25: <covered>
26: <xsl:value-of select="$covered" />
27: </covered>
28: <notcovered>
29: <xsl:value-of select="$not_covered" />
30: </notcovered>
31: <percent>
32: <xsl:value-of select="$percent" />
33: </percent>
34: </module>
35:
36: </xsl:template>
37:
38: </xsl:stylesheet>
More reading
If you want to know even more, John Cunningham has a very detailed post on this topic.