Some notes on the way the XSLT works.
First up, the format of NUnit results and MSTest TRX files are drastically different. There are some common items, but a TRX has repeated sections for tests (results summary & results) and the TRX files rely on GUIDs to cross reference results and executions.
Unfortunately generating GUIDs in a transform isn't possible and yet we need to generate the GUIDs for each transform as the TRX TestRun id GUID is used internally by TFS to uniquely identify test results. If we try publishing different test results using
the same GUID then TFS will reject the second attempt with a message indicating the test results have already been published. What I've had to do is cheat and psuedo-generate the GUIDs based on date/time values extracted from the NUnit results.
In the XSLT this is done by the TestRunGUID template.
TRX's also use GUIDs internally for executionID's and testID's. These are generated from the test number. Basically I've used the NUnit test result number (from the $pos xsl variable), padded it with zero's and prepended a portion of a Guid
onto it to form a properly constructed value. Since these only need to be unique within the test result file and not across test results (thankfully!) this is OK and makes it fairly easy to generate. Plus, because we're using the $pos xsl variable, it
means we can generate the cross-referenced GUID values that the TRX needs without having to store the values. Phew!
The rest of the XSLT is a simple extract and transform operation. It's a bit lengthy because of the multiple passes of the NUnit results but it works :-).