private string CreateCoverReport(string mergeFile)
        {
            string       reportxmlFileName = _context.WriteTempFile("zzz", "UnitTest-CoverReport-Result.xml");
            ReportParams rp = new ReportParams();

            rp.Source     = mergeFile;
            rp.Output     = reportxmlFileName;
            rp.ReportType = "XML";

            if (File.Exists(reportxmlFileName))
            {
                File.Delete(reportxmlFileName);
            }


            string args2File = _context.WriteTempFile(rp, "UnitTest-CoverReport-args.xml");

            // 调用 ReSharper dotCover ,生成代码覆盖率 报告文件
            ExecuteResult result = CommandLineHelper.Execute(s_dotCoverPath, string.Format("report \"{0}\"", args2File));

            _context.ConsoleWrite(result.ToString());

            result.FillBaseInfo();                  // 设置日志的时间,当前机器名
            _context.WriteTempFile(result, "UnitTest-CoverReport-Console.txt");

            System.Threading.Thread.Sleep(3000);                // 等待文件写入
            return(rp.Output);
        }
        private string MergedSnapshots(string[] projectFiles)
        {
            string      dcvrFileName = _context.WriteTempFile("aaaa", "UnitTest-MergedSnapshots-Result.dcvr");
            MergeParams mp           = new MergeParams();

            mp.Output = dcvrFileName;
            mp.Source = new List <string>();

            if (File.Exists(dcvrFileName))
            {
                File.Delete(dcvrFileName);
            }

            foreach (string file in projectFiles)
            {
                string dcvrFile = Path.Combine(Path.GetDirectoryName(file), "CoverResult.dcvr");
                mp.Source.Add(dcvrFile);
            }

            string args1File = _context.WriteTempFile(mp, "UnitTest-merge-args.xml");


            // 调用 ReSharper dotCover ,合并 代码覆盖率快照文件
            ExecuteResult result = CommandLineHelper.Execute(s_dotCoverPath, string.Format("merge \"{0}\"", args1File));

            _context.ConsoleWrite(result.ToString());

            result.FillBaseInfo();                  // 设置日志的时间,当前机器名
            _context.WriteTempFile(result, "UnitTest-MergedSnapshots-Console.txt");

            System.Threading.Thread.Sleep(3000);                // 等待文件写入
            return(mp.Output);
        }
        private void ExecuteTask()
        {
            // 单元测试结果文件,包含通过率数据
            // 为了防止项目同名,单元测试生成的结果文件和项目文件保存在一起,而不是直接保存到临时目录
            string resultFile = Path.Combine(Path.GetDirectoryName(_projectFile), @"TestResult.xml");
            string coverFile  = Path.Combine(Path.GetDirectoryName(_projectFile), @"CoverResult.dcvr");

            int retryTime = 0;

            while (retryTime <= 3)
            {
                if (File.Exists(resultFile))
                {
                    File.Delete(resultFile);
                }

                if (File.Exists(coverFile))
                {
                    File.Delete(coverFile);
                }


                CoverageParams cp = new CoverageParams();
                cp.TargetExecutable = _nunitPath;
                cp.TargetArguments  = string.Format("\"{0}\" --result \"{1}\"  --inprocess", _projectFile, resultFile);
                cp.TargetWorkingDir = Path.Combine(Path.GetDirectoryName(_projectFile), "bin");
                cp.Output           = coverFile;

                string argFileName = string.Format("UnitTest-cover-args-{0}.xml",
                                                   Path.GetFileNameWithoutExtension(_projectFile).Replace(".", "_"));
                string args1File = _context.WriteTempFile(cp, argFileName);

                // 调用 ReSharper dotCover ,执行单元测试,并生成代码覆盖率快照文件
                ExecuteResult result = CommandLineHelper.Execute(_dotCoverPath, string.Format("cover \"{0}\"", args1File));
                ConsoleWrite(result.ToString());

                result.FillBaseInfo();      // 设置日志的时间,当前机器名
                _context.WriteTempFile(result, "UnitTest-RunCover-Console-" + Path.GetFileNameWithoutExtension(_projectFile) + ".txt");


                // ReSharper dotCover 时常会出现BUG,现象为不能生成代码覆盖率快照文件,例如下面的执行消息:

                //Results (nunit3) saved as D:\TFS\10_5_10_96\Prod\ERP-V1.0\40_成本系统\01_主干-开发分支\88 公共类库\Mysoft.Cbxt.Common.UnitTest\TestResult.xml
                //[JetBrains dotCover] Coverage session finished [2018/1/3 6:06:05]
                //[JetBrains dotCover] Coverage session finished but no snapshots were created.

                // 目前的解决方法是,运行 dotCover 之后再检查是否已生成快照文件,如果文件没有生成就重新执行
                // 重试的最大次数为 3

                if (File.Exists(coverFile))
                {
                    break;
                }
                else
                {
                    System.Threading.Thread.Sleep(3000);
                    retryTime++;
                }
            }



            System.Threading.Thread.Sleep(3000);    // 等待文件写入

            if (File.Exists(resultFile))
            {
                NunitTestResult testResult = XmlHelper.XmlDeserializeFromFile <NunitTestResult>(resultFile);

                this.Result = new UnitTestResult {
                    ProjectName = Path.GetFileNameWithoutExtension(_projectFile),
                    Total       = testResult.Total,
                    Passed      = testResult.Passed
                };

                ConsoleWrite($"{Path.GetFileNameWithoutExtension(_projectFile)}: {testResult.Passed} / {testResult.Total}");

                // 将单元测试结果复制到临时目录。
                string tempFileName = string.Format("UnitTest-Result-{0}.xml", Path.GetFileNameWithoutExtension(_projectFile));

                try {
                    string text = File.ReadAllText(resultFile, Encoding.UTF8);
                    _context.WriteTempFile(text, tempFileName);
                }
                catch { /* 如果有异常发生,就忽略  */ }
            }
            else
            {
                ConsoleWrite(resultFile + " NOT FOUND!");
            }
        }