我创建了一个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.0Common7IDE";
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:TestResultsTestMethod1.trx");
当我在控制台项目中调试此方法时,它运行良好。但是当我运行 WCF 测试方法时,似乎什么也没发生。当我调试它时,我可以调用 WCF 方法,代码似乎被执行了,但实际上没有结果。
请问你对此有什么想法吗?
下面的修改代码将正确定位mstest.exe
并验证输入和输出文件是否存在。 如果未创建预期的输出,我们将抛出一个异常,其中包含进程的错误输出。 我们只使用完整路径来避免更改工作目录。
这些更改至少应该为您指明正确的方向,即从 WCF 使用它时出了什么问题。
但是请注意,下面的代码存在多个错误,如果它接受来自不受信任的客户端的输入,可能会影响安全性。 警告程序员。
// Example use
RunTest(@"......UnitTestProject1binDebugUnitTestProject1.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:rn" + 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(@"SOFTWAREWow6432NodeMicrosoftVisualStudio" + 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;
}
}