0

我有以下程序

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 ";

}
4

2 回答 2

0

我敲出的一个非常粗略的例子是here。我没有测试过边缘情况,例如:行长度非常接近或正好是限制,或者单个测试用例超过限制。我会把这些练习留给你。

有时最简单的方法就是编写单元测试,输出标准循环和长度检查以通过这些测试,然后使用 LINQ 或正则表达式或代码清理来获得可维护和可读的东西。

string input = @"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";

const int LINE_LIMIT = 300;
const string TEST_MARKER = " /test:";

int testIndex = input.IndexOf(TEST_MARKER);
string prefix = input.Substring(0, testIndex);
int availableCharacters = LINE_LIMIT - prefix.Length;

Queue<string> tests = new Queue<string>(input.Substring(testIndex).Split(new []{TEST_MARKER}, StringSplitOptions.RemoveEmptyEntries));

List<string> testSets = new List<string>();
string currentTest = "";
while (tests.Count > 0)
{
    //restores the test marker from splitting
    string test = TEST_MARKER + tests.Dequeue(); 

    if (currentTest.Length + test.Length > availableCharacters)
    {
        testSets.Add(currentTest);
        currentTest = "";
    }
    else
    {
        currentTest += test;
    }
}

if (currentTest != "")
{
    testSets.Add(currentTest);
}

var lines = testSets.Select(t => prefix + t).ToList(); //your line outputs
于 2013-04-01T11:11:27.383 回答
0
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 ";

}
于 2013-04-02T02:02:46.163 回答