/// <summary>
        /// Called when a test result is received.
        /// </summary>
        private void TestResultHandler(object sender, TestResultEventArgs e)
        {
            if (e.Result.Outcome == TestOutcome.NotFound)
            {
                return;
            }

            DataType.TestCaseDetail caseDetail = ConvertToTestCase(e.Result);
            results.TryAdd(caseDetail.Name, caseDetail);

            // Generate txt log file
            string txtFileName = Path.Combine(
                txtResultFolderPath,
                string.Format("{0}_{1}_{2}.txt",
                              caseDetail.StartTime.ToLocalTime().ToString("yyyy-MM-dd-HH-mm-ss"),
                              caseDetail.Result,
                              caseDetail.Name)
                );

            File.WriteAllText(txtFileName, ConstructCaseTxtReport(caseDetail));

            // Generate html log file
            string htmlFileName = Path.Combine(htmlResultFolderPath, $"{caseDetail.Name}.html");

            File.WriteAllText(htmlFileName, ConstructCaseHtml(caseDetail));
        }
        /// <summary>
        /// Constructs details of test case.
        /// 1. Gets log from the test case detail
        /// 2. Copies capture to the log folder, and saves the path.
        /// </summary>
        /// <param name="caseDetail">The informatoin of each test case which contains the detail log</param>
        /// <param name="captureFolder">Capture folder path</param>
        /// <returns>return the log information in Json format</returns>
        public string ConstructCaseDetail(DataType.TestCaseDetail caseDetail, string captureFolder)
        {
            caseDetail.CapturePath = CopyCaptureAndReturnPath(caseDetail.FullyQualifiedName, captureFolder);

            var caseDetailForJson = new DataType.TestCaseDetailForJson();

            caseDetailForJson.Update(caseDetail);

            return(Serialize(caseDetailForJson));
        }
        /// <summary>
        /// Inserts the corresponding script to the template html and generates the [testcase].html
        /// </summary>
        private string ConstructCaseHtml(DataType.TestCaseDetail caseDetail)
        {
            // Insert script to the template html (testcase.html)
            StringBuilder sb = new StringBuilder();

            sb.Append(ConstructDetailObj(caseDetail));
            sb.AppendLine("var titleObj = document.getElementById(\"right_sidebar_case_title\");");
            sb.Append(string.Format("CreateText(titleObj, \"{0}\");", caseDetail.Name));

            return(InsertScriptToTemplate(Properties.Resources.testcase, sb.ToString()));
        }
        /// <summary>
        /// Constructs detailObj used in each [caseName].html
        /// </summary>
        private string ConstructDetailObj(DataType.TestCaseDetail caseDetail)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine();
            sb.Append("var detailObj=");
            sb.Append(txtToJSON.ConstructCaseDetail(caseDetail, captureFolderPath));
            sb.AppendLine(";");

            return(sb.ToString());
        }
        /// <summary>
        /// Called when a test result is received.
        /// </summary>
        private void TestResultHandler(object sender, TestResultEventArgs e)
        {
            if (e.Result.Outcome == TestOutcome.NotFound)
            {
                return;
            }

            DataType.TestCaseDetail caseDetail = ConvertToTestCase(e.Result);
            results.TryAdd(caseDetail.FullyQualifiedName, caseDetail);

            // Generate html log file
            string htmlFileName = Path.Combine(htmlResultFolderPath, $"{caseDetail.FullyQualifiedName}.html");

            File.WriteAllText(htmlFileName, ConstructCaseHtml(caseDetail));
        }
        /// <summary>
        /// Inserts the corresponding script to the template html and generates the [testcase].html
        /// </summary>
        private string ConstructCaseTxtReport(DataType.TestCaseDetail caseDetail)
        {
            StringBuilder sb = new StringBuilder();

            if (DateTimeOffset.Compare(testRunStartTime, caseDetail.StartTime.ToLocalTime()) > 0)
            {
                testRunStartTime = caseDetail.StartTime.ToLocalTime();
            }
            if (DateTimeOffset.Compare(testRunEndTime, caseDetail.EndTime.ToLocalTime()) < 0)
            {
                testRunEndTime = caseDetail.EndTime.ToLocalTime();
            }

            sb.AppendLine(caseDetail.Name);
            sb.AppendLine("Start Time: " + caseDetail.StartTime.ToLocalTime().ToString("MM/dd/yyyy HH:mm:ss"));
            sb.AppendLine("End Time: " + caseDetail.EndTime.ToLocalTime().ToString("MM/dd/yyyy HH:mm:ss"));
            sb.AppendLine("Result: " + caseDetail.Result);
            sb.AppendLine(caseDetail.Source);
            if (caseDetail.ErrorStackTrace.Count() > 0)
            {
                sb.AppendLine("===========ErrorStackTrace===========");
                caseDetail.ErrorStackTrace.ForEach(line => sb.AppendLine(line));
            }
            if (caseDetail.ErrorMessage.Count() > 0)
            {
                sb.AppendLine("===========ErrorMessage==============");
                caseDetail.ErrorMessage.ForEach(line => sb.AppendLine(line));
            }
            if (caseDetail.StandardOut.Count() > 0)
            {
                sb.AppendLine("===========StandardOut===============");
                caseDetail.StandardOut.ForEach(stdout => sb.AppendLine(stdout.Content));
            }

            return(sb.ToString());
        }
