6

I am trying to run some unit tests using PowerShell. I have a command that (sort of) works:

$output = & $vsTestPath $TestAssembly $logger $TestCaseFilter 2>&1

The problem with this is that the standard out and standard error streams don't come out in the right order - they get mixed up. One solution to this (from here) is to use cmd.exe, but I cannot get this to work. I feel like I've tried everything I can think of.

Here's what I have:

$vsTestPath = "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"
$TestAssembly = "C:\IntegrationTesting\Test Application\Ads.Slms.IntegrationTesting.Web.Smartfill.dll"
$output = & cmd.exe /c $vsTestPath $TestAssembly 2`>`&1

This last line does not work. Wierdly, if I just have

$output = & cmd.exe /c $vsTestPath 2`>`&1

Then this runs, but of course it's no use to me. It's the second parameter that's the problem. Other things I've tried. How can I get this to run?

$output = & cmd.exe /c $vsTestPath $TestAssembly 2`>`&1
$output = & cmd.exe /c $vsTestPath,$TestAssembly 2`>`&1
$output = & cmd.exe /c "$vsTestPath" $TestAssembly 2`>`&1
$output = & cmd.exe /c """$vsTestPath""" $TestAssembly 2`>`&1
$output = & cmd.exe /c "$vsTestPath" "$TestAssembly" 2`>`&1
$output = & cmd.exe /c """$vsTestPath""" """$TestAssembly""" 2`>`&1
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
bornfromanegg
  • 2,826
  • 5
  • 24
  • 40
  • Try this: `$output = & cmd.exe /c '"' $vsTestPath $TestAssembly '2>&1' '"'` – user4003407 Feb 18 '15 at 10:47
  • if you look at the example that you reference in the link above, the example does not include the '&', I've used this in the past `$output = cmd.exe /c $vsTestPath $TestAssembly 2`>`&1` – mhatch73 Feb 18 '15 at 12:05
  • @PetSerAl - that worked! Exactly why, I'm not sure. It does look a little like black magic. :-) If you add it as an answer, I can accept it. Thanks for all the answers - I can't tell you how grateful I am to get this working. mhatch73 - didn't work, I'm afraid ('C:\Program' is not recognized as an internal or external command). I should point out that there are spaces in vsTestPath and TestAssembly - I think that's what's (been) causing me the problems. – bornfromanegg Feb 18 '15 at 14:55

1 Answers1

13

When you run this PowerShell command,

& cmd.exe /c $vsTestPath $TestAssembly 2`>`&1

PowerShell produces this command line:

cmd.exe /c "C:\Program Files (x86)\BlaBlaBla.exe" "C:\IntegrationTesting\Test Application\BlaBlaBla.dll" 2>&1

PowerShell encloses values of $vsTestPath and $TestAssembly in quotes as they contain spaces and the first character is not a quote itself. Now you have to understand how cmd processes this command line (see cmd /?):

If /C or /K is specified, then the remainder of the command line after
the switch is processed as a command line, where the following logic is
used to process quote (") characters:

    1.  If all of the following conditions are met, then quote characters
        on the command line are preserved:

        - no /S switch
        - exactly two quote characters
        - no special characters between the two quote characters,
          where special is one of: &<>()@^|
        - there are one or more whitespace characters between the
          two quote characters
        - the string between the two quote characters is the name
          of an executable file.

    2.  Otherwise, old behavior is to see if the first character is
        a quote character and if so, strip the leading character and
        remove the last quote character on the command line, preserving
        any text after the last quote character.

As you can see, we have more than two quotes and first character is quote, so cmd will strip first and last quote from the command line:

C:\Program Files (x86)\BlaBlaBla.exe" "C:\IntegrationTesting\Test Application\BlaBlaBla.dll 2>&1

Now you actually starting C:\Program with some arguments, and you very likely does not have C:\Program.exe or C:\Program.cmd. Solution: add extra quotes to make cmd happy:

& cmd.exe /c `" $vsTestPath $TestAssembly 2`>`&1 `"
cmd.exe /c " "C:\Program Files (x86)\BlaBlaBla.exe" "C:\IntegrationTesting\Test Application\BlaBlaBla.dll" 2>&1 "
"C:\Program Files (x86)\BlaBlaBla.exe" "C:\IntegrationTesting\Test Application\BlaBlaBla.dll" 2>&1
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user4003407
  • 21,204
  • 4
  • 50
  • 60