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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
Ë
½SðhÆJã ó—dZddlmZddlZddlZddlZddlZddlZddlZddl    m
Z
m Z m Z m Z ddlmZdgej"d<dej"d<    ddlZ    ddlZ    ddlZej0d    «ddlmZ    dd
lmZdd lmZGd „d «ZGd„d«Zedk(r·edd¬«Z ej «Z!ddl"Z"e#dd«D]mZ$e!e$dzzZ%e&de"jNdd««Z(e"jD«dkDrdndZ)e)dk(rdndZ*e jWe$e%e)e(e"jXdd«e*¬«Œoe j[dgd ¢¬!«Z.e/d"e.«yy#e$rdZYŒ
wxYw#e$rdZYŒwxYw#e$rdZYŒwxYw#e$rdZYŒwxYw)#u"
压测报告生成器(中文报告)
 
依赖:
  - numpy
  - pandas (可选,用于更方便的表格导出)
  - matplotlib (用于绘图)
  - python-docx (可选,用于生成 Word æ–‡æ¡£)
 
使用场景:在你的压测脚本中,逐条调用 `recorder.record_result(...)` æˆ–者在压测结束后把结果一次性传入 `bulk_record`,
然后调用 `generate_report(output_dir, formats=['html','docx','json','csv'])`。
 
输出:HTML æŠ¥å‘Šï¼ˆå«ç»Ÿè®¡ä¸Žå›¾è¡¨ï¼‰ã€å¯é€‰çš„ Word æŠ¥å‘Šã€JSON/CSV æ˜Žç»†æ–‡ä»¶å’Œå›¾åƒæ–‡ä»¶ã€‚
 
é)Ú annotationsN)ÚListÚOptionalÚDictÚAnyÚSimHeizfont.sans-serifFzaxes.unicode_minusÚAgg)ÚDocument)ÚInchescó.—eZdZdZ    d                    dd„Zdd„Zy)Ú RequestRecordu!单条请求记录数据结构。Ncón—||_||_||_||_||_||_|xsi|_y)N©ÚindexÚ    timestampÚ status_codeÚ
latency_msÚ response_sizeÚerrorÚextra)Úselfrrrrrrrs        õ;H:\项目\造数脚本\Util\stress_test_report_generator.pyÚ__init__zRequestRecord.__init__8s9€àˆŒ
Ø"ˆŒØ&ˆÔØ$ˆŒØ*ˆÔ؈Œ
Ø’[˜bˆ
ócó—|j|jtjj|j«j    dd¬«|j
|j |j|jdœ|jxsi¥S)Nú Úseconds)ÚsepÚtimespec)rrÚdatetimerrrr)
rrr Ú fromtimestampÚ    isoformatrrrrr)rs rÚto_dictzRequestRecord.to_dictBsw€à—Z‘ZØŸ™Ü ×)Ñ)×7Ñ7¸¿¹ÓG×QÑQÐVYÐdmÐQÓnØ×+Ñ+ØŸ/™/Ø!×/Ñ/Ø—Z‘Zñ    
ðz‰zÒ˜Rð    
ð        
r©NNN©rÚintrÚfloatrr&rr'rz Optional[int]rú Optional[str]rzOptional[Dict]©ÚreturnúDict[str, Any])Ú__name__Ú
__module__Ú __qualname__Ú__doc__rr#©rrr r 5s.„Ù+ðlpð!Ø -ð!Ø=Jð!ØZhó!ô
 