Пример #7
0
        /// <summary>
        /// Constructs details of test case.
        /// 1. Gets log from the txt file
        /// 2. Copies capture to the log folder, and saves the path.
        /// </summary>
        /// <param name="txtfile">The path to the log txt file which contains the detail log</param>
        /// <returns>Returns the log information</returns>
        public string ConstructCaseDetail(DataType.TestCaseDetail caseDetail, string captureFolder)
        {
            caseDetail.CapturePath = CopyCaptureAndReturnPath(caseDetail.Name, captureFolder);

            return(serializer.Serialize(caseDetail));
        }
        /// <summary>
        /// Constructs details of test case.
        /// 1. Gets log from the txt file
        /// 2. Copies capture to the log folder, and saves the path.
        /// </summary>
        /// <param name="txtfile">The path to the log txt file which contains the detail log</param>
        /// <returns>Returns the log information</returns>
        public string ConstructCaseDetail(string txtfile, string captureFolder)
        {
            FileStream fs = new FileStream(txtfile, FileMode.Open);
            string type = ""; // Help judge whether the line is the end of the file, help distinguish file content
            StreamReader sr = new StreamReader(fs);
            string line;
            string content = "";
            string standardOutType = "";
            DataType.TestCaseDetail caseDetail = new DataType.TestCaseDetail(sr.ReadLine(), sr.ReadLine(), sr.ReadLine(), sr.ReadLine());
            DataType.StandardOutDetail stdDetail;
            string dllFile = sr.ReadLine();
            if (!dllFiles.Contains(dllFile))
            {
                dllFiles.Add(dllFile);
            }
            while ((line = sr.ReadLine()) != null)
            {
                if (line == "") //Rule out blank line
                    continue;

                if (line.StartsWith("==========="))
                {
                    type = line.Replace("=", "");
                    continue;
                }

                LogType eType = (LogType)Enum.Parse(typeof(LogType), type);
                switch (eType)
                {
                    case LogType.ErrorStackTrace:
                        caseDetail.ErrorStackTrace.Add(line);
                        break;
                    case LogType.ErrorMessage:
                        caseDetail.ErrorMessage.Add(line);
                        break;
                    case LogType.StandardOut:
                        int begin = line.IndexOf('[');
                        int end = line.IndexOf(']');

                        if (begin != -1 && end != -1)
                        {
                            if (standardOutType != "")
                            {
                                stdDetail = new DataType.StandardOutDetail()
                                {
                                    Content = content,
                                    Type = standardOutType
                                };
                                caseDetail.StandardOut.Add(stdDetail);
                            }
                            if (end > begin && end < line.Length)
                            {
                                standardOutType = line.Substring(begin + 1, end - begin - 1);
                                if (!caseDetail.StandardOutTypes.Contains(standardOutType))
                                    caseDetail.StandardOutTypes.Add(standardOutType);
                            }
                            content = line;
                        }
                        else
                            content += line;
                        break;
                    default: break;
                }
            }
            stdDetail = new DataType.StandardOutDetail()
            {
                Content = content,
                Type = standardOutType
            };
            fs.Close();
            caseDetail.StandardOut.Add(stdDetail);

            caseDetail.CapturePath = CopyCaptureAndReturnPath(caseDetail.Name, captureFolder);

            return (serializer.Serialize(caseDetail));
        }
