python+unittest框架整理(一点点学习前辈们的封装思路,一点点成长。。。)

时间:2021-10-26 18:24:50

预期框架整理目标:

1.单个用例维护在单个.py文件中可单个执行,也可批量生成组件批量执行

2.对定位参数,定位方法,业务功能脚本,用例脚本,用例批量执行脚本,常用常量进行分层独立,各自维护在单独的.py文件中

3.加入日志,htlm报表,发送邮件功能

框架结构

python+unittest框架整理(一点点学习前辈们的封装思路,一点点成长。。。)

结构说明:

config:配置部分,浏览器种类和定位信息维护在此处

constant:常量部分,固定不变的数据维护在此处

data:存放用于参数化的文本表格等文件

encapsulation:定位等selenium功能二次封装在此处

error_picture:存放错误截图

function:业务功能脚本维护在此处

log:存放log类

report:存放测试报告文件

test_case:存放用例文件

all_case.py:用来执行所有用例

debug_case.py:本人调试用的,可以忽略

tst.log:生成的日志

逐个介绍各个包下面的.py文件,并附上源码(说明见注释哈哈~):

 #!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017-05-11 13:42
# config/config_01.py
from selenium import webdriver
import time
from selenium.webdriver.common.action_chains import * # config配置部分 # 浏览器种类维护在此处
browser_config = {
'ie': webdriver.Ie,
'chrome': webdriver.Chrome
} # 定位信息维护在此处,维护结构由外到内为:页面名称--页面下元素名称--元素的定位方式+参数
locat_config = {
'博客园首页': {
'找找看输入框': ['id', 'zzk_q'],
'找找看按钮': ['xpath', '//input[@value="找找看"]']
}
}
 #!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017-05-15 13:20
# constant/constant_1.py # 常量部分(固定不变使用频繁的参数维护在此处)
LOGIN_URL = 'https://www.cnblogs.com/'
 #!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017-05-15 13:20
# encapsulation/encapsulation.py # 封装部分维护在此 from config.config_01 import locat_config
from log.log import Logger
from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class UIHandle():
logger = Logger() # 构造方法,用来接收selenium的driver对象
@classmethod
def __init__(cls, driver):
cls.driver = driver # 输入地址
@classmethod
def get(cls, url):
cls.logger.loginfo(url)
cls.driver.get(url) # 关闭浏览器驱动
@classmethod
def quit(cls):
cls.driver.quit() # element对象(还可加入try,截图等。。。)
@classmethod
def element(cls, page, element):
# 加入日志
cls.logger.loginfo(page)
# 加入隐性等待
# 此处便可以传入config_o1中的dict定位参数
el = WebDriverWait(cls.driver, 10).until(EC.presence_of_element_located(locat_config[page][element]))
# 加入日志
cls.logger.loginfo(page+'OK')
return el
# element对象(还未完成。。。)
def elements(cls, page, element):
# 加入日志
cls.logger.loginfo(page)
# 加入隐性等待
WebDriverWait(cls.driver, 10)
els = cls.driver.find_elements(*locat_config[page][element])
# 注意返回的是list
return els # send_keys方法
@classmethod
def Input(cls, page, element, msg):
el = cls.element(page, element)
el.send_keys(msg) # click方法
@classmethod
def Click(cls, page, element):
el = cls.element(page, element)
el.click()
 #!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017-05-15 13:22
# function/function_01.py
# 业务功能脚本(用例脚本可调用此处的功能脚本) from encapsulation.encapsulation import UIHandle
from constant.constant_1 import LOGIN_URL
from config.config_01 import browser_config
from time import sleep # 打开博客园首页,进行找找看搜索功能
def search(msg):
# 打开浏览器
driver = browser_config['chrome']()
# 传入driver对象
uihandle = UIHandle(driver)
#输入url地址
uihandle.get(LOGIN_URL)
# 调用二次封装后的方法,此处可见操作了哪个页面,哪个元素,msg是要插入的值,插入值得操作在另外一个用例文件中传入
uihandle.Input('博客园首页', '找找看输入框', msg)
uihandle.Click('博客园首页', '找找看按钮')
uihandle.quit()
 #!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017-05-17 11:19
# log/log.py import logging
import logging.handlers # 日志类
class Logger():
LOG_FILE = 'tst.log' handler = logging.handlers.RotatingFileHandler(LOG_FILE, maxBytes = 1024*1024, backupCount = 5) # 实例化handler
fmt = '%(asctime)s - %(filename)s:%(lineno)s - %(name)s - %(message)s' formatter = logging.Formatter(fmt) # 实例化formatter
handler.setFormatter(formatter) # 为handler添加formatter logger = logging.getLogger('tst') # 获取名为tst的logger
logger.addHandler(handler) # 为logger添加handler
logger.setLevel(logging.DEBUG)
def loginfo(self, message):
self.logger.info(message) def logdebug(self, message):
self.logger.debug(message)
 #!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017-05-15 15:30
# test_case/test_case_1/start_case_01.py import unittest
from function.function_01 import *
# 用例
class Case_02(unittest.TestCase):
u'''哇塞好玩'''
def setUp(self):
pass def test_zzk(self):
u'''输入哇塞好玩后点击找找看'''
search("哇塞好玩")
print('打印方法名:test_zzk') def tearDown(self):
pass if __name__ == "__main__":
unittest.main()
 #!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017-05-10 16:34
# all_case.py import unittest
import HTMLTestRunner
import time,os,datetime
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage # 取test_case文件夹下所有用例文件
def creatsuitel(lists):
testunit = unittest.TestSuite()
# discover 方法定义
discover = unittest.defaultTestLoader.discover(lists, pattern='start_*.py', top_level_dir=None)
#discover 方法筛选出来的用例,循环添加到测试套件中
for test_suite in discover:
for test_case in test_suite:
testunit.addTests(test_case)
print(testunit)
return testunit
list_1 = 'test_case\\test_case_1'
alltestnames = creatsuitel(list_1) #取前面时间加入到测试报告文件名中
now = time.strftime("%Y-%m-%M-%H_%M_%S", time.localtime(time.time()))
filename = "report\\"+now+'result.html' #定义个报告存放路径,支持相对路径。
fp = open(filename, 'wb')
runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title='Report_title', description='Report_description') if __name__ == "__main__":
# 执行测试用例集并生成报告
runner = unittest.TextTestRunner()

感谢@大师兄+@我去热饭的指导与帮助。

 

为什么选择?

有的人喜欢创造世界,他们做了程序员

有的人喜欢拯救世界,他们做了测试员