一、摘要
本博文将介绍Python和Selenium做自动化测试的时候,基于unittest框架,借助ddt模块使用json文件作为数据文件作为测试输入,最后生成html测试报告
二、json文件
[
"北京||北京","上海||上海","广州||广州","深圳||深圳","香港||香港"
]
三、ReportTemplate.py
# encoding = utf-8
"""
__title__ = 'DataDrivenTestByDDT use this template for generating testing report'
__author__ = 'davieyang'
__mtime__ = '2018/4/21'
"""
# encoding = utf-8
def htmlTemplate(trData):
htmlStr = u'''<!DOCTYPE HTML>
<html>
<head>
<title>单元测试报告</title>
<style>
body {
width:80%;
margin:40px auto;
font-weight:bold;
font-family: 'trebuchet MS', 'Lucida sans', SimSun;
font-size:18px;
color: #000;
}
table {
* border-collapse:collapse;
border-spacing:0;
width:100%;
}
.tableStyle {
/* border:solid #ggg 1px;*/
border-style:outset;
border-width:2px;
/*border:2px;*/
border-color:blue;
}
.tableStyle tr:hover {
background: rgb(173.216.230);
}
.tableStyle td,.tableStyle th{
border-left:solid 1px rgb(146,208,80);
border-top:1px solid rgb(146,208,80);
padding:15px
text-align:center
}
.tableStyle th{
padding:15px;
background-color:rgb(146,208,80);
/*表格标题栏设置渐变颜色*/
background-image: -webkit -gradient(linear, left top, left bottom, from(#92D050), to(#A2D668))
/*rgb(146,208,80)*/
}
</style>
</head>
<body>
<center><h1>测试报告</h1></center><br />
<table class="tableStyle">
<thead>
<tr>
<th>Search Words</th>
<th>Assert Words</th>
<th>Start Time</th>
<th>Waste Time(s)</th>
<th>Status</th>
</tr>
</thead>'''
endStr = u'''
</table>
</body>
</html>'''
html = htmlStr + trData + endStr
print(html)
with open("D:\\\Programs\\\Python\\\PythonUnittest\\\Reports\\testTemplate.html", "wb") as fp:
fp.write(html.encode("gbk"))
四、测试脚本
# encoding = utf-8
"""
__title__ = ''
__author__ = 'davieyang'
__mtime__ = '2018/4/21'
"""
from selenium import webdriver
import unittest
import time
import logging
import traceback
import ddt
from DataDrivenTest.ReportTemplate import htmlTemplate
from selenium.common.exceptions import NoSuchElementException
# 初始化日志对象
logging.basicConfig(
# 日志级别
level=logging.INFO,
# 时间、代码所在文件名、代码行号、日志级别名字、日志信息
format='%(asctime)s %(filename)s[line: %(lineno)d] %(levelname)s %(message)s',
# 打印日志的时间
datefmt='%a, %d %b %Y %H:%M:%S',
# 日志文件存放的目录及日志文件名
filename='D:\\Programs\\Python\\PythonUnittest\\Reports\\TestResults.TestResults',
# 打开日志的方式
filemode='w'
)
@ddt.ddt
class DataDrivenTestByDDT(unittest.TestCase):
@classmethod
def setUpClass(cls):
# 整个测试过程只调用一次
DataDrivenTestByDDT.trStr = ""
def setUp(self):
self.driver = webdriver.Chrome(executable_path="D:\\Programs\\Python\\PythonUnittest\\BrowserDrivers\\chromedriver.exe")
status = None # 用于存放测试结果状态,失败‘fail’,成功‘pass’
flag = 0 # 数据驱动测试结果的标志,失败置0,成功置1
@ddt.file_data("D:\\Programs\\Python\\PythonUnittest\\TestData\\test_data_list.json")
def test_dataDrivenByFile(self, value):
# 决定测试报告中状态单元格中内容的颜色
flagDict = {0: 'red', 1: '#00AC4E'}
url = "http://www.baidu.com"
self.driver.get(url)
self.driver.maximize_window()
print(value)
# 从.json文件中读取出的数据用“||”分割成测试数据和期望的数据
testdata, execptdata = tuple(value.strip().split("||"))
# 设置隐式等待时间
self.driver.implicitly_wait(10)
try:
# 获取当前的时间戳,用于后面计算查询耗时用
start = time.time()
# 获取当前时间的字符串,表示测试开始时间
startTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
self.driver.find_element_by_id("kw").send_keys(testdata)
self.driver.find_element_by_id("su").click()
time.sleep(3)
# 断言期望结果是否出现在页面中
self.assertTrue(execptdata in self.driver.page_source)
except NoSuchElementException as e:
logging.error(u"查找的页面元素不存在,异常堆栈信息为:"+ str(traceback.format_exc()))
status = 'fail'
flag = 0
except AssertionError as e:
logging.info(u"搜索 ‘%s’,期望 ‘%s’ ,失败" %(testdata, execptdata))
status = 'fail'
flag = 0
except Exception as e:
logging.error(u"未知错误,错误信息:" + str(traceback.format_exc()))
status = 'fail'
flag = 0
else:
logging.info(u"搜索 ‘%s’,期望 ‘%s’ ,通过" %(testdata, execptdata))
status = 'pass'
flag = 1
# 计算耗时,从将测试数据输入到输入框中到断言期望结果之间所耗时
wasteTime = time.time() - start - 3 # 减去强制等待3秒
# 每一组数据测试结束后,都将其测试结果信息插入表格行的HTML代码中,并将这些行HTML代码拼接到变量trStr变量中,
# 等所有测试数据都被测试结束后,传入htmlTemplate()函数中,生成完整测试报告的HTML代码
DataDrivenTestByDDT.trStr += u'''
<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%.2f</td>
<td style = "color: %s">%s</td>
</tr><br/>''' % (testdata, execptdata, startTime, wasteTime, flagDict[flag], status)
def tearDown(self):
self.driver.quit()
@classmethod
def tearDownClass(cls):
# 写自定义的HTML测试报告,整个过程只被调用一次
htmlTemplate(DataDrivenTestByDDT.trStr)
if __name__ == '__main__':
unittest.main()
五、生成日志
Fri, 07 Dec 2018 15:05:36 DataDrivenTestByDDT.py[line: 81] INFO 搜索 ‘北京’,期望 ‘北京’ ,通过
Fri, 07 Dec 2018 15:05:50 DataDrivenTestByDDT.py[line: 81] INFO 搜索 ‘上海’,期望 ‘上海’ ,通过
Fri, 07 Dec 2018 15:06:04 DataDrivenTestByDDT.py[line: 81] INFO 搜索 ‘广州’,期望 ‘广州’ ,通过
Fri, 07 Dec 2018 15:06:18 DataDrivenTestByDDT.py[line: 81] INFO 搜索 ‘深圳’,期望 ‘深圳’ ,通过
Fri, 07 Dec 2018 15:06:32 DataDrivenTestByDDT.py[line: 81] INFO 搜索 ‘香港’,期望 ‘香港’ ,通过
六、测试报告