views:

249

answers:

3

Is there an API for running Visual Studio Unit Tests programmatically?

Running MSTests.exe with Process.Start() does not work in the current scenario. What I'm looking for is something like the NUnit SimpleTestRunner.

Any ideas?

/Erik

A: 

Why not using Reflector and seeing how NUnit SimpleTestRunner is running the tests... And then use this technique...

Peter Gfader
Digging in with Reflector is a great idea. However, the NUnit SimpleTestRunner uses the NUnit test runner API, which anyone can use. The problem is that VSTest does not seem to have a corresponding API.
Erik Öjebo
+1  A: 

After taking a deep dive with reflector into MSTest.exe and further down into the Visual Studio Unit Test stack, I found that the API used by MSTest is sealed up and made private so that i cannot be used from the outside.

Erik Öjebo
+3  A: 

You're correct in that there's no public API for the mstest framework. I wrote a manual replacement for mstest one day to see how hard it was, and it's not as simple as it looks (particularly if you want to take advantage of more than one CPU core), so beware of going down this path.

Personally I've always just run mstest.exe programatically and then parsed the resulting .trx XML file. Are there any particular reasons why you can't use Process.Start to run it?

P.S. Some of the strange behaviour of mstest.exe are solved if you pass the /noisolation command line parameter - give that a go if you feel so inclined :-)


Update: Erik mentions he wants to run the test API in the current thread so he can set the thread culture for globalization issues.

If you run a unit test under the debugger, you'll notice that mstest creates a bunch of threads, and runs all your tests in different threads, so this isn't likely to work even if you could access the API.

What I'd suggest doing is this:

  1. From your test "runner" application, set an environment variable
  2. Run mstest pointing it at the specific tests
  3. Add a [ClassInitialize] (or [TestInitialize]) method which reads this environment variable and sets the culture
  4. Profit!
Orion Edwards
I need to run mstest in the current thread so that I can set the culture in which the tests run. We have some culture sensitive code that we want to run under multiple cultures.What kind of strange behaviour is solved by /noisolation?
Erik Öjebo
if you don't set /noisolation, mstest creates a whole bunch of extra threads and appdomains and things. This causes code coverage tools like ncover and partcover to fail.
Orion Edwards
Thanks for the info! Always nice to get a deeper understanding for the tools you use. Your solution for the culture thingy is more or less what we ended up implementing, since we could not get it to run in the current thread. However, it would be nice to not have to rely on an external signaling mechanism.
Erik Öjebo