Hacking MSTest out of Visual Studio

For a while, we’ve been using Hudson as our Continuous Integration server for a while now, but we had a problem where the unit tests we had written were all in MSTest. However, MSTest doesn’t like to be installed without all of Visual Studio. Luckily, Mark Kharitonov at Shunra has figured it out and written up a post about it. I’ll only note two things I had to do to make his solution work:

  1. I had to add the VS2008Stub\Common7\IDE folder to the global PATH so that mstest.exe could be found (and restart Hudson so Hudson would update it’s PATH)
  2. Hack MSTest to allow me to use the /testmetadata and /testlist options.

I had to do #2, because the MSTest plugin for hudson seems to only want a single TRX file, which would have required me writing a bunch of MSBuild stuff I didn’t feel up to writing so that MSTest would run once for the entire build, instead of once per Test DLL file. By using the /testmetadata option, I can set up a vsmdi file and tell it which tests to run, which also provides me the added benefit of disabling certain tests that I might not want to run for some reason or another. In my case, I had a few tests that went against the database that really need to be rebuilt using a Mocking framework. They can’t run on the CI server (the CI server doesn’t have access to the Database), but they have some mild use currently on my local machine, so I don’t want to simply exclude them.

Anyway, MSTest, it turns out, actually checks your Visual Studio license to determine how it should function. Basically, it offers a few more options if you have a Visual Studio license, and a few more options if you have a Team System license. We don’t have Team System (or we’d probably be using Team Build anyway), but we do have Visual Studio licenses. Of course, they don’t tell you that the binary does different things based on a registry key, that’s what my good friend .NET Reflector is for.

Due to the fact that Reflector actually displays disassembled code, code I didn’t write, and I sure don’t have permission to redistribute, I’m going to gloss over what exactly I did to figure out what to do in the next paragraph. I’ll likely put together a new post in the future about hacking .NET using Reflector, but it will be on non-encumbered code.

It turns out there are five special codes that MSTest looks for to enable or disable features, namely the Test List Editor (what I was interested in), Team Developer Tools, TFS Integration, Remote Execution, and Authoring Non Core Tests. I’m not entirely sure what those last four are (though I plan to investigate), since as I said, I only really need the first one. Interestingly enough, the way they’ve implemented this security, it’s a pretty simple hack to enable the ones that you aren’t licensed to use. Which wouldn’t be the right thing to do, which is why I’m not providing those codes, or even the actual location of the codes you shouldn’t have, to you, my reader. I’m covering my own ass.

Open up Regedit on your development box, and point it to HKLM\SOFTWARE\Microsoft\VisualStudio\9.0\Licenses, and you’ll see a list of keys (probably only one, but it could be more than one). Export the keys you see under this hive, and then import them into your CI server, and it should automagically unlock the features you were missing on CI, check the /help output to be sure. Note: On a 64-bit system, the Hive is HKLM\Software\Wow6432Node\Microsoft\VisualStudio\9.0\Licenses. Just make sure you export and import to and from the correct location, if there is a difference in bit-width between your two boxes.

Now, you should have all the MSTest features you had on your development box on your CI box, and you didn’t have to do a full install of Visual Studio in CI.