我有以下程序
class Program
{
static void Main(string[] args)
{
List<Assembly> failedAssemblies = LoadAssembly();
string batchFile = "D:\\1" + ".bat";
FileStream fs = File.Create(batchFile);
fs.Close();
using (StreamWriter outFile = new StreamWriter(batchFile))
{
string command = @"echo off";
outFile.WriteLine(command);
Process(outFile, failedAssemblies);
}
}
private static void Process(StreamWriter outFile, List<Assembly> assembliesList)
{
string command = "mstest.exe ";
string testcontainer = " /testcontainer:";
List<string> testContainerAssemblies = new List<string>(4);
outFile.WriteLine("SET Path=%MsTestPath%");
foreach (Assembly assmbly in assembliesList)
{
command = string.Empty;
if (!testContainerAssemblies.Contains(assmbly.AssemblyName))
{
outFile.WriteLine(' ');
testContainerAssemblies.Add(assmbly.AssemblyName);
command = "mstest.exe ";
command += testcontainer + "\\" + assmbly.AssemblyName + " ";
command += "/resultsfile:\"" + "\\Resultfile_" + assmbly.AssemblyName.Replace(".dll", "") + "_" + "1".ToString() + ".trx\"";
command += " /runconfig:";
command += " /detail:owner";
command += " /detail:duration";
command += " /detail:description";
command += " /unique ";
}
command += " /test:" + assmbly.NameSpaceName + "." + assmbly.ClassName + "." + assmbly.FunctionName;
outFile.Write(command);
}
}
private static List<Assembly> LoadAssembly()
{
var assemblyCollection = new List<Assembly>();
assemblyCollection.Add(new Assembly { AssemblyName = "AccountTestBase.dll", NameSpaceName = "ECardTest", ClassName = "ECardTest", FunctionName = "ECardTestDownLoadPKGSuccess" });
assemblyCollection.Add(new Assembly { AssemblyName = "AccountTestBase.dll", NameSpaceName = "AccountTest", ClassName = "IAccountTest", FunctionName = "Somefunc" });
assemblyCollection.Add(new Assembly { AssemblyName = "TestPayment.dll", NameSpaceName = "TestPayment", ClassName = "CreditCardTestCases", FunctionName = "BoletoFunctionalTestCase" });
assemblyCollection.Add(new Assembly { AssemblyName = "TestPayment.dll", NameSpaceName = "TestPayment", ClassName = "CreditCardTestCases", FunctionName = "BoletoEndToEndFunctionalTestCase" });
assemblyCollection.Add(new Assembly { AssemblyName = "TestPayment.dll", NameSpaceName = "TestPayment", ClassName = "CreditCardTestCases", FunctionName = "BoletoPurcahseTestCase" });
assemblyCollection.Add(new Assembly { AssemblyName = "TestPayment.dll", NameSpaceName = "TestPayment", ClassName = "CreditCardTestCases", FunctionName = "CreditCard_ResumeOrder_Success" });
assemblyCollection.Add(new Assembly { AssemblyName = "TestPayment.dll", NameSpaceName = "TestPayment", ClassName = "CreditCardTestCases", FunctionName = "CreditCard_EURCurr_USBilling_ENUS" });
assemblyCollection.Add(new Assembly { AssemblyName = "TestPayment.dll", NameSpaceName = "TestPayment", ClassName = "CreditCardTestCases", FunctionName = "DinersClubPayment" });
return assemblyCollection;
}
}
public class Assembly
{
public string AssemblyName { get; set; }
public string ClassName { get; set; }
public string FunctionName { get; set; }
public string NameSpaceName { get; set; }
}
它生成以下输出
echo off
SET Path=%MsTestPath%
mstest.exe /testcontainer:\AccountTestBase.dll /resultsfile:"\Resultfile_AccountTestBase_1.trx" /runconfig: /detail:owner /detail:duration /detail:description /unique /test:ECardTest.ECardTest.ECardTestDownLoadPKGSuccess /test:AccountTest.IAccountTest.Somefunc
mstest.exe /testcontainer:\TestPayment.dll /resultsfile:"\Resultfile_TestPayment_1.trx" /runconfig: /detail:owner /detail:duration /detail:description /unique /test:TestPayment.CreditCardTestCases.BoletoFunctionalTestCase /test:TestPayment.CreditCardTestCases.BoletoEndToEndFunctionalTestCase /test:TestPayment.CreditCardTestCases.BoletoPurcahseTestCase /test:TestPayment.CreditCardTestCases.CreditCard_ResumeOrder_Success /test:TestPayment.CreditCardTestCases.CreditCard_EURCurr_USBilling_ENUS /test:TestPayment.CreditCardTestCases.DinersClubPayment
现在出现了一个新要求,我们需要根据通过的限制来打破输出。
假设如果限制为 300,则输出将是
echo off
SET Path=%MsTestPath%
mstest.exe /testcontainer:\AccountTestBase.dll /resultsfile:"\Resultfile_AccountTestBase_1.trx" /runconfig: /detail:owner /detail:duration /detail:description /unique /test:ECardTest.ECardTest.ECardTestDownLoadPKGSuccess
mstest.exe /testcontainer:\TestPayment.dll /resultsfile:"\Resultfile_TestPayment_1.trx" /runconfig: /detail:owner /detail:duration /detail:description /unique /test:TestPayment.CreditCardTestCases.BoletoFunctionalTestCase /test:TestPayment.CreditCardTestCases.BoletoEndToEndFunctionalTestCase
mstest.exe /testcontainer:\TestPayment.dll /resultsfile:"\Resultfile_TestPayment_1.trx" /runconfig: /detail:owner /detail:duration /detail:description /unique /test:TestPayment.CreditCardTestCases.BoletoPurcahseTestCase /test:TestPayment.CreditCardTestCases.CreditCard_ResumeOrder_Success /test:TestPayment.CreditCardTestCases.CreditCard_EURCurr_USBilling_ENUS /test:TestPayment.CreditCardTestCases.DinersClubPayment
即第一个的总字符数限制为 210(大约),此后保持不变。第二个已经越界了,需要拆分成两部分。第一个被拆分(290),因为再添加一个命令会超过限制。这就是为什么我们需要将它拆分为两部分。
还有一点要说的是,我们不能仅仅根据提供的 Limit 值精确分割。因为它是一个需要运行的 MSTest 命令。今后,
"mstest.exe /testcontainer:\TestPayment.dll /resultsfile:"\Resultfile_TestPayment_1.trx" /runconfig: /detail:owner /detail:duration /detail:description /unique"
总会来然后"test/..."
如何在 C# 中做同样的事情?
MyShot(请改进)
private static void Process(StreamWriter outFile, List<Assembly> failedAssemblies)
{
int MAXLIMIT = 2000;
string command = "mstest.exe ";
string testcontainer = " /testcontainer:";
List<string> testContainerAssemblies = new List<string>(4);
int sum = 0;
outFile.WriteLine("SET Path=%MsTestPath%");
var failedAssemblyCollections = (from x in failedAssemblies
group x by x.AssemblyName into g
select new
{
AssemblyNames = g.Key,
FullyQualifiedTestMethods = g.Select(i => " /test:" + i.NameSpaceName + "." + i.ClassName + "." + i.FunctionName),
FullyQualifiedTestMethodsLen = g.Select(i => Convert.ToString(" /test:" + i.NameSpaceName + "." + i.ClassName + "." + i.FunctionName).Length)
});
foreach (var item in failedAssemblyCollections)
{
var assemblyNames = item.AssemblyNames;
var methodsLengths = item.FullyQualifiedTestMethodsLen.ToList();
var flag = true;
int counter = 0;
//write for the very first time
if (flag)
{
Write(outFile, ref command, testcontainer, assemblyNames);
flag = false;
}
for (int i = 0; i < methodsLengths.Count; i++)
{
sum += methodsLengths[i];
if (sum <= MAXLIMIT)
{
command += item.FullyQualifiedTestMethods.ToList()[i];
//this will execute when a long command is splitted and is written in new trx files
if (flag)
{
counter++;
Write(outFile, ref command, testcontainer, assemblyNames);
flag = false;
}
}
//if the value crosses max limit
//write the current output
//then reset variables to original
if (sum >= MAXLIMIT)
{
outFile.Write(command);
sum = 0;
flag = true;
i--;
}
}
outFile.Write(command);
}
}
private static void Write(StreamWriter outFile, ref string command, string testcontainer, string assemblyNames)
{
outFile.WriteLine(' ');
command = "mstest.exe ";
command += testcontainer + "\\" + assemblyNames + " ";
command += " /runconfig:";
command += " /detail:owner";
command += " /detail:duration";
command += " /detail:description";
command += " /unique ";
}