介绍:框架采用excel驱动unittest 完成ui自动化测试
安装python、selenium的方法就不说了,网上一大把,直接进入正题
1.data数据源:
动作:封装selenium各种动作
定位类型:定位元素的方式
定位值:与定位类型匹配使用
输入值:与动作匹配使用
2.变量文件
为了数据后期更好维护,用一个csv文件放置变量
casedata中可直接引用变量值(采用jmeter变量思想)
3.框架介绍
配置文件:config.conf
#运行模式 [mode] mode = normal #normal模式下各个文件路径 [normal] file = ./data/客户端.xlsx sheet = BB电子 var_file = ./data/变量.csv
读取excel文件:excelutil
#-*- coding:utf-8 -*- import xlrd import json import csv import re import config from pylog import Pylog ‘‘‘获取测试数据‘‘‘ class ExcelUtil: def __init__(self,file,sheetname): self.sheetname = sheetname self.dataSheet = xlrd.open_workbook(file).sheet_by_name(sheetname) # get titles self.row = self.dataSheet.row_values(0) # get rows number self.rowNum = self.dataSheet.nrows # get columns number self.colNum = self.dataSheet.ncols # the current column self.curRowNo = 1 #获取用例数据 def get_excel(self): var_file = config.get_config("normal","var_file") r = [] while self.hasNext(): s = {} col = self.dataSheet.row_values(self.curRowNo) i = self.colNum for x in range(i): s[self.row[x]] = col[x] #重置用例名称 s["用例No"] = self.sheetname + str(s["用例No"]) #引入变量 if s["输入值"][:2] == "${": var = re.findall(‘{(.*)}‘, s["输入值"], re.S)[0] vars = self.get_var(var=var,var_file=var_file) s["输入值"] = vars #引入其他用例集 try: if s["动作"] == "引入": file = ‘./data/‘+json.loads(s["输入值"])["file"] sheet = json.loads(s["输入值"])["sheet"] aimslist = ExcelUtil(file=file,sheetname=sheet).get_excel() r.extend(aimslist) else: r.append(s) except Exception as e : Pylog.error("引入用例错误..." + str(e) + "|"+ s["输入值"]) self.curRowNo += 1 return r #遍历 def hasNext(self): if self.rowNum == 0 or self.rowNum <= self.curRowNo: return False else: return True #获取变量 def get_var(self,var="all_vars",var_file=None): dic = {} try: with open(var_file,‘r‘) as file: reader = csv.reader(file) for row in reader: dic[row[0]] = row[1] if var == "all_vars": return dic return dic[var] except Exception as e : Pylog.error("读取变量错误:"+str(e))
日志文件:pylog
import logging import time class Pylog: def __init__(self): ##############################日志配置############################################################ logging.basicConfig(level=logging.DEBUG, format=‘%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s‘, datefmt=‘%a, %d %b %Y %H:%M:%S‘, # filename="./log/"+ time.strftime(‘%Y%m%d%H%M%S‘,time.localtime(time.time()))+".log", filename="./Report/test.log", filemode=‘w‘) console = logging.StreamHandler() console.setLevel(logging.INFO) formatter = logging.Formatter(‘%(name)-12s: %(levelname)-8s %(message)s‘) console.setFormatter(formatter) logging.getLogger(‘‘).addHandler(console) ################################################################################################### @staticmethod def info(data = None): logging.info(data) @staticmethod def debug(data = None): logging.debug(data) @staticmethod def error(data = None): logging.error(data) @staticmethod def warning(data = None): logging.warning(data)
获取测试数据:
import config from pylog import Pylog from excelutil import ExcelUtil import json class Predata: def __init__(self): pass def get_data(self): datalist = [] mode = config.get_config("mode", "mode") file = config.get_config("normal","file") sheet = config.get_config("normal","sheet") if mode == "normal": datalist = self.get_exceldata(file,sheet) return datalist def get_exceldata(self,file,sheet): datalist = ExcelUtil(file,sheet).get_excel() n = 0 for item in datalist: item["用例No"] = str(10000+n) + item["用例No"] n += 1 return datalist
单元测试部分:
import unittest import config import ddtSelenium import time from pylog import Pylog from action import Action from predata import Predata @ddtSelenium.ddt class Case(unittest.TestCase): @classmethod def setUpClass(cls): cls.action = Action() #进入浏览器设置 # options = cls.action.driver.webdriver.ChromeOptions() # options.add_argument() @classmethod def tearDownClass(cls): time.sleep(3) # cls.action.driver.close() @ddtSelenium.data(*Predata().get_data()) def testcase(self, data): Pylog.info(str(data[list(data.keys())[0]]) + "开始") if data["动作"] == "等待": time.sleep(int(data["输入值"])) else: text = self.action.pre_do(data) if data["动作"] == "断言": Pylog.info("断言:"+ str(data[list(data.keys())[0]])) if text != data["输入值"]: Pylog.info("断言截图:" + str(data[list(data.keys())[0]])) self.action.driver.save_png(‘./Report/‘+data[‘用例No‘]+‘.jpg‘) self.assertEqual(text, data["输入值"])
action部分:(pyse引用虫师封装py)
from pylog import Pylog from pyse import Pyse import os import config from predata import Predata class Action: def __init__(self): self.driver = Pyse("chrome") def pre_do(self,data): if config.get_config("mode","mode") == "normal": return self.do_action(data) def do_action(self,data): try: if data["动作"] == "断言": text = self.driver.get_element(data["定位类型"] + ‘=>‘ + data["定位值"]).text return text if data["动作"] == "打开": self.driver.open(data["输入值"]) if data["动作"] == "点击": self.driver.click(data["定位类型"] + ‘=>‘ + data["定位值"]) if data["动作"] == "清除": self.driver.clear(data["定位类型"] + ‘=>‘ + data["定位值"]) # if data["动作"] == "等待": # self.driver.wait(int(data["输入值"])) if data["动作"] == "输入": self.driver.type(data["定位类型"] + ‘=>‘ + data["定位值"],data["输入值"]) if data["动作"] == "滚动条下拉": self.driver.js( "var q=document.body.scrollTop="+data["输入值"]+";") if data["动作"] == "等待元素": self.driver.element_wait(data["定位类型"] + ‘=>‘ + data["定位值"],10) if data["动作"] == "最大化": self.driver.max_window() if data["动作"] == "关闭浏览器": self.driver.close() if data["动作"] == "外调程序": os.system(data["输入值"]) except Exception as e : Pylog.error("异常截图-"+data["动作"]+str(e)) self.driver.save_png(‘./Report/‘+data[‘用例No‘]+‘.jpg‘)
框架源码:https://github.com/Acguo
时间: 2024-10-06 02:51:15