WCF 服务方法创建一个进程来运行 MsTest,该进程将不会执行

本文关键字:进程 MsTest 运行 执行 WCF 创建 方法 一个 服务 | 更新日期: 2023-09-27 18:36:57

我创建了一个WCF方法来执行MsTest命令来运行测试,如下所示:

Process process = new System.Diagnostics.Process();
ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = @"cmd";
//I used Test Agent
startInfo.WorkingDirectory = @"C:'Program Files (x86)'Microsoft Visual Studio 12.0'Common7'IDE";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardInput = true;
startInfo.CreateNoWindow = true;
process.StartInfo = startInfo;
process.Start();
process.StandardInput.WriteLine(@"mstest /testcontainer:MyTests.dll /test:MyTests.TestMethod1 /unique /resultsfile:C:'TestResults'TestMethod1.trx");

当我在控制台项目中调试此方法时,它运行良好。但是当我运行 WCF 测试方法时,似乎什么也没发生。当我调试它时,我可以调用 WCF 方法,代码似乎被执行了,但实际上没有结果。

请问你对此有什么想法吗?

WCF 服务方法创建一个进程来运行 MsTest,该进程将不会执行

下面的修改代码将正确定位mstest.exe并验证输入和输出文件是否存在。 如果未创建预期的输出,我们将抛出一个异常,其中包含进程的错误输出。 我们只使用完整路径来避免更改工作目录。

这些更改至少应该为您指明正确的方向,即从 WCF 使用它时出了什么问题。

但是请注意,下面的代码存在多个错误,如果它接受来自不受信任的客户端的输入,可能会影响安全性。 警告程序员。

// Example use
RunTest(@"..'..'..'UnitTestProject1'bin'Debug'UnitTestProject1.dll", "UnitTest1.TestMethod2", "out2.trx");
private static void RunTest(string testDll, string testMethod, string outFile)
{
    //Contract.Requires(!String.IsNullOrEmpty(testDll));
    //Contract.Requires(!String.IsNullOrEmpty(testMethod));
    //Contract.Requires(!String.IsNullOrEmpty(outFile));
    testDll = Path.GetFullPath(testDll);
    // this and all of the other tests suffer from TOCTOU issues, but they
    // are just advisory.  MSTest is the real gauntlet.
    if (!File.Exists(testDll))
    {
        throw new FileNotFoundException("testDll not found", testDll);
    }
    outFile = Path.GetFullPath(outFile);
    if (File.Exists(outFile) || !Directory.Exists(Path.GetDirectoryName(outFile)))
    {
        throw new InvalidOperationException("outFile already exists or directory does not exist");
    }
    string msTestLoc = GetMsTestPath("12.0"); // 12 == 2013, 11 = 2012, 10 == 2010, 9 == 2008
    // while testDll and outFile are minimally validated, testMethod is a
    // ripe target for injection into the command arguments.  Validation
    // would be appropriate.
    var psi = new ProcessStartInfo(msTestLoc, string.Format(
        "/testcontainer:'"{0}'" /test:{1} /unique /resultsfile:'"{2}'"",
        testDll, testMethod, outFile))
    {
        UseShellExecute = false,
        CreateNoWindow = true,
        RedirectStandardError = true,
        RedirectStandardOutput = true
    };
    var proc = Process.Start(psi);
    var errorOutput = new StringBuilder();
    proc.ErrorDataReceived += (_1, args) => errorOutput.AppendLine(args.Data);
    proc.OutputDataReceived += (_1, args) => errorOutput.AppendLine(args.Data);
    proc.BeginErrorReadLine();
    proc.BeginOutputReadLine();
    proc.WaitForExit();
    // we would check the return code here, but they don't seem to be documented
    if (!File.Exists(outFile))
    {
        throw new InvalidOperationException("mstest.exe did not produce an "
            + "output file:'r'n" + errorOutput.ToString());
    }
}
private static string GetMsTestPath(string vsVersion)
{
    //Contract.Ensures(Contract.Result<string>() != null);
    //Contract.Requires(!string.IsNullOrEmpty(vsVersion));
    using (var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
    using (var vsReg = hklm.OpenSubKey(@"SOFTWARE'Wow6432Node'Microsoft'VisualStudio'" + vsVersion))
    {
        var res = (string)vsReg.GetValue("InstallDir");
        if (res == null || !Directory.Exists(res))
        {
            throw new InvalidOperationException("VS install path not found");
        }
        var msbuildPath = Path.Combine(res, "mstest.exe");
        if (!File.Exists(msbuildPath))
        {
            throw new InvalidOperationException("MSTest not found");
        }
        return msbuildPath;
    }
}