测试流程:
1、账号密码手动写入Excel中
2、使用ddt读取Excel中的账号密码
3、使用unittest进行单元测试,登录公司某个系统
4、断言是否用例是否执行成功(登录成功判断页面中是否有“退出”,登录失败的判断页面提示是否正确)
5、最后生成HTML测试报告
在本地磁盘D:\test\DataDrivenTesting目录中新建一个“登录测试.xlsx”,工作表名为“账号密码”,内容如下:
序号 账号 密码 期望结果
1 chenyl1 a123456 退出
2 chenyl2 a123456 退出
3 chenyl3 a123456 退出
4 chenyl4 a123456 退出
5 chenyl4 请输入密码
6 a123456 请输入用户名
7 请输入用户名
8 abc1234 a123456 该用户不存在
9 chenyl1 xx112233 密码错误
10 acbd123 1123aaxx 该用户不存在
在PyCharm中创建MyLoginProject的Python工程,并在工程下创建以下文件:ExcelUtil.py ,ReportTemplate.py,MyLoginDataDrivenByExcel.py
ExcelUtil.py文件用于编写读取Excel的脚本,具体内容如下:
#encoding=utf-8
from openpyxl importload_workbookclassParseExcel(object):def __init__(self, excelPath, sheetName):#将要读取的excel加载到内存
self.wb =load_workbook(excelPath)#通过工作表名称获取一个工作表对象
self.sheet =self.wb.get_sheet_by_name(sheetName)#获取工作表中存在数据的区域的最大行号
self.maxRowNum =self.sheet.max_rowdefgetDatasFromSheet(self):#用于存放从工作表中读取出来的数据
dataList =[]for line inself.sheet.rows:#遍历工作表中数据区域的每一行,
#并将每行中各个单元格的数据取出存于列表tmpList中,
#然后再将存放一行数据的列表添加到最终数据列表dataList中
tmpList =[]#如果单元格为空,则在列表中插入一个为空的unicode字符串,以免输入账号密码时报错
if line[1].value ==None:
tmpList.append(u"")else:
tmpList.append(line[1].value)if line[2].value ==None:
tmpList.append(u"")else:
tmpList.append(line[2].value)
tmpList.append(line[3].value)
dataList.append(tmpList)#将获取工作表中的所有数据的迭代对象返回
#因为工作表中的第一行是标题行,所以需要去掉
return dataList[1:]if __name__ == '__main__':
excelPath= u'D:\\test\\DataDrivenTesting\\登录测试.xlsx'sheetName= u"账号密码"pe=ParseExcel(excelPath, sheetName)printpe.getDatasFromSheet()for i inpe.getDatasFromSheet():printi[0],type(i[0])#i[1],i[2]
文件ReportTemplate.py用于生成自定义HTML测试报告,具体内容如下:
#encoding=utf-8
defhtmlTemplate(url, trData):
htmlStr= u'''
单元测试报告body {
width: 80%; /*整个body区域占浏览器的宽度百分比*/
margin: 40px auto; /*整个body区域相对浏览器窗口摆放位置(左右,上下)*/
font-weight: bold; /*整个body区域的字体加粗*/
font-family: 'trebuchet MS', 'Lucida sans', SimSun; /*表格中文字的字体类型*/
font-size: 18px; /*表格中文字字体大小*/
color: #000; /*整个body区域字体的颜色*/
}
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); /*鼠标滑过一行时,动态显示的颜色146,208,80*/
}
.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)*/
}
测试报告
NoUsernamePasswordAssert WordsStart TimeWaste Time(s)Status'''endStr= u'''
'''
#拼接完整的测试报告HTML页面代码
html = htmlStr + u"测试网址:" + url + u"" + trData +endStr#print html
#生成.html文件
with open(u"D:\\test\\DataDrivenTesting\\testTemplate.html", "w") as fp:
fp.write(html.encode("gbk"))
MyLoginDataDrivenByExcel.py用于编写数据驱动测试脚本,具体内容如下:
#encoding=utf-8
from selenium importwebdriverimportunittest,time,osimportlogging,tracebackimportddtfrom ExcelUtil importParseExcelfrom ReportTemplate importhtmlTemplatefrom selenium.common.exceptions importNoSuchElementException#初始化日志对象
logging.basicConfig(#日志级别
level=logging.INFO,#日志格式
#时间、代码所在文件名、代码行号、日志级别名字、日志信息
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',#打印日志的时间
datefmt='%a, %Y-%m-%d %H:%M:%S',#日志文件存放的目录(目录必须存在)及日志文件名
filename='D:\\test\\DataDrivenTesting\\report.log',#打开日志文件的方式
filemode='w')
excelPath= u"D:\\test\\DataDrivenTesting\\登录测试.xlsx"sheetName= u"账号密码"
#ParseExcel类的实例对象
excel =ParseExcel(excelPath,sheetName)
@ddt.ddtclassTestDemo(unittest.TestCase):
#公司地址保密,使用xxx代替
url= "xxx"no=0
@classmethoddefsetUpClass(cls):#整个测试过程只被调用一次
TestDemo.trStr = ""
defsetUp(self):
self.driver= webdriver.Ie(executable_path="D:\\IEDriverServer")
status= None #用于存放测试结果状态,失败'fail',成功'pass'
flag = 0 #数据驱动测试结果的标志,失败置0,成功置1
TestDemo.no += 1@ddt.data(*excel.getDatasFromSheet())deftest_dataDrivenByFile(self, data):#决定测试报告中状态单元格中内容的颜色
flagDict = {0: 'red', 1: '#00AC4E'}#访问系统
self.driver.get(TestDemo.url)#将浏览器窗口最大化
self.driver.maximize_window()#print data
#读取Excel中的账号密码及期望结果
username,password, expectdata =tuple(data)#设置隐式等待时间为10秒
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("username").send_keys(username)#找到密码输入框,并输入测试数据
self.driver.find_element_by_id("password").send_keys(password)#找到登录按钮,并点击
self.driver.find_element_by_id("button").click()
time.sleep(5)#断言期望结果是否出现在页面源代码中
self.assertTrue(expectdata inself.driver.page_source)exceptNoSuchElementException, e:
logging.error(u"查找的页面元素不存在,异常堆栈信息:" +str(traceback.format_exc()))
status= 'fail'flag=0exceptAssertionError, e:
logging.info(u"登录账号:“%s”,期望“%s”,失败" %(username, expectdata))
status= 'fail'flag=0exceptException, e:
logging.error(u"未知错误,错误信息:" +str(traceback.format_exc()))
status= 'fail'flag=0else:
logging.info(u"登录账号:“%s”,期望“%s”通过" %(username, expectdata))
status= 'pass'flag= 1
#计算耗时,从将测试数据输入到输入框中到断言期望结果之间所耗时
wasteTime = time.time() - start - 5 #减去强制等待的3秒
#每一组数据测试结束后,都将其测试结果信息插入表格行
#的HTML代码中,并将这些行HTML代码拼接到变量trStr变量中,
#等所有测试数据都被测试结束后,传入htmlTemplate()函数中
#生成完整测试报告的HTML代码
TestDemo.trStr += u'''
%s%s%s%s%s%.2f%s''' %(TestDemo.no, username,password, expectdata, startTime, wasteTime, flagDict[flag], status)deftearDown(self):
self.driver.quit()
@classmethoddeftearDownClass(cls):#写自定义的html测试报告
#整个测试过程只被调用一次
htmlTemplate(TestDemo.url, TestDemo.trStr)if __name__ == '__main__':
unittest.main()