Selenium3+python自动化011-unittest生成测试报告(HTMLTestRunner)

批量执行完用例后,生成的测试报告是文本形式的,不够直观,为了更好的展示测试报告,最好是生成HTML格式的。

unittest里面是不能生成html格式报告的,需要导入一个第三方的模块:HTMLTestRunner

 

一、导入HTMLTestRunner

1.这个模块下载不能通过pip安装了,只能下载后手动导入,下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html

2.Download下HTMLTestRunner.py文件就是我们需要下载的包。

3.下载后手动拖到python安装文件的Lib目录下

4.验证安装成功 执行 import HTMLTestRunner 没有报错证明配置成功。

报告路径

 1 # encoding = utf - 8
 2 import unittest
 3 import sys
 4 import HTMLTestRunner
 5 import time
 6 import os
 7 
 8 #被测试类
 9 class myclass(object):
10     """classmethod 修饰符对应的函数不需要实例化,
11     不需要 self 参数,但第一个参数需要是表示自身
12     类的 cls 参数,可以来调用类的属性,类的方法,
13     实例化对象等。"""
14     @classmethod
15     def sum(cls,a,b):
16         return a + b   #将两个传入参数进行相加操作
17     @classmethod
18     def sub(cls, a, b):
19         return a - b   #将两个传入参数进行相减操作
20 
21 class mytest(unittest.TestCase):
22     # @classmethod
23     # def setUpClass(cls):
24     #     """初始化类固件"""
25     #     print("-----setUpClass")
26 
27     # @classmethod
28     # def tearDownClass(cls):
29     #     """重构类固件"""
30     #     print("--tearDownClas")
31 
32     #初始化工作
33     def setUp(self):
34         self.a = 3
35         self.b = 1
36         print("--setUp")
37 
38     #退出清理工作
39     def tearDown(self):
40         print("--tearDown")
41 
42     #具体的测试用例,一定要以test开头
43     def test1sum(self):
44         # res=3/0 抛出异常,执行结果为F
45         #断言两数之和的结果是否是4
46         res=myclass.sum(self.a,self.b)
47         self.assertEqual(res,4,'test sum fail')
48         print('testsum方法')
49 
50     def testsub(self):
51         #断言两数之差的结果是否是2
52         self.assertEqual(myclass.sub(self.a,self.b),2,'test sub fail')
53         print('testsub方法')
54 
55 
56 class aa(unittest.TestCase):
57     # num=2
58     # @unittest.skip('skipping')
59     # @unittest.skipIf(num>1,'num已经大于1')
60     @unittest.skipUnless(sys.platform == "linux", "requires linux")
61     def testaa(self):
62         print('testaa')
63 
64 
65 if __name__ == '__main__':
66     testCase = unittest.TestLoader().loadTestsFromTestCase(mytest)
67     #将多个测试类加载到测试集合中
68     suite = unittest.TestSuite([testCase])
69     # 创建时间
70     cur_time = time.strftime('%Y-%m-%d_%H_%M_%S')
71     # 文件路径
72     filename = os.path.dirname(os.path.abspath('.'))+'\report\'+cur_time+'.html'
73     print("===================================")
74     print("当前文件路径是:",os.path.abspath('.'))
75     print("===================================")
76     print("当前文件路径的上一级文件路径是:",os.path.dirname(os.path.abspath('.')))
77     # 写入一个文件
78     f = open(filename,"wb")
79     # 报告详情
80     runner = HTMLTestRunner.HTMLTestRunner(stream=f,title="测试报告",description='测试报告描述')
81     runner.run(suite)
82 
83     # 原始版本
84     # f = open("./report.html","wb")
85     # runner = HTMLTestRunner.HTMLTestRunner(stream=f,title="测试报告",description="测试报告描述")
86     # runner.run(suite)
View Code
  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3 <html xmlns="http://www.w3.org/1999/xhtml">
  4 <head>
  5     <title>测试报告</title>
  6     <meta name="generator" content="HTMLTestRunner 0.8.2"/>
  7     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  8     
  9 <style type="text/css" media="screen">
 10 body        { font-family: verdana, arial, helvetica, sans-serif; font-size: 80%; }
 11 table       { font-size: 100%; }
 12 pre         { }
 13 
 14 /* -- heading ---------------------------------------------------------------------- */
 15 h1 {
 16     font-size: 16pt;
 17     color: gray;
 18 }
 19 .heading {
 20     margin-top: 0ex;
 21     margin-bottom: 1ex;
 22 }
 23 
 24 .heading .attribute {
 25     margin-top: 1ex;
 26     margin-bottom: 0;
 27 }
 28 
 29 .heading .description {
 30     margin-top: 4ex;
 31     margin-bottom: 6ex;
 32 }
 33 
 34 /* -- css div popup ------------------------------------------------------------------------ */
 35 a.popup_link {
 36 }
 37 
 38 a.popup_link:hover {
 39     color: red;
 40 }
 41 
 42 .popup_window {
 43     display: none;
 44     position: relative;
 45     left: 0px;
 46     top: 0px;
 47     /*border: solid #627173 1px; */
 48     padding: 10px;
 49     background-color: #E6E6D6;
 50     font-family: "Lucida Console", "Courier New", Courier, monospace;
 51     text-align: left;
 52     font-size: 8pt;
 53     width: 500px;
 54 }
 55 
 56 }
 57 /* -- report ------------------------------------------------------------------------ */
 58 #show_detail_line {
 59     margin-top: 3ex;
 60     margin-bottom: 1ex;
 61 }
 62 #result_table {
 63     width: 80%;
 64     border-collapse: collapse;
 65     border: 1px solid #777;
 66 }
 67 #header_row {
 68     font-weight: bold;
 69     color: white;
 70     background-color: #777;
 71 }
 72 #result_table td {
 73     border: 1px solid #777;
 74     padding: 2px;
 75 }
 76 #total_row  { font-weight: bold; }
 77 .passClass  { background-color: #6c6; }
 78 .failClass  { background-color: #c60; }
 79 .errorClass { background-color: #c00; }
 80 .passCase   { color: #6c6; }
 81 .failCase   { color: #c60; font-weight: bold; }
 82 .errorCase  { color: #c00; font-weight: bold; }
 83 .hiddenRow  { display: none; }
 84 .testcase   { margin-left: 2em; }
 85 
 86 
 87 /* -- ending ---------------------------------------------------------------------- */
 88 #ending {
 89 }
 90 
 91 </style>
 92 
 93 </head>
 94 <body>
 95 <script language="javascript" type="text/javascript"><!--
 96 output_list = Array();
 97 
 98 /* level - 0:Summary; 1:Failed; 2:All */
 99 function showCase(level) {
100     trs = document.getElementsByTagName("tr");
101     for (var i = 0; i < trs.length; i++) {
102         tr = trs[i];
103         id = tr.id;
104         if (id.substr(0,2) == 'ft') {
105             if (level < 1) {
106                 tr.className = 'hiddenRow';
107             }
108             else {
109                 tr.className = '';
110             }
111         }
112         if (id.substr(0,2) == 'pt') {
113             if (level > 1) {
114                 tr.className = '';
115             }
116             else {
117                 tr.className = 'hiddenRow';
118             }
119         }
120     }
121 }
122 
123 
124 function showClassDetail(cid, count) {
125     var id_list = Array(count);
126     var toHide = 1;
127     for (var i = 0; i < count; i++) {
128         tid0 = 't' + cid.substr(1) + '.' + (i+1);
129         tid = 'f' + tid0;
130         tr = document.getElementById(tid);
131         if (!tr) {
132             tid = 'p' + tid0;
133             tr = document.getElementById(tid);
134         }
135         id_list[i] = tid;
136         if (tr.className) {
137             toHide = 0;
138         }
139     }
140     for (var i = 0; i < count; i++) {
141         tid = id_list[i];
142         if (toHide) {
143             document.getElementById('div_'+tid).style.display = 'none'
144             document.getElementById(tid).className = 'hiddenRow';
145         }
146         else {
147             document.getElementById(tid).className = '';
148         }
149     }
150 }
151 
152 
153 function showTestDetail(div_id){
154     var details_div = document.getElementById(div_id)
155     var displayState = details_div.style.display
156     // alert(displayState)
157     if (displayState != 'block' ) {
158         displayState = 'block'
159         details_div.style.display = 'block'
160     }
161     else {
162         details_div.style.display = 'none'
163     }
164 }
165 
166 
167 function html_escape(s) {
168     s = s.replace(/&/g,'&amp;');
169     s = s.replace(/</g,'&lt;');
170     s = s.replace(/>/g,'&gt;');
171     return s;
172 }
173 
174 /* obsoleted by detail in <div>
175 function showOutput(id, name) {
176     var w = window.open("", //url
177                     name,
178                     "resizable,scrollbars,status,width=800,height=450");
179     d = w.document;
180     d.write("<pre>");
181     d.write(html_escape(output_list[id]));
182     d.write("
");
183     d.write("<a href='javascript:window.close()'>close</a>
");
184     d.write("</pre>
");
185     d.close();
186 }
187 */
188 --></script>
189 
190 <div class='heading'>
191 <h1>测试报告</h1>
192 <p class='attribute'><strong>Start Time:</strong> 2019-07-01 23:11:41</p>
193 <p class='attribute'><strong>Duration:</strong> 0:00:00.001000</p>
194 <p class='attribute'><strong>Status:</strong> Pass 2</p>
195 
196 <p class='description'>测试报告描述</p>
197 </div>
198 
199 
200 
201 <p id='show_detail_line'>Show
202 <a href='javascript:showCase(0)'>Summary</a>
203 <a href='javascript:showCase(1)'>Failed</a>
204 <a href='javascript:showCase(2)'>All</a>
205 </p>
206 <table id='result_table'>
207 <colgroup>
208 <col align='left' />
209 <col align='right' />
210 <col align='right' />
211 <col align='right' />
212 <col align='right' />
213 <col align='right' />
214 </colgroup>
215 <tr id='header_row'>
216     <td>Test Group/Test case</td>
217     <td>Count</td>
218     <td>Pass</td>
219     <td>Fail</td>
220     <td>Error</td>
221     <td>View</td>
222 </tr>
223 
224 <tr class='passClass'>
225     <td>mytest</td>
226     <td>2</td>
227     <td>2</td>
228     <td>0</td>
229     <td>0</td>
230     <td><a href="javascript:showClassDetail('c1',2)">Detail</a></td>
231 </tr>
232 
233 <tr id='pt1.1' class='hiddenRow'>
234     <td class='none'><div class='testcase'>test1sum</div></td>
235     <td colspan='5' align='center'>
236 
237     <!--css div popup start-->
238     <a class="popup_link" onfocus='this.blur();' href="javascript:showTestDetail('div_pt1.1')" >
239         pass</a>
240 
241     <div id='div_pt1.1' class="popup_window">
242         <div style='text-align: right; color:red;cursor:pointer'>
243         <a onfocus='this.blur();' onclick="document.getElementById('div_pt1.1').style.display = 'none' " >
244            [x]</a>
245         </div>
246         <pre>
247         
248 pt1.1: 
249 
250         </pre>
251     </div>
252     <!--css div popup end-->
253 
254     </td>
255 </tr>
256 
257 <tr id='pt1.2' class='hiddenRow'>
258     <td class='none'><div class='testcase'>testsub</div></td>
259     <td colspan='5' align='center'>
260 
261     <!--css div popup start-->
262     <a class="popup_link" onfocus='this.blur();' href="javascript:showTestDetail('div_pt1.2')" >
263         pass</a>
264 
265     <div id='div_pt1.2' class="popup_window">
266         <div style='text-align: right; color:red;cursor:pointer'>
267         <a onfocus='this.blur();' onclick="document.getElementById('div_pt1.2').style.display = 'none' " >
268            [x]</a>
269         </div>
270         <pre>
271         
272 pt1.2: 
273 
274         </pre>
275     </div>
276     <!--css div popup end-->
277 
278     </td>
279 </tr>
280 
281 <tr id='total_row'>
282     <td>Total</td>
283     <td>2</td>
284     <td>2</td>
285     <td>0</td>
286     <td>0</td>
287     <td>&nbsp;</td>
288 </tr>
289 </table>
290 
291 <div id='ending'>&nbsp;</div>
292 
293 </body>
294 </html>
测试报告

 

原文地址:https://www.cnblogs.com/liunaixu/p/11117489.html