Пример #9
0
        /// <summary>
        /// Constructs details of test case.
        /// 1. Gets log from the txt file
        /// 2. Copies capture to the log folder, and saves the path.
        /// </summary>
        /// <param name="txtfile">The path to the log txt file which contains the detail log</param>
        /// <returns>Returns the log information</returns>
        public string ConstructCaseDetail(string txtfile, string captureFolder)
        {
            FileStream   fs   = new FileStream(txtfile, FileMode.Open);
            string       type = ""; // Help judge whether the line is the end of the file, help distinguish file content
            StreamReader sr   = new StreamReader(fs);
            string       line;
            string       content         = "";
            string       standardOutType = "";

            DataType.TestCaseDetail    caseDetail = new DataType.TestCaseDetail(sr.ReadLine(), sr.ReadLine(), sr.ReadLine(), sr.ReadLine());
            DataType.StandardOutDetail stdDetail;
            string dllFile = sr.ReadLine();

            if (!dllFiles.Contains(dllFile))
            {
                dllFiles.Add(dllFile);
            }
            while ((line = sr.ReadLine()) != null)
            {
                if (line == "") //Rule out blank line
                {
                    continue;
                }

                if (line.StartsWith("==========="))
                {
                    type = line.Replace("=", "");
                    continue;
                }

                LogType eType = (LogType)Enum.Parse(typeof(LogType), type);
                switch (eType)
                {
                case LogType.ErrorStackTrace:
                    caseDetail.ErrorStackTrace.Add(line);
                    break;

                case LogType.ErrorMessage:
                    caseDetail.ErrorMessage.Add(line);
                    break;

                case LogType.StandardOut:
                    int begin = line.IndexOf('[');
                    int end   = line.IndexOf(']');

                    if (begin != -1 && end != -1)
                    {
                        if (standardOutType != "")
                        {
                            stdDetail = new DataType.StandardOutDetail()
                            {
                                Content = content,
                                Type    = standardOutType
                            };
                            caseDetail.StandardOut.Add(stdDetail);
                        }
                        if (end > begin && end < line.Length)
                        {
                            standardOutType = line.Substring(begin + 1, end - begin - 1);
                            if (!caseDetail.StandardOutTypes.Contains(standardOutType))
                            {
                                caseDetail.StandardOutTypes.Add(standardOutType);
                            }
                        }
                        content = line;
                    }
                    else
                    {
                        content += line;
                    }
                    break;

                default: break;
                }
            }
            stdDetail = new DataType.StandardOutDetail()
            {
                Content = content,
                Type    = standardOutType
            };
            fs.Close();
            caseDetail.StandardOut.Add(stdDetail);

            caseDetail.CapturePath = CopyCaptureAndReturnPath(caseDetail.Name, captureFolder);

            return(serializer.Serialize(caseDetail));
        }
Пример #10
0
 /// <summary>
 /// Constructs details of test case.
 /// 1. Gets log from the txt file
 /// 2. Copies capture to the log folder, and saves the path.
 /// </summary>
 /// <param name="txtfile">The path to the log txt file which contains the detail log</param>
 /// <returns>Returns the log information</returns>
 public string ConstructCaseDetail(DataType.TestCaseDetail caseDetail, string captureFolder)
 {
     caseDetail.CapturePath = CopyCaptureAndReturnPath(caseDetail.Name, captureFolder);
     return(specificDateTimeOffsetSerializer(caseDetail));
 }
        /// <summary>
        /// Convert a vstest TestResult object to TestCaseDetail
        /// </summary>
        private DataType.TestCaseDetail ConvertToTestCase(TestResult result)
        {
            var eolSeparators = new char[] { '\r', '\n' };

            string        caseName       = !string.IsNullOrEmpty(result.TestCase.DisplayName) ? result.TestCase.DisplayName : result.TestCase.FullyQualifiedName.Split('.').Last();
            string        outcome        = result.Outcome == TestOutcome.Skipped ? "Inconclusive" : result.Outcome.ToString();
            string        classType      = result.TestCase.FullyQualifiedName.Split('.').Reverse().ElementAtOrDefault(1);
            List <string> testCategories = GetCustomPropertyValueFromTestCase(result.TestCase, categoryPropertyKey);

            var ret = new DataType.TestCaseDetail(caseName, result.TestCase.FullyQualifiedName, result.StartTime, result.EndTime, outcome, result.TestCase.Source, classType, testCategories);

            if (!String.IsNullOrEmpty(result.ErrorStackTrace))
            {
                ret.ErrorStackTrace.AddRange(result.ErrorStackTrace.Split(eolSeparators, StringSplitOptions.RemoveEmptyEntries));
            }

            if (!String.IsNullOrEmpty(result.ErrorMessage))
            {
                ret.ErrorMessage.AddRange(result.ErrorMessage.Split(eolSeparators, StringSplitOptions.RemoveEmptyEntries));
            }

            var stdout = new List <string>();

            foreach (TestResultMessage m in result.Messages)
            {
                if (m.Category == TestResultMessage.StandardOutCategory && !String.IsNullOrEmpty(m.Text))
                {
                    stdout.AddRange(m.Text.Split(eolSeparators, StringSplitOptions.RemoveEmptyEntries));
                }
            }
            foreach (string line in stdout)
            {
                string pattern = @"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3} \[(\w+)\] ";
                Regex  r       = new Regex(pattern, RegexOptions.IgnoreCase);

                Match m = r.Match(line);
                if (m.Success)
                {
                    string type = m.Groups[1].Value;
                    ret.StandardOut.Add(new DataType.StandardOutDetail()
                    {
                        Content = line,
                        Type    = type
                    });
                }
                else
                {
                    // There must be at least one record in the list.
                    // Just to make the logger robust, let's do a check here.
                    // (But it won't happen)
                    int stdoutCount = ret.StandardOut.Count;
                    if (stdoutCount == 0)
                    {
                        continue;
                    }
                    else
                    {
                        var lastOutput = ret.StandardOut[stdoutCount - 1];
                        lastOutput.Content = lastOutput.Content + '\n' + line;
                    }
                }
            }

            ret.StandardOutTypes = ret.StandardOut.Select(output => output.Type).Distinct().ToList();

            return(ret);
        }