rr cób—eZdZdZd d d„Z    d                     dd„Zdd„Zdd„Zdd„Zddd„Z    dd    „Z
dd
„Z y)ÚLoadTestReportGeneratoruE压测报告生成器。将请求结果记录并生成中文报告。NcóX—||_|xs|›d|_g|_d|_d|_y)Nu æŠ¥å‘Š)Ú    test_nameÚ report_titleÚrecordsÚ _started_atÚ    _ended_at)rr4r5s   rrz LoadTestReportGenerator.__init__Rs3€Ø"ˆŒØ(ÒA¨y¨k¸Ð,AˆÔØ,.ˆŒ Ø,0ˆÔØ*.ˆrc    óæ—t|||||||«}|jj|«|j||jkr||_|j||jkDr||_yy)uC记录单条请求结果。timestamp ä¸º unix æ—¶é—´æˆ³ï¼ˆç§’)。N)r r6Úappendr7r8)    rrrrrrrrÚrecs             rÚ record_resultz%LoadTestReportGenerator.record_resultZsq€ô˜E 9¨k¸:À}ÐV[Ð]bÓcˆØ  ‰ ×јCÔ Ø × Ñ Ð # y°4×3CÑ3CÒ'CØ(ˆDÔ Ø >‰>Ð ! Y°·±Ò%?Ø&ˆDNð&@rc óR—|D]¢}|j|jdt|j«dz«|dt    |jdd««t |jdd««|jd«|jd«|jd    «¬
«Œ¤y ) uo一次性批量导入结果。每一项是 dict,需包含 index,timestamp,status_code,latency_ms ç­‰å­—段。rérrrrrrrrN)r<ÚgetÚlenr6r&r')rÚresultsÚrs   rÚ bulk_recordz#LoadTestReportGenerator.bulk_recordds€àò        ˆAØ × Ñ Ø—e‘e˜G¤S¨¯©Ó%6¸Ñ%:Ó;ؘK™.Ü §¡ m°QÓ 7Ó8Ü  §¡ |°QÓ!7Ó8ØŸe™e OÓ4Ø—e‘e˜G“nØ—e‘e˜G“nð õ ñ        rcó—|jsiS|jDcgc]}|j€Œ|j‘Œ}}|jDcgc]}|j‘Œ}}|jDcgc]}|jsŒ|‘Œ}}t    |j«}t d„|D««}||z
}|j r>|jr2|j|j kDr|j|j z
nd}|r t|«nd}|dkDr||z nd}    tr|rttj|d««nd}
|rttj|d««nd} |rttj|d««nd} |rttj|d««nd} n2t|«}d„}||d«}
||d«} ||d«} ||d«} i}|D]}|j|d«d    z||<Œi}|jD]/}t|j«}|j|d«d    z||<Œ1i}|D]A}|jr |jnd
|j›}|j|d«d    z||<ŒC||||r||z nd||    |r t|«nd|r t!|«nd|rt#j$|«nd|
| | | d œ||tt'|j)«««d œ
}|Scc}wcc}wcc}w) Nc3ó>K—|]}d|cxkrdksŒnnd–—Œy­w)éÈi,r>Nr0)Ú.0Úss  rú    <genexpr>z8LoadTestReportGenerator.compute_stats.<locals>.<genexpr>{sèø€ÒB !°3¸!´>¸c¶>œAÑBùs‚“
gré2éZé_éccó—|syt|«dz
|dz z}tj|«}tj|«}||k(r|t    |«S|t    |«||z
z}|t    |«||z
z}||zS)Nrr>éd)r@ÚmathÚfloorÚceilr&)ÚlstÚqÚkÚfÚcÚd0Úd1s       rÚ
percentilez9LoadTestReportGenerator.compute_stats.<locals>.percentile‹s‚€ÙØÜ˜“X˜a‘Z A c¡EÑ*Ü—J‘J˜q“MÜ—I‘I˜a“LØ˜’6Øœs 1›v™;Ð&Øœ˜Q›‘[ A a¡CÑ(Øœ˜Q›‘[ A a¡CÑ(Ø˜B‘wrr>Ústatus_)ÚminÚmaxÚavgÚmedianÚp90Úp95Úp99)
Útotal_requestsÚ success_countÚ
fail_countÚ success_rateÚduration_secondsÚthroughput_rpsrÚ status_groupsÚ error_summaryÚ
rps_series)r6rrrr@Úsumr7r8r'ÚnprZÚsortedr?r&rr\r]Ú
statisticsÚmeanÚlistÚitems)rrBÚ    latenciesÚstatusesÚerrorsÚtotalrdreÚdurationÚ
throughputÚp50r`rarbÚ
lat_sortedrZrirHrkÚsecrjÚkeyÚstatss                       rÚ compute_statsz%LoadTestReportGenerator.compute_statsrsô€Ø|Š|؈Ià+/¯<©<ÖT a¸1¿<¹<Ñ;SQ—\“\ÐTˆ    ÐTØ+/¯<©<Ö8 aA—M“MÐ8ˆÐ8Ø!Ÿ\™\Ö5˜¨Q¯W«W’!Ð5ˆÐ5äD—L‘LÓ!ˆÜÑB xÔBÓBˆ ؘ]Ñ*ˆ
à;?×;KÒ;KÐPT×P^ÒP^Ðcg×cqÑcqÐtx÷uEñuEòdED—N‘N T×%5Ñ%5Ò5ðLPˆÙ&.”5˜”?°Cˆà+3°aª<e˜hÒ&¸Sˆ
õ Ù9B”%œŸ ™  i°Ó4Ô5ȈCÙ9B”%œŸ ™  i°Ó4Ô5ȈCÙ9B”%œŸ ™  i°Ó4Ô5ȈCÙ9B”%œŸ ™  i°Ó4Ô5ȉCä     Ó*ˆJò
ñ˜Z¨Ó,ˆCÙ˜Z¨Ó,ˆCÙ˜Z¨Ó,ˆCÙ˜Z¨Ó,ˆCà(*ˆ Øò    ;ˆAØ,×0Ñ0°°AÓ6¸Ñ:ˆM˜!Ò ð    ;ðˆ
Ø—‘ò    9ˆAܐa—k‘kÓ"ˆCØ(Ÿn™n¨S°!Ó4°qÑ8ˆJsŠOð    9ð
)+ˆ Øò    ?ˆAØŸWšW!—'’'¨G°A·M±M°?Ð*CˆCØ!.×!2Ñ!2°3¸Ó!:¸QÑ!>ˆM˜#Ò ð    ?ð
$Ø*Ø$Ù5:˜M¨EÒ1ÀØ (Ø(á)2”s˜9”~¸Ù)2”s˜9”~¸Ù5>”z—‘ yÔ1ÀAØØØØñð+Ø*Ü ¤ j×&6Ñ&6Ó&8Ó!9Ó:ñ%
ˆð(ˆ ùòSUùÚ8ùÚ5sK8¯K8Á K=Á0LÂLcór—tjj|«stj|d¬«yy)NT)Úexist_ok)ÚosÚpathÚexistsÚmakedirs)rr‚s  rÚ _ensure_dirz#LoadTestReportGenerator._ensure_dirÂs%€Üw‰w~‰~˜dÔ#Ü K‰K˜ tÖ ,ð$rc    ó> —|xsddg}|j|«|j«}tjj«j    d«}|j
j dd«›d|›}i}d|vrtjj||dz«}t|dd¬    «5}tj||jD    cgc]}    |    j«‘Œc}    d
œ|d d ¬ «ddd«||d<d|vr tjj||dz«}
trPtj |jD    cgc]}    |    j«‘Œc}    «} | j#|
d d¬«n¢ddl} t|
ddd¬«5}| j'|t)|jdj«j+««¬«} | j-«|jD]!}    | j/|    j««Œ#    ddd«|
|d<i}t0r8    |jD    cgc]}    |    j2€Œ|    j2‘Œ}}    |rÏt1j4«t1j6|d¬«t1j8d«t1j:d«t1j<d«tjj||dz«}t1j>«t1j@|«t1jB«||d<|jD    cgc]}    tE|    jF«‘Œ}}    |rddl$m%}||«}tM|j+««}|Dcgc]}||‘Œ    }}t1j4«t1jN||«t1j8d«t1j:d «t1j<d!«tjj||d"z«}t1j>«t1j@|«t1jB«||d#<||d%<d|vrbtjj||d&z«}|jU||«}t|dd¬    «5}|jW|«ddd«||d<d'|vrDtXr>    tjj||d(z«}|j[|||«||d'<|S|Scc}    w#1swYŒ/xYwcc}    w#1swYŒxYwcc}    wcc}    wcc}w#tP$r}tSd$|«Yd}~Œd}~wwxYw#1swYŒ®xYw#tP$r}tSd)|«Yd}~|Sd}~wwxYw)*u
        ç”ŸæˆæŠ¥å‘Šã€‚
        formats: åˆ—表,支持 'html','docx','json','csv'。
        è¿”回生成的文件路径字典。
        ÚhtmlÚjsonz %Y%m%d_%H%M%SrÚ_z .summary.jsonÚwzutf-8)Úencoding)r}r6Fé)Ú ensure_asciiÚindentNÚcsvz .details.csvz    utf-8-sig)rr‹rÚ)Únewliner‹)Ú
fieldnamesrJ)Úbinsu响应时间分布 (ms)u 延迟 (ms)u 请求数量z_latency_hist.pngÚ latency_hist)ÚCounteru每秒请求数 (RPS)uUnix ç§’u    è¯·æ±‚æ•°z_rps.pngÚrpsu生成图表时出错:Úchartsz.htmlÚdocxz.docxu生成 docx æŠ¥å‘Šæ—¶å‡ºé”™ï¼š).r…r~r ÚnowÚstrftimer4Úreplacerr‚ÚjoinÚopenrˆÚdumpr6r#ÚpdÚ    DataFrameÚto_csvrÚ
DictWriterrqÚkeysÚ writeheaderÚwriterowÚpltrÚfigureÚhistÚtitleÚxlabelÚylabelÚ tight_layoutÚsavefigÚcloser&rÚ collectionsr•rnÚplotÚ    ExceptionÚprintÚ_build_html_reportÚwriter
Ú_build_docx_report)rÚ
output_dirÚformatsr}Ú timestamp_strÚ    base_nameÚoutputsÚ    json_pathrVrBÚcsv_pathÚdfrÚwriterr—rsÚ    hist_pathÚtimesr•ÚcntÚxsÚxÚysÚrps_pathÚeÚ    html_pathÚ html_contentÚ    docx_paths                            rÚgenerate_reportz'LoadTestReportGenerator.generate_reportÆs €ð Ò-˜f fÐ-ˆØ ×јÔ$à×"Ñ"Ó$ˆÜ ×)Ñ)×-Ñ-Ó/×8Ñ8¸ÓIˆ Ø—~‘~×-Ñ-¨c°3Ó7Ð8¸¸-¸ÐIˆ    àˆð WÑ ÜŸ™Ÿ ™  Z°¸_Ñ1LÓMˆIܐi ¨wÔ7ð }¸1Ü—    ‘     EÈDÏLÉLÖ6YÀq°q·y±yµ{Ò6YÑZÐ\]ÐlqÐz{Õ|÷ }à'ˆGF‰Oð GÒ Ü—w‘w—|‘| J°    ¸NÑ0JÓKˆHÝÜ—\‘\¸¿ ¹ Ö"E°1 1§9¡9¥;Ò"EÓFØ—    ‘    ˜(¨%¸+    ÕFóܘ( C°¸gÔFð5È!Ø Ÿ^™^¨A¼$¸t¿|¹|ÈA¹×?VÑ?VÓ?X×?]Ñ?]Ó?_Ó:`˜^ÓaFØ×&Ñ&Ô(Ø!Ÿ\™\ò5˜ØŸ™¨¯    ©    « Õ4ñ5÷5ð
&ˆGE‰NðˆÞ ð! 5à37·<±<Ö\¨aÀ1Ç<Á<ÑC[˜QŸ\›\Ð\    Ð\ÙÜ—J‘J”LÜ—H‘H˜Y¨RÕ0Ü—I‘IÐ7Ô8Ü—J‘J˜}Ô-Ü—J‘J˜~Ô.Ü "§¡§ ¡ ¨Z¸ÐEXÑ9XÓ YIÜ×$Ñ$Ô&Ü—K‘K     Ô*Ü—I‘I”KØ-6F˜>Ñ*ð48·<±<Ö@¨aœ˜QŸ[™[Õ)Ð@Ð@ÚÝ3Ù! %›.CÜ §¡£
Ó+BØ*,Ö- Q˜#˜a›&Ð-BÐ-Ü—J‘J”LÜ—H‘H˜R Ô$Ü—I‘IÐ5Ô6Ü—J‘J˜zÔ*Ü—J‘J˜{Ô+Ü!Ÿw™wŸ|™|¨J¸    ÀJÑ8NÓOHÜ×$Ñ$Ô&Ü—K‘K Ô)Ü—I‘I”KØ$,F˜5‘Mð#ˆÑð WÑ ÜŸ™Ÿ ™  Z°¸WÑ1DÓEˆIØ×2Ñ2°5¸&ÓAˆLܐi ¨wÔ7ð &¸1Ø—‘˜ Ô%÷ &à'ˆGF‰Oð WÑ ¥ð ;ÜŸG™GŸL™L¨°YÀÑ5HÓI    Ø×'Ñ'¨¨v°yÔAØ"+˜‘ðˆˆwˆùòY7Z÷ }ñ }üò#F÷
5ñ5üò]ùòAùò
.øôò 5ÜÐ0°!×4Ò4ûð 5ú÷ &ð &ûôò ;ÜÐ6¸×:Ð:àˆûð ;úsŸÂ/TÃT Ã% TÅ
T,ÆBT1È.U È<T>ÉT>ÉC!U Ì=UÍ0U Π    UÎCU Ò1U0Ó;U<ÔTÔT)Ô1T;Ô>U Õ     U-Õ U(Õ(U-Õ0U9Õ<    VÖ VÖVcó —|j}tjj«jd«}d|›d|›d|j    dd«›d|j    dd«›d    |j    d
d«›d |j    d d«d ›d|j    dd«d›d|j    dd«d›d}|j    di«}d|j    dd«d›d|j    dd«d›d|j    dd«d›d|j    dd«d›d|j    dd«d›d|j    d d«d›d!|j    d"d«d›d}d#}|j    d$i«j «D]\}    }
|d%|    ›d&|
›d'z }Œ|d(z }d)} |j    d*«r?| d+z } |j    d*i«j «D]\}    }
| d%|    ›d&|
›d'z } Œ| d(z } n| d,z } d-} |j «D]1\} }| d.| ›d/t jj|«›d0| ›d1z } Œ3|jdd2Dcgc]}|j«‘Œ}}d3j|Dcgc]-}d4|d5›d6|d7›d6|d8›d6|d›d6|d9›d6|d:xsd3›d; ‘Œ/c}«}d<|›d=}d>|›d?|›d@|›dA|›dA|›dA| ›dA| ›dA|›dB}|Scc}wcc}w)CNú%Y-%m-%d %H:%M:%SuC
        <h2>摘要</h2>
        <ul>
          <li>报告名称:u#</li>
          <li>生成时间:u#</li>
          <li>总请求数:rcru </li>
          <li>成功数:rdu,失败数:reu,成功率:rfú.2%u)</li>
          <li>总耗时(秒):rgú.2fu.</li>
          <li>平均吞吐(req/s):rhz</li>
        </ul>
        ruN
        <h2>响应时间统计 (ms)</h2>
        <ul>
          <li>最小:r\u</li>
          <li>最大:r]u</li>
          <li>平均:r^u%</li>
          <li>中位数(P50):r_u</li>
          <li>P90:r`u    ï¼ŒP95:rau    ï¼ŒP99:rbu<h2>状态码分布</h2><ul>riz<li>ú: z</li>z</ul>u<h2>错误汇总</h2>rjz<ul>u<p>无错误记录</p>u<h2>图表</h2>z    <div><h3>z</h3><img src="z" alt="z-" style="max-width:100%;height:auto;"/></div>rOrz<tr><td>rz    </td><td>r rrrz
</td></tr>uò
        <h2>请求明细(仅显示前100条)</h2>
        <table border="1" cellpadding="4" cellspacing="0">
          <tr><th>#</th><th>时间</th><th>状态码</th><th>延迟(ms)</th><th>响应大小</th><th>错误</th></tr>
          z
        </table>
        zv
        <!doctype html>
        <html lang="zh-CN">
        <head>
          <meta charset="utf-8">
          <title>a]</title>
          <style>
            body{font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial; padding:20px}
            h2{color:#2c3e50}
            table{border-collapse:collapse; width:100%}
            th,td{padding:6px; text-align:left}
          </style>
        </head>
        <body>
          <h1>z</h1>
          z
          u
          <p>注:如需查看所有请求明细,请下载同目录下的 CSV/JSON æ–‡ä»¶ã€‚</p>
        </body>
        </html>
        ) r5r r™ršr?rrrr‚Úbasenamer6r#rœ)rr}r—r©r™Ú summary_htmlÚlatencyÚ latency_htmlÚ status_htmlrUÚvÚ
error_htmlÚ charts_htmlÚnamer‚rBÚdetailsÚdÚ detail_rowsÚ details_htmlr‡s                     rr³z*LoadTestReportGenerator._build_html_report'sS€à×!Ñ!ˆÜ×Ñ×#Ñ#Ó%×.Ñ.Ð/BÓCˆðð$˜Wð%Ø!˜Uð#Ø#Ÿi™iÐ(8¸!Ó<Ð=ð>Ø Ÿ9™9 _°QÓ7Ð8¸ÈÏ    É    ÐR^Ð_`ÓHaÐGbÐbqÐrw×r{Ñr{ð}KðLMósNðORðrSðS$Ø$)§I¡IÐ.@ÀÓ$CÀCÐ#HðI)Ø).¯©Ð3CÀAÓ)FÀsÐ(KðL    ð
 ˆ ð—)‘)˜L¨"Ó-ˆðð Ÿ ™  E¨!Ó,¨SÐ1ð2ØŸ ™  E¨!Ó,¨SÐ1ð2ØŸ ™  E¨!Ó,¨SÐ1ð2 Ø '§ ¡ ¨H°QÓ 7¸Ð<ð=Ø—[‘[  qÓ)¨#Ð.¨i¸¿ ¹ ÀEÈ!Ó8LÈSÐ7QÐQZÐ[b×[fÑ[fÐglÐmnÓ[oÐpsÐZtðu    ð     ˆ ð5ˆ Ø—I‘I˜o¨rÓ2×8Ñ8Ó:ò    0‰DˆAˆqØ ˜T !  B q c¨Ð/Ñ /‰Kð    0àwш à,ˆ
