alielie
2026-09-10 f3889f2d36c50cf99468594854def9b7ed069fb5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using AddInPlugin.Setting;
using OpenTap;
using OpenTap.Addin.Entity;
using OpenTap.Addin.Util;
using Scriban;
using Scriban.Runtime;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text.Json.Serialization;
 
namespace AddInPlugin
{
    public class ReportData
    {
        public string Name { get; set; }
        public string StartTime { get; set; }
        public string EndTime { get; set; }
        public Verdict Verdict { get; set; }
        public string Consuming { get; set; }
        public List<ReportDetail> Parameters { get; set; }
    }
 
    public class TestReport
    {
        public string Name { get; set; }
        public Verdict Verdict { get; set; }
        public string StartTime { get; set; }
        public string EndTime { get; set; }
        public string CreateTime { get; set; }
        public List<ReportData> Steps { get; set; } = new List<ReportData>();
    }
 
    public class HtmlReportListener : ReportListener
    {
        private static string templateStr;
 
        private TestReport report;
 
        public static string ReadEmbeddedResource(string resourceName)
        {
            // resourceName 格式: "命名空间.文件夹.文件名.txt"
            // 例如: "MyApp.Templates.test_report_template.txt"
 
            var assembly = Assembly.GetExecutingAssembly();
 
            using (Stream stream = assembly.GetManifestResourceStream(resourceName))
            {
                if (stream == null)
                {
                    // 调试:列出所有可用的资源名称
                    var allResources = assembly.GetManifestResourceNames();
                    throw new FileNotFoundException(
                        $"资源 '{resourceName}' 未找到。可用资源: {string.Join(", ", allResources)}");
                }
 
                using (StreamReader reader = new StreamReader(stream))
                {
                    return reader.ReadToEnd();
                }
            }
        }
 
 
        static HtmlReportListener()
        {
            templateStr = ReadEmbeddedResource("AddInPlugin.html_report_template.txt");
        }
 
        public HtmlReportListener(string name) : base(name)
        {
 
        }
 
        public override IResultListener CreateChild()
        {
            var res = new HtmlReportListener($"{Name}_Child")
            {
                RootPlanRun = this.RootPlanRun
            };
 
            if (this.Root == null)
            {
                res.Root = this;
            }
            else
            {
                res.Root = this.Root;
            }
            return res;
        }
 
        private void WriteReport()
        {
            string file = Path.Combine(StationSettings.Current.ReportPath, $"{CurrentPlanRun.TestPlanName}_{CurrentPlanRun.StartTime.ToString("yyyyMMddHHmmssfff")}.html");
            var template = Template.Parse(templateStr);
            report.CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
 
            var context = new TemplateContext();
            context.LoopLimit = 0;
            var scriptObject = new ScriptObject();
            scriptObject.Import(report);
            context.PushGlobal(scriptObject);
            var result = template.Render(context);
            File.WriteAllText(file, result);
        }
 
        protected override void PlanStarted()
        {
            lock (this)
            {
                report = new TestReport
                {
                    Name = $"{CurrentPlanRun.TestPlanName} 测试报告",
                    StartTime = $"开始时间:{CurrentPlanRun.StartTime.ToString("yyyy-MM-dd HH:mm:ss.fff")}",
                    Verdict = CurrentPlanRun.Verdict,
                    EndTime = "-"
                };
            }
        }
 
        protected override void StepComplated(TestStepRun stepRun)
        {
            lock (this)
            {
                if (stepRun.Report != null)
                {
                    var reportData = new ReportData
                    {
                        Name = stepRun.TestStepPath,
                        StartTime = $"开始时间:{stepRun.Report.StartTime.ToString("yyyy-MM-dd HH:mm:ss.fff")}",
                        EndTime = $"开始时间:{stepRun.Report.EndTime.ToString("yyyy-MM-dd HH:mm:ss.fff")}",
                        Consuming = $"耗时:{(stepRun.Report.EndTime - stepRun.Report.StartTime).TotalSeconds:N2}s",
                        Verdict = stepRun.Verdict,
                        Parameters = stepRun.Report.Details
                    };
                    report.Steps.Add(reportData);
                    WriteReport();
                }
            }
        }
 
        protected override void PlanComplated()
        {
            lock (this)
            {
                report.Verdict = CurrentPlanRun.Verdict;
                report.EndTime = $"结束时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}";
                WriteReport();
            }
        }
    }
}