Ø 9‰9_Ô %Ø ˜&Ñ  ˆJØŸ    ™     /°2Ó6×<Ñ<Ó>ò 3‘1Ø  Q C r¨!¨¨EÐ2Ñ2‘
ð 3à ˜'Ñ !‰Jà Ð2Ñ 2ˆJà'ˆ Ø Ÿ,™,›.ò    O‰JˆD$Ø ˜Y t f¨O¼B¿G¹G×<LÑ<LÈTÓ<RÐ;SÐSZÐ[_ÐZ`ðaNðOñ O‰Kð    Oð)-¯ © °T°cÐ(:Ö; 11—9‘9•;Ð;ˆÐ;Ø—g‘gðPWöXðKL ¨!¨G©*¨°Y¸qÀ¹}¸oÈYÐWXÐYfÑWgÐVhÐhqÐrsðuAñsBðrCðCLðMNðO^ñM_ðL`ð`iðjkðlsñjtòjzðxzði{ð{Eò FòXóYˆ ð ð ˆ-ð    ð     ˆ ðð
ð    ðˆgð Ø ˆ.ð Ø ˆ.ð Ø ˆ-ð Ø ˆ,ð Ø ˆ-ð Ø ˆ.ð    ð) ˆð6ˆ ùòK<ùòXs ÉKÉ*2K c ó0    —ts td«‚t«}|j|jd¬«|j    dt
j
j «jd«›«|jdd¬«|j    d|jd    d
«›d |jd d
«›d |jdd
«›d|jdd
«d›«|j    d|jdd
«d›d|jdd
«d›«|jdd¬«|jdi«}|j    d|jdd
«d›d|jdd
«d›d|jdd
«d›«|j    d|jd d
«d›d!|jd"d
«d›d#|jd$d
«d›d%|jd&d
«d›«|jd'd¬«|jd(i«j«D]\}}|j    |›d)|›«Œ|jd*d¬«|jd+«r?|jd+i«j«D]\}}|j    |›d)|›«Œn|j    d,«|j«D]U\}}    tjj|    «sŒ&|j|d¬«    |j|    td-«¬.«ŒW|jd0d¬«|j!dd-¬1«}
|
j"d
j$} d2| d
_d3| d_d4| d_d5| d6_d7| d8_d9| d:_|j(dd;D]³} |
j+«j$} | j-«}t/|d<«| d
_|d=| d_t/|d>«| d_|d›| d6_t/|jd?d@««| d8_|jdA«xsd@| d:_Œµ|j1|«y#t$r|j    d/|    ›«YŒÊwxYw)BNu-缺少 python-docx åº“,无法生成 docx。r>)Úlevelu生成时间:rÌu摘要rŒu总请求数:rcru   æˆåŠŸï¼šrdu   å¤±è´¥ï¼šreu  æˆåŠŸçŽ‡ï¼šrfrÍu总耗时(秒):rgrÎu  å¹³å‡åžå(req/s):rhu响应时间统计 (ms)ru    æœ€å°ï¼šr\u   æœ€å¤§ï¼šr]u   å¹³å‡ï¼šr^uP50:r_u  P90:r`u  P95:rau  P99:rbu状态码分布rirÏu 错误汇总rju无错误记录é)Úwidthu无法插入图片:u请求明细(前100条))ÚrowsÚcolsú#u时间u    çŠ¶æ€ç u
延迟(ms)éu 响应大小éu错误érOrr rrrr)r
Ú RuntimeErrorÚ add_headingr5Ú add_paragraphr r™ršr?rrrr‚rƒÚ add_picturer r±Ú    add_tableráÚcellsÚtextr6Úadd_rowr#ÚstrÚsave)rr}r—rÉÚdocÚlatrUrÕrØr‚ÚtableÚ    hdr_cellsrBÚ    row_cellsrÚs               rrµz*LoadTestReportGenerator._build_docx_report}s    €ÝÜÐNÓOÐ OÜ‹jˆØ ‰˜×)Ñ)°ˆÔ3Ø ×јO¬H×,=Ñ,=×,AÑ,AÓ,C×,LÑ,LÐM`Ó,aÐ+bÐcÔdà ‰˜¨ˆÔ*Ø ×јO¨E¯I©IÐ6FÀqÓ,IÐ+JÈ+ÐV[×V_ÑV_Ð`oÐpqÓVrÐUsÐs~ð@E÷@Iñ@IðJVðWXó@YðZðZhðin÷irñirðsAðBCóiDðEHðhIðJô    KØ ×ÑÐ-¨e¯i©iÐ8JÈ1Ó.MÈcÐ-RÐRjÐkp×ktÑktðvFðGHólIðJMðkNðOô    Pà ‰Ð1¸ˆÔ;؏i‰i˜  bÓ)ˆØ ×јI c§g¡g¨e°AÓ&6°sÐ%;¸;ÀsÇwÁwÈuÐUVÓGWÐX[ÐF\Ð\gÐhk×hoÑhoÐpuÐvwÓhxÐy|Ðg}Ð~ÔØ ×јF 3§7¡7¨8°AÓ#6°sÐ";¸8ÀCÇGÁGÈEÐRSÓDTÐUXÐCYÐYaÐbe×biÑbiÐjoÐpqÓbrÐsvÐawÐwðAD÷AHñAHðINðOPóAQðRUð@VðWô    Xà ‰Ð)°ˆÔ3Ø—I‘I˜o¨rÓ2×8Ñ8Ó:ò    +‰DˆAˆqØ × Ñ    2 a S˜kÕ *ð    +ð     ‰˜¨aˆÔ0Ø 9‰9_Ô %ØŸ    ™     /°2Ó6×<Ñ<Ó>ò /‘1Ø×!Ñ! Q C r¨!¨ +Õ.ñ /ð × Ñ Ð/Ô 0ð!Ÿ,™,›.ò    F‰JˆD$܏w‰w~‰~˜dÕ#Ø—‘ ¨AÔ.ðFØ—O‘O D´°q³    OÕ:ð        Fð     ‰Ð5¸QˆÔ?Ø— ‘  1¨1 Ó-ˆØ—J‘J˜q‘M×'Ñ'ˆ    Øˆ    !‰ ÔØ$ˆ    !‰ ÔØ'ˆ    !‰ ÔØ(ˆ    !‰ ÔØ*ˆ    !‰ ÔØ$ˆ    !‰ Ôà—‘˜d˜sÐ#ò    5ˆAØŸ ™ ›×-Ñ-ˆIØ—    ‘    “ ˆAÜ # A g¡J£ˆIa‰LÔ Ø ! *¡ ˆIa‰LÔ Ü # A mÑ$4Ó 5ˆIa‰LÔ Ø#$ \¡?Ð"3ˆIa‰LÔ Ü # A§E¡E¨/¸2Ó$>Ó ?ˆIa‰LÔ Ø !§¡ g£Ò 4°"ˆIa‰LÕ ð    5ð     ‰Õøô1!òFØ×%Ñ%Ð(=¸d¸VÐ&D×EðFúsÌQ4Ñ4RÒR)u 压测任务N)r4rïr5r(r$r%)rAzList[Dict[str, Any]]r))r‚rï)z./load_test_reportN)r¶rïr·zOptional[List[str]])r}r+r—úDict[str, str]r*rï)r}r+r—rörÉrï) r,r-r.r/rr<rCr~r…rÊr³rµr0rrr2r2OsR„ÙOô/ðquð'Ø%2ð'ØBOð'Ø_mó'ó óMó`-ô_óBTôl9rr2Ú__main__u 示例压测u示例压测详细报告)r4r5r>éerægð?rFrJgš™™™™™©?iôz500 Internal Server Erroriˆ)rrz./example_report)r‡rˆrr˜)r·u已生成报告:)0r/Ú
__future__rrrˆrPÚtimeror ÚtypingrrrrÚmatplotlib.pyplotÚpyplotr¦ÚrcParamsÚnumpyrmr±ÚpandasrŸÚ
matplotlibÚuser˜r
Ú docx.sharedr r r2r,Úgenr™ÚrandomÚrangeÚiÚtsr]ÚgaussròÚstatusÚerrr<ÚrandintrÊrºr²r0rrú<module>r sÆðñõ #Û    Û Û Û ÛÛß,Ó,ÝØ#+ *€‡  Ð ÑØ%*€‡  Ð !Ñ"ðÛðÛðÛØ€J‡NN5ÔÝ#ðÝÝ"÷
 
ñ
÷4gñgðV  ˆzÒá
!¨NÐIcÔ
d€CØ
ˆ$)‰)‹+€CãÙ 1c‹]òbˆØ A˜‘F‰^ˆÙ#|v—|‘| C¨Ó,Ó-ˆØ%˜Ÿ ™ ›¨$Ò.‘°CˆØ ’m‰dÐ)DˆØ ×ј!˜R ¨¸N¸F¿N¹NÈ3ÐPTÓ<UÐ]`ÐÕað bð×!Ñ!Ð"4Ò>]Ð!Ó^€GÙ    Ð
 Õ(ðøðw òØ     ƒBðûð
òØ     ƒBðûðòØ
ƒCðûð ò؃HðúsHÁEÁE%ÁE3Á: FÅE"Å!E"Å%E0Å/E0Å3E>Å=E>ÆF Æ F