一直想着写篇博客对年前学习UI自动化及项目实战进行总结,一直没时间,今天整理一下实战项目的代码分享出来,(代码数据分离做的不太好,项目有几次大改动,对于一个初学者产生了一些影响)大家共同学习。(注:项目是针对我们公司内部系统的测试,我就不分享链接了。)
项目简介
项目名称:****转账系统
项目目的:实现系统项目自动化测试执行
项目版本:v1.0
项目目录
Package# 存放第三方插件 HTMLTestRunner.py framfriend #项目文件 Config __init__.py Conf.py# 读配置文件获取项目跟目录路径 并获取所有欲使用的目录文件的路径 Config.ini# 存放项目跟目录的路径 Data TestData __init__.py elementDate.xlsx# 存放项目中所有的元素信息及测试数据 Email_receiver.txt# 存放邮件的接受者信息 Report# 测试报告 Image Fail# 存放用例执行失败时的截图 Pass# 存放用例执行成功时的截图 Log# 存放用例执行过程中的log信息 TestReport# 存放测试用例执行完成后生成的测试报告 Test_case# 测试用例信息 Models # 存放一些公共方法 Doconfini.py# 读配置文件 Doexcel.py# 读excel文件 Driver.py# 存放driver Log.py# 生成log Myunit.py# 继承unittest.Testcase Sendmail.py# 发送邮件 Strhandle.py# 字符串处理 Tcinfo.py# 测试用例基本信息 Testreport.py# 测试报告 Page_obj# 测试模块
runTc.py# 执行测试用例
项目框架
unittest单元测试框架
pageobject 设计模式
项目设计
1.一个模块(被测项目的页面)对应一个py文件及一个测试类(测试文件)
2.每一个测试页面(系统的页面)中存储页面元素及此页面中涉及到的功能
3.每一个用例组合在一个测试类里面生成一个py文件
项目目标
1. 生成测试用例执行结果报告
2.生成测试用例执行日志
3.用例执行失败或者执行完成后自动发送邮件报告
4.数据驱动(读取测试数据,减少脚本维护成本)
项目代码
config.ini # 存放项目根路径
[project] project_path = F:python_testframfriend_Test_Project [tesesection] name = hello word
elementData.xlsx # 存放所有的测试数据及元素
mail_receiver.txt# 存放邮件接收者的账号 , 可以添加多个账号以‘,’号分割
**@qq.com,**@qq.com
conf.py#获取各种路径
''' Code description:read config.ini, get path Create time: Developer: ''' import os import sys from framfriend.test_case.models.doconfIni import DoConfIni # 获取当前路径 currPath= os.path.split(os.path.realpath(__file__))[0] # 读配置文件获取项目路径 readConfig = DoConfIni() proPath = readConfig.getConfValue(os.path.join(currPath,'config.ini'),'project','project_path') # 获取日志路径 logPath= os.path.join(proPath,'framfriend','report','Log') # 测试用例路径 tcPath = os.path.join(proPath,'framfriend','test_case') # 获取报告路径 reportPath= os.path.join(proPath,'framfriend','report','TestReport') # 获取测试数据路径 dataPath= os.path.join(proPath,'framfriend','data','TestData') # 保存截图路径 # 错误截图 failImagePath = os.path.join(proPath, 'framfriend', 'report', 'image','fail') # 成功截图 passImagePath = os.path.join(proPath, 'framfriend', 'report', 'image','pass') # 被调函数名称 funcName = sys._getframe().f_code.co_name # 被调函数所在行号 funcNo = sys._getframe().f_back.f_lineno # 被调函数所在文件名称 funcFile= sys._getframe().f_code.co_filename
公共方法models
doconfini.py #读写ini文件
''' Code description:read conf file Create time: Developer: ''' import logging import configparser from framfriend.config.conf import * from framfriend.test_case.models.log import Logger log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO) class DoConfIni(object): def __init__(self): """ :param filename: """ self.cf = configparser.ConfigParser() # 从ini文件中读数据 def getConfValue(self,filename,section,name): """ :param config: :param name: :return: """ try: self.cf.read(filename) value = self.cf.get(section,name) except Exception as e: log.logger.exception('read file [%s] for [%s] failed , did not get the value' %(filename,section)) raise e else: log.logger.info('read excel value [%s] successed! ' %value) return value # 向ini文件中写数据 def writeConfValue(self,filename, section, name, value): """ :param section: section :param name: value name :param value: value :return: none """ try: self.cf.add_section(section) self.cf.set(section, name, value) self.cf.write(open(filename, 'w')) except Exception : log.logger.exception('section %s has been exist!' %section) raise configparser.DuplicateSectionError(section) else: log.logger.info('write section'+section+'with value '+value+' successed!') if __name__ == '__main__': file_path = currPath print(file_path) read_config = DoConfIni() value = read_config.getConfValue(os.path.join(currPath,'config.ini'),'project','project_path') print(value) read_config.writeConfValue(os.path.join(currPath,'config.ini'),'tesesection', 'name', 'hello word')
doexcel.py #读取excel文件数据
''' Code description:read excel.xlsx, get values Create time: Developer: ''' import xlrd import os import logging from framfriend.config import conf from framfriend.test_case.models.log import Logger log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO) class ReadExcel(object): def __init__(self,fileName='elementDate.xlsx',sheetName='elementsInfo'): """ :param fileName: :param sheetName: """ try: self.dataFile = os.path.join(conf.dataPath, fileName) self.workBook = xlrd.open_workbook(self.dataFile) self.sheetName = self.workBook.sheet_by_name(sheetName) except Exception: log.logger.exception('init class ReadExcel fail', exc_info=True) raise else: log.logger.info('initing class ReadExcel') # 读excel中的数据 def readExcel(self,rownum,colnum): """ :param rownum: :param colnum: :return: """ try: value = self.sheetName.cell(rownum,colnum).value except Exception: log.logger.exception('read value from excel file fail', exc_info=True) raise else: log.logger.info('reading value [%s] from excel file [%s] completed' %(value, self.dataFile)) return value if __name__ == '__main__': cellValue = ReadExcel().readExcel(11,3) print((cellValue))
driver.py #浏览器启动
''' Code description:save all driver info Create time: Developer: ''' import time from selenium import webdriver import logging import sys from framfriend.test_case.models.log import Logger log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO) class WDriver(object): # Firefox driver def fireFoxDriver(self): """ :return: """ try: self.driver = webdriver.Firefox() except Exception as e: log.logger.exception('FireFoxDriverServer.exe executable needs to be in PATH. Please download!', exc_info=True) raise e else: log.logger.info('%s:found the Firefox driver [%s] successed !' %(sys._getframe().f_code.co_name,self.driver)) return self.driver # chrom driver def chromeDriver(self): """ :return: """ try: chromeOptions = webdriver.ChromeOptions() prefs = {"download.default_directory": "F:\TestDownloads"} chromeOptions.add_experimental_option("prefs", prefs) self.driver = webdriver.Chrome(options=chromeOptions) time.sleep(10) except Exception as e: log.logger.exception('ChromeDriverServer.exe executable needs to be in PATH. Please download!', exc_info=True) raise e else: log.logger.info('%s:found the chrome driver [%s] successed !' % (sys._getframe().f_code.co_name, self.driver)) return self.driver # Ie driver def ieDriver(self): """ :return: """ try: self.driver = webdriver.Ie() except Exception as e: log.logger.exception('IEDriverServer.exe executable needs to be in PATH. Please download!', exc_info=True) raise e else: log.logger.info('%s:found the IE driver [%s] successed !' % (sys._getframe().f_code.co_name, self.driver)) return self.driver if __name__ == '__main__': WDrive=WDriver() WDrive.chromeDriver()
log.py # 输出日志文件
''' Code description:log info Create time: Developer: ''' import logging import time class Logger(object): def __init__(self, logger, CmdLevel=logging.INFO, FileLevel=logging.INFO): """ :param logger: :param CmdLevel: :param FileLevel: """ self.logger = logging.getLogger(logger) self.logger.setLevel(logging.DEBUG) # 设置日志输出的默认级别 # 日志输出格式 fmt = logging.Formatter('%(asctime)s - %(filename)s:[%(lineno)s] - [%(levelname)s] - %(message)s') # 日志文件名称 # self.LogFileName = os.path.join(conf.log_path, "{0}.log".format(time.strftime("%Y-%m-%d")))# %H_%M_%S currTime = time.strftime("%Y-%m-%d") self.LogFileName = r'F:python_testframfriend_Test_Projectframfriend eportLoglog'+currTime+'.log' # 设置控制台输出 # sh = logging.StreamHandler() # sh.setFormatter(fmt) # sh.setLevel(CmdLevel)# 日志级别 # 设置文件输出 fh = logging.FileHandler(self.LogFileName) fh.setFormatter(fmt) fh.setLevel(FileLevel)# 日志级别 # self.logger.addHandler(sh) self.logger.addHandler(fh) def debug(self, message): """ :param message: :return: """ self.logger.debug(message) def info(self,message): """ :param message: :return: """ self.logger.info(message) def warn(self,message): """ :param message: :return: """ self.logger.warning(message) def error(self,message): """ :param message: :return: """ self.logger.error(message) def criti(self,message): """ :param message: :return: """ self.logger.critical(message) if __name__ == '__main__': logger = Logger("fox",CmdLevel=logging.DEBUG, FileLevel=logging.DEBUG) logger.logger.debug("debug") logger.logger.log(logging.ERROR,'%(module)s %(info)s',{'module':'log日志','info':'error'}) #ERROR,log日志 error
myunittest.py # 设置前置后置操作(一个测试类(文件)执行一次打开浏览器, 节约每个用例打开一次浏览器的时间)
''' Code description:unittest framwork Create time: Developer: ''' from selenium import webdriver from framfriend.test_case.models.driver import WDriver import logging import unittest from framfriend.test_case.page_obj.login_page import LoginPage from framfriend.test_case.models.log import Logger log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO) class MyunitTest(unittest.TestCase): """ """ @classmethod def setUpClass(cls): # 一个测试类(文件)执行一次打开浏览器, 节约每个用例打开一次浏览器的时间 cls.driver = WDriver().chromeDriver() cls.driver.maximize_window() log.logger.info('opened the browser successed!') # ---------------------------- def setUp(self): """ :return: """ self.login = LoginPage(self.driver) self.login.open() log.logger.info('************************starting run test cases************************') def tearDown(self): """ :return: """ self.driver.refresh() log.logger.info('************************test case run completed************************') @classmethod def tearDownClass(cls): cls.driver.quit() log.logger.info('quit the browser success!') #---------------------------- if __name__ == '__main__': unittest.main()
sendmail.py # 发送邮件
''' Code description:send email Create time: Developer: ''' import smtplib from email.mime.text import MIMEText from email.header import Header import os from framfriend.config import conf from framfriend.test_case.models.log import Logger log = Logger(__name__) # 邮件发送接口 class SendMail(object): ''' 邮件配置信息 ''' def __init__(self, receiver, subject='framfriend 系统测试报告', server='smtp.qq.com', fromuser='******@qq.com', frompassword='yryyintgafnubded', sender='******@qq.com'): """ :param receiver: :param subject: :param server: :param fromuser: :param frompassword: :param sender: """ self._server = server self._fromuser = fromuser self._frompassword = frompassword self._sender = sender self._receiver = receiver self._subject = subject def sendEmail(self, fileName): """ :param filename: :return: """ # 打开报告文件读取文件内容 try: f = open(os.path.join(conf.reportPath, fileName), 'rb') fileMsg = f.read() except Exception: log.logger.exception('open or read file [%s] failed,No such file or directory: %s' %(fileName, conf.reportPath)) log.logger.info('open and read file [%s] successed!' %fileName) else: f.close() # 邮件主题 subject = 'Python test report' # # 邮件设置 msg = MIMEText(fileMsg, 'html', 'utf-8') msg['subject'] = Header(subject, 'utf-8') msg['from'] = self._sender # 连接服务器,登录服务器,发送邮件 try: smtp = smtplib.SMTP() smtp.connect(self._server) smtp.login(self._fromuser, self._frompassword) except Exception: log.logger.exception('connect [%s] server failed or username and password incorrect!' %smtp) else: log.logger.info('email server [%s] login success!' %smtp) try: smtp.sendmail(self._sender, self._receiver, msg.as_string()) except Exception: log.logger.exception('send email failed!') else: log.logger.info('send email successed!') # 从文件中读取邮件接收人信息 def getReceiverInfo(fileName): ''' :param filename: 读取接收邮件人信息 :return: 接收邮件人信息 ''' try: openFile = open(os.path.join(conf.dataPath, fileName)) except Exception: log.logger.exception('open or read file [%s] failed,No such file or directory: %s' %(fileName, conf.dataPath)) else: log.logger.info('open file [%s] successed!' %fileName) for line in openFile: msg = [i.strip() for i in line.split(',')] log.logger.info('reading [%s] and got receiver value is [%s]' %(fileName, msg)) return msg if __name__ == '__main__': readMsg=getReceiverInfo('mail_receiver.txt') sendmail = SendMail(readMsg) sendmail.sendEmail('report2019-10-21 15_55_26.html')
testreport.py #输出测试报告html文件
''' Code description:test report Create time: Developer: ''' import time import logging import unittest from BeautifulReport import BeautifulReport from framfriend.config import conf from framfriend.test_case.models.log import Logger from package import HTMLTestRunner log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO) # 用HTMLTestRunner 实现的测试报告 def testreport(): """ :return: """ currTime = time.strftime('%Y-%m-%d %H_%M_%S') fileName = conf.reportPath + r' eport' + currTime + '.html' try: fp = open(fileName, 'wb') except Exception : log.logger.exception('[%s] open error cause Failed to generate test report' %fileName) else: runner = HTMLTestRunner.HTMLTestReportCN (stream=fp, title='framfriend sys测试报告', description='处理器:Intel(R) Core(TM) ' 'i5-5200U CPU @ 2.20GHz 2.20 GHz ' '内存:8G 系统类型: 64位 版本: windows 10 专业版') log.logger.info('successed to generate test report [%s]' %fileName) return runner, fp, fileName # def addTc(TCpath = conf.tcPath, rule = '*TC.py'): """ :param TCpath: 测试用例存放路径 :param rule: 匹配的测试用例文件 :return: 测试套件 """ discover = unittest.defaultTestLoader.discover(TCpath, rule) return discover # 用BeautifulReport模块实现测试报告 def runTc(discover): """ :param discover: 测试套件 :return: """ currTime = time.strftime('%Y-%m-%d %H_%M_%S') fileName = currTime+'.html' try: result = BeautifulReport(discover) result.report(filename=fileName, description='测试报告', log_path=conf.reportPath) except Exception: log.logger.exception('Failed to generate test report', exc_info=True) else: log.logger.info('successed to generate test report [%s]' % fileName) return fileName if __name__ == '__main__': testreport() suite = addTc(rule = '*TC.py') runTc(suite)
#测试用例(测试用例我就展出一个了,如果想看其他的可以上我的github下载查看)
base_page.py # 封装页面公共方法
''' Code description: base page 封装一些公共方法 Create time: Developer: ''' from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By import os import logging import sys from framfriend.test_case.models.log import Logger from framfriend.config import conf from framfriend.test_case.models.doexcel import ReadExcel eleData = ReadExcel() # 存储系统所有的元素数据 testLoginData = ReadExcel('elementDate.xlsx', 'userNamePw') # 登录模块测试数据 userData = ReadExcel('elementDate.xlsx','userData') queryData = ReadExcel('elementDate.xlsx', 'queryData') log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO) class BasePage(object): """主菜单""" menuList = [(By.ID, eleData.readExcel(11, 3)), #左侧菜单栏 (By.ID, eleData.readExcel(12, 3)), # 功能开发 (By.ID, eleData.readExcel(13, 3)), # 基本功能维护 (By.ID, eleData.readExcel(14, 3)), # 银农直联系统 (By.ID, eleData.readExcel(15, 3)), # 财务系统 (By.ID, eleData.readExcel(16, 3)), # 审批流程 (By.ID, eleData.readExcel(17, 3))] # 合同管理 def __init__(self, driver,url='http://localhost:8080/farmfriend/login/main.do'): """ :param driver: :param url: """ self.driver = driver self.base_url = url def _open(self,url): """ :param url: :return: """ try: self.driver.get(url) self.driver.implicitly_wait(10) except Exception as e: log.logger.exception(e, exc_info=True) raise ValueError('%s address access error, please check!' %url) else: log.logger.info('%s is accessing address %s at line[46]' %(sys._getframe().f_code.co_name,url)) def open(self): """ :return: """ self._open(self.base_url) log.logger.info('%s loading successed!' %self.base_url) return self.base_url # *loc 代表任意数量的位置参数 def findElement(self, *loc): """ 查找单一元素 :param loc: :return: """ try: WebDriverWait(self.driver,10).until(EC.visibility_of_element_located(loc)) # log.logger.info('The page of %s had already find the element %s'%(self,loc)) # return self.driver.find_element(*loc) except Exception as e: log.logger.exception('finding element timeout!, details' ,exc_info=True) raise e else: log.logger.info('The page of %s had already find the element %s' % (self, loc)) return self.driver.find_element(*loc) def findElements(self, *loc): """ 查找一组元素 :param loc: :return: """ try: WebDriverWait(self.driver,10).until(EC.visibility_of_element_located(loc)) # log.logger.info('The page of %s had already find the element %s' % (self, loc)) # return self.driver.find_elements(*loc) except Exception as e: log.logger.exception('finding element timeout!, details', exc_info=True) raise e else: log.logger.info('The page of %s had already find the element %s' % (self, loc)) return self.driver.find_elements(*loc) #输入数据 def inputValue(self, inputBox, value): """ 后期修改其他页面直接调用这个函数 :param inputBox: :param value: :return: """ inputB = self.findElement(*inputBox) try: inputB.clear() inputB.send_keys(value) except Exception as e: log.logger.exception('typing value error!', exc_info=True) raise e else: log.logger.info('inputValue:[%s] is receiveing value [%s]' % (inputBox, value)) # 获取元素数据 def getValue(self, *loc): """ :param loc: :return: """ element = self.findElement(*loc) try: value = element.text #return value except Exception: #element = self.find_element_re(*loc) value = element.get_attribute('value') log.logger.info('reading the element [%s] value [%s]' % (loc, value)) return value except: log.logger.exception('read value failed', exc_info=True) raise Exception else: log.logger.info('reading the element [%s] value [%s]' % (loc,value)) return value def getValues(self, *loc): """ :param loc: :return: """ value_list = [] try: for element in self.findElements(*loc): value = element.text value_list.append(value) except Exception as e: log.logger.exception('read value failed', exc_info=True) raise e else: log.logger.info('reading the element [%s] value [%s]'% (loc,value_list)) return value_list # 执行js脚本 def jScript(self,src): """ :param src: :return: """ try: self.driver.execute_script(src) except Exception as e: log.logger.exception('execute js script [%s] failed ' %src) raise e else: log.logger.info('execute js script [%s] successed ' %src) # 判断元素是否存在 def isElementExist(self, element): """ :param element: :return: """ try: WebDriverWait(self.driver, 10).until(EC.presence_of_element_located(element)) except: # log.logger.exception('The element [%s] not exist', exc_info=True) return False else: # log.logger.info('The element [%s] have existed!' %element) return True # 截图 def saveScreenShot(self, filename): """ :param filename: :return: """ list_value = [] list = filename.split('.') for value in list: list_value.append(value) if list_value[1] == 'png' or list_value[1] == 'jpg' or list_value[1] == 'PNG' or list_value[1] == 'JPG': if 'fail' in list_value[0].split('_'): try: self.driver.save_screenshot(os.path.join(conf.failImagePath, filename)) except Exception: log.logger.exception('save screenshot failed !', exc_info=True) else: log.logger.info('the file [%s] save screenshot successed under [%s]' % (filename, conf.failImagePath)) elif 'pass' in list_value[0]: try: self.driver.save_screenshot(os.path.join(conf.passImagePath, filename)) except Exception: log.logger.exception('save screenshot failed !', exc_info=True) else: log.logger.info( 'the file [%s] save screenshot successed under [%s]' % (filename, conf.passImagePath)) else: log.logger.info('save screenshot failed due to [%s] format incorrect' %filename) else: log.logger.info('the file name of [%s] format incorrect cause save screenshot failed, please check!' % filename) # 接受错误提示框 def accept(self, *loc): """ :return: """ self.findElement(*loc).click() log.logger.info('closed the error information fram successed!') # 点击按钮 def cBtn(self,button): btn = self.findElement(*button) try: btn.click() except Exception: log.logger.exception( 'can not click the button' ,exc_info=True) else: log.logger.info( 'page [%s] :clicking the button [%s]' % (sys._getframe().f_code.co_name ,button)) def clearValue(self,clear): ''' 清空输入项 :param clear: :return: ''' input_clear = self.findElement(*clear) try: input_clear.clear() except Exception: log.logger.exception( 'can not clear input', exc_info=True) else: log.logger.info( 'page [%s] :clearing input [%s]' % (sys._getframe().f_code.co_name, clear)) if __name__ == '__main__': pass
#单笔转账页面
''' Code description: Pay_Page Create time: Developer: ''' import time import sys import logging from selenium.webdriver.common.by import By from framfriend.test_case.models.log import Logger from framfriend.test_case.page_obj.base_page import BasePage,eleData log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO) class Pay_Page(BasePage): ''' 单笔支付 ''' #银农直联系统 Silverfarmers = (By.XPATH,eleData.readExcel(14,3)) #银农直联列表 Silverfarmersul = (By.XPATH,'//*[@id="sidebarTree_23_ul"]') #转账功能 pay = (By.XPATH,'//*[@id="sidebarTree_24"]') #转账功能列表 payul = (By.XPATH,'//*[@id="sidebarTree_24_ul"]') #单笔支付 singlePay = (By.XPATH,eleData.readExcel(226,3)) #按钮 button_list = [(By.XPATH, eleData.readExcel(238, 3)),#村居0 (By.XPATH, eleData.readExcel(239, 3)),#选择一项村居1 (By.XPATH, eleData.readExcel(240, 3)),#收款方2 (By.XPATH, eleData.readExcel(241, 3)),#选择一项收款方3 (By.XPATH, eleData.readExcel(242, 3)),#添加新收款方4 (By.XPATH, eleData.readExcel(243, 3)),#开始支付5 (By.XPATH, eleData.readExcel(244, 3)),#关闭支付6 (By.XPATH, eleData.readExcel(245, 3))]#确定支付7 #输入框 input_list = [(By.XPATH, eleData.readExcel(246, 3)),#收款方名称0 (By.NAME, eleData.readExcel(247, 3)),#收款方账号1 (By.NAME, eleData.readExcel(248, 3)),#收款方户名2 (By.XPATH, eleData.readExcel(249, 3)),#联行号3 (By.XPATH, eleData.readExcel(250, 3)),#金额4 (By.XPATH, eleData.readExcel(251, 3)),#摘要5 (By.XPATH, eleData.readExcel(252, 3))]#支付密码6 #验证信息 msg_list = [(By.XPATH, eleData.readExcel(253, 3)),#村居为空提示0 (By.XPATH, eleData.readExcel(254, 3)),#账号为空提示1 (By.XPATH, eleData.readExcel(255, 3)),#收款账号为空提示2 (By.XPATH, eleData.readExcel(256, 3)),#金额为空错误提示3 (By.XPATH, eleData.readExcel(257, 3)),#摘要为空提示4 (By.XPATH, eleData.readExcel(258, 3)),#收款账号错误提示5 (By.XPATH, eleData.readExcel(259, 3)),#收款账号为空提示6 (By.XPATH, eleData.readExcel(260, 3)),#收款户名为空提示7 (By.XPATH, eleData.readExcel(261, 3)),#联行号为空错误提示8 (By.XPATH, eleData.readExcel(262, 3)),#右上提示9 (By.XPATH, eleData.readExcel(263, 3)),#选择村居验证10 (By.XPATH, eleData.readExcel(264, 3)),#选择村居验证11 (By.XPATH, eleData.readExcel(265, 3)),#选择村居验证12 (By.XPATH, eleData.readExcel(266, 3)),#选择收款方验证13 (By.XPATH, eleData.readExcel(267, 3)),#选择收款方验证14 (By.XPATH, eleData.readExcel(268, 3)),#选择收款方验证15 (By.XPATH, eleData.readExcel(269, 3)),#选择收款方验证16 (By.XPATH, eleData.readExcel(270, 3)),#收款方为空提示17 (By.XPATH, eleData.readExcel(271, 3)),#确定支付窗口18 (By.XPATH, eleData.readExcel(272, 3)),#关闭支付验证19 (By.XPATH, eleData.readExcel(273, 3)),#点击添加新收款方验证20 (By.XPATH, '//*[@id="hasntOtherBank"]/div[4]/div/small[2]')]#新增收款方联行号错误 # 测试数据 valueList = ['967687572875767575', '811247857857', '1','123456','测试'] reason = time.strftime('%Y-%m-%d:%H-%M-%S') + '测试' def insinglePay(self): ''' 进入单笔支付页面 :return: ''' leftMenu = self.findElement(*self.menuList[0]) # 左侧菜单栏 leftMenu.find_element_by_id('sidebarTree_23_a').click() # 点击银农直联系统 time.sleep(1) Silverfarmersul = self.findElement(*self.Silverfarmersul) Silverfarmersul.find_element_by_xpath('//*[@id="sidebarTree_24_a"]').click() # 点击支付功能 time.sleep(1) payul = self.findElement(*self.payul) payul.find_element_by_xpath('//*[@id="sidebarTree_25_a"]').click()#点击单笔支付 time.sleep(1) log.logger.info('page[%s] :found the menu [%s] and [%s]' % ( sys._getframe().f_code.co_name, self.menuList[0], self.payul)) def cBtn(self, button): ''' 点击按钮 :return: ''' btn = self.findElement(*button) try: btn.click() except Exception: log.logger.exception('can not the button ', exc_info=True) raise else: log.logger.info( 'page[%s]:clicking the button [%s]' % (sys._getframe().f_code.co_name, button)) if __name__ == '__main__': pass
#单笔转账测试用例
''' Code description:单笔支付模块 testcase Create time: Developer: ''' import time from framfriend.test_case.models.myunittest import MyunitTest from framfriend.test_case.page_obj.pay_page import Pay_Page class Pay_Tc(MyunitTest): '''单笔支付模块用例''' def test_singlePay_1(self): '''选择村居验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1])#选择村居 msg1_1 = menu.isElementExist(menu.msg_list[10]) self.assertTrue(msg1_1,'显示账号') msg1_2 = menu.isElementExist(menu.msg_list[11]) self.assertTrue(msg1_2,'显示户名') msg1_3 = menu.isElementExist(menu.msg_list[12]) self.assertTrue(msg1_3,'显示联行号') def test_singlePay_2(self): '''选择收款方验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1])#选择村居 menu.cBtn(menu.button_list[2]) menu.cBtn(menu.button_list[3])#选择收款方 msg2_1 = menu.isElementExist(menu.msg_list[13]) self.assertTrue(msg2_1, '显示收款账号') msg2_2 = menu.isElementExist(menu.msg_list[14]) self.assertTrue(msg2_2, '显示户名') msg2_3 = menu.isElementExist(menu.msg_list[15]) self.assertTrue(msg2_3, '显示联行号') msg2_4 = menu.isElementExist(menu.msg_list[16]) self.assertTrue(msg2_4, '显示是否农商行') def test_singlePay_3(self): '''不输入内容点击开始支付验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[5])#点击开始支付 msg3_1 = menu.isElementExist(menu.msg_list[0]) if msg3_1: msgInfo3 = menu.getValue(*menu.msg_list[0]) self.assertEqual(msgInfo3,'不能为空','提示信息正确') msg3_2 = menu.isElementExist(menu.msg_list[3]) self.assertTrue(msg3_2, '出现提示信息') if msg3_2: msgInfo4 = menu.getValue(*menu.msg_list[3]) self.assertEqual(msgInfo4,'请输入有效的数字','提示信息正确') msg3_3 = menu.isElementExist(menu.msg_list[4]) self.assertTrue(msg3_3, '出现提示信息') if msg3_3: msgInfo5 = menu.getValue(*menu.msg_list[4]) self.assertEqual(msgInfo5,'不能为空','提示信息正确') def test_singlePay_4(self): '''不选择村居点击开始支付验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.inputValue(menu.input_list[4],menu.valueList[2]) menu.inputValue(menu.input_list[5],menu.reason) menu.cBtn(menu.button_list[5])#点击开始支付 msg4_1 = menu.isElementExist(menu.msg_list[0]) self.assertTrue(msg4_1, '出现提示信息') if msg4_1: msgInfo1 = menu.getValue(*menu.msg_list[0]) self.assertEqual(msgInfo1,'不能为空','提示信息正确') def test_singlePay_5(self): '''不选择收款方点击开始支付验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1]) # 选择村居 menu.inputValue(menu.input_list[4], menu.valueList[2])#输入金额 menu.inputValue(menu.input_list[5], menu.reason)#输入摘要 menu.cBtn(menu.button_list[5]) # 点击开始支付 msg5_1 = menu.isElementExist(menu.msg_list[17]) self.assertTrue(msg5_1, '收款方出现提示信息') if msg5_1: msgInfo1 = menu.getValue(*menu.msg_list[17]) self.assertEqual(msgInfo1, '不能为空', '提示信息正确') def test_singlePay_6(self): '''不输入金额点击开始支付验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1]) # 选择村居 menu.cBtn(menu.button_list[2]) menu.cBtn(menu.button_list[3]) # 选择收款方 menu.inputValue(menu.input_list[5], menu.reason) # 输入摘要 menu.cBtn(menu.button_list[5]) # 点击开始支付 msg6_1 = menu.isElementExist(menu.msg_list[3]) self.assertTrue(msg6_1, '金额出现提醒信息') if msg6_1: msgInfo = menu.getValue(*menu.msg_list[3]) self.assertEqual(msgInfo, '请输入有效的数字', '提示信息正确') def test_singlePay_7(self): '''不输入摘要点击开始支付验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1]) # 选择村居 menu.cBtn(menu.button_list[2]) menu.cBtn(menu.button_list[3]) # 选择收款方 menu.inputValue(menu.input_list[4], menu.valueList[2]) # 输入金额 menu.cBtn(menu.button_list[5]) # 点击开始支付 msg7_1 = menu.isElementExist(menu.msg_list[4]) self.assertTrue(msg7_1, '摘要出现提示信息') if msg7_1: msgInfo = menu.getValue(*menu.msg_list[4]) self.assertEqual(msgInfo, '不能为空', '提示信息正确') def test_singlePay_8(self): '''输入错误金额点击开始支付验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1]) # 选择村居 menu.cBtn(menu.button_list[2]) menu.cBtn(menu.button_list[3]) # 选择收款方 menu.inputValue(menu.input_list[4], menu.reason) # 输入错误金额 menu.inputValue(menu.input_list[5], menu.valueList[4]) # 输入摘要 menu.cBtn(menu.button_list[5]) # 点击开始支付 msg8_1 = menu.isElementExist(menu.msg_list[3]) self.assertTrue(msg8_1, '金额出现提示信息') if msg8_1: msgInfo = menu.getValue(*menu.msg_list[3]) self.assertEqual(msgInfo, '请输入有效的数字', '提示信息正确') def test_singlePay_9(self): '''正确输入点击开始支付验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1]) # 选择村居 menu.cBtn(menu.button_list[2]) menu.cBtn(menu.button_list[3]) # 选择收款方 menu.inputValue(menu.input_list[4], menu.valueList[2]) # 输入金额 menu.inputValue(menu.input_list[5], menu.valueList[4]) # 输入摘要 menu.cBtn(menu.button_list[5]) # 点击开始支付 msg9_1 = menu.isElementExist(menu.msg_list[18]) self.assertTrue(msg9_1, '弹出确认支付窗口') def test_singlePay_10(self): '''不输入支付密码确定验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1]) # 选择村居 menu.cBtn(menu.button_list[2]) menu.cBtn(menu.button_list[3]) # 选择收款方 menu.inputValue(menu.input_list[4], menu.valueList[2]) # 输入金额 menu.inputValue(menu.input_list[5], menu.valueList[4]) # 输入摘要 menu.cBtn(menu.button_list[5]) # 点击开始支付 menu.cBtn(menu.button_list[7])#点击确定按钮 msg10_1 = menu.isElementExist(menu.msg_list[9]) self.assertTrue(msg10_1, '提示信息') def test_singlePay_11(self): '''输入错误支付密码确定验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1]) # 选择村居 menu.cBtn(menu.button_list[2]) menu.cBtn(menu.button_list[3]) # 选择收款方 menu.inputValue(menu.input_list[4], menu.valueList[2]) # 输入金额 menu.inputValue(menu.input_list[5], menu.valueList[4]) # 输入摘要 menu.cBtn(menu.button_list[5]) # 点击开始支付 menu.inputValue(menu.input_list[6],menu.valueList[2])#输入错误密码验证 menu.cBtn(menu.button_list[7]) # 点击确定按钮 msg11_1 = menu.isElementExist(menu.msg_list[9]) self.assertTrue(msg11_1, '提示信息') def test_singlePay_12(self): '''输入正确支付密码确定验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1]) # 选择村居 menu.cBtn(menu.button_list[2]) menu.cBtn(menu.button_list[3]) # 选择收款方 menu.inputValue(menu.input_list[4], menu.valueList[2]) # 输入金额 menu.inputValue(menu.input_list[5], menu.valueList[4]) # 输入摘要 menu.cBtn(menu.button_list[5]) # 点击开始支付 menu.inputValue(menu.input_list[6], menu.valueList[3]) # 输入密码 menu.cBtn(menu.button_list[7]) # 点击确定按钮 msg12_1 = menu.isElementExist(menu.msg_list[9]) self.assertTrue(msg12_1, '提示信息') def test_singlePay_13(self): '''关闭支付验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1]) # 选择村居 menu.cBtn(menu.button_list[2]) menu.cBtn(menu.button_list[3]) # 选择收款方 menu.inputValue(menu.input_list[4], menu.valueList[2]) # 输入金额 menu.inputValue(menu.input_list[5], menu.reason) # 输入摘要 menu.cBtn(menu.button_list[5]) # 点击开始支付 menu.inputValue(menu.input_list[6], menu.valueList[3]) # 输入密码 menu.cBtn(menu.button_list[6]) # 点击关闭按钮 msg13_1 = menu.isElementExist(menu.msg_list[19]) self.assertTrue(msg13_1, '关闭支付窗口') def test_singlePay_14(self): '''点击添加新收款方验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[4])#点击添加新收款方 msg14_1 = menu.isElementExist(menu.msg_list[20]) self.assertTrue(msg14_1, '窗口验证') def test_singlePay_15(self): '''不输入新收款方内容支付验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1]) # 选择村居 time.sleep(1) menu.cBtn(menu.button_list[4]) # 点击添加新收款方 menu.inputValue(menu.input_list[4], menu.valueList[2]) # 输入金额 menu.inputValue(menu.input_list[5], menu.reason) # 输入摘要 menu.cBtn(menu.button_list[5]) # 点击开始支付 msg15_2 = menu.isElementExist(menu.msg_list[6]) self.assertTrue(msg15_2,'收款账号出现提示信息') if msg15_2: msgInfo2 = menu.getValue(*menu.msg_list[6]) self.assertEqual(msgInfo2, '不能为空', '提示信息正确') msg15_3 = menu.isElementExist(menu.msg_list[7]) self.assertTrue(msg15_3,'收款户名出现提示信息') if msg15_3: msgInfo3 = menu.getValue(*menu.msg_list[7]) self.assertEqual(msgInfo3, '不能为空', '提示信息正确') msg15_4 = menu.isElementExist(menu.msg_list[8]) self.assertTrue(msg15_4,'联行号出现提示信息') if msg15_4: msgInfo4 = menu.getValue(*menu.msg_list[8]) self.assertEqual(msgInfo4, '不能为空', '提示信息正确') def test_singlePay_16(self): '''不输入新收款方账号支付验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1]) # 选择村居 time.sleep(1) menu.cBtn(menu.button_list[4]) # 点击添加新收款方 menu.inputValue(menu.input_list[2], menu.reason) # 输入户名 menu.inputValue(menu.input_list[3], menu.valueList[1]) # 输入联行号 menu.inputValue(menu.input_list[4], menu.valueList[2]) # 输入金额 menu.inputValue(menu.input_list[5], menu.reason) # 输入摘要 menu.cBtn(menu.button_list[5]) # 点击开始支付 msg15_2 = menu.isElementExist(menu.msg_list[6]) self.assertTrue(msg15_2, '收款账号出现提示信息') if msg15_2: msgInfo2 = menu.getValue(*menu.msg_list[6]) self.assertEqual(msgInfo2, '不能为空', '提示信息正确') def test_singlePay_17(self): '''输入不规则新收款方账号支付验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1]) # 选择村居 time.sleep(1) menu.cBtn(menu.button_list[4]) # 点击添加新收款方 menu.inputValue(menu.input_list[1], menu.reason) # 输入账号 menu.inputValue(menu.input_list[2], menu.reason) # 输入户名 menu.inputValue(menu.input_list[3], menu.valueList[1]) # 输入联行号 menu.inputValue(menu.input_list[4], menu.valueList[2]) # 输入金额 menu.inputValue(menu.input_list[5], menu.reason) # 输入摘要 menu.cBtn(menu.button_list[5]) # 点击开始支付 msg15_2 = menu.isElementExist(menu.msg_list[5]) self.assertTrue(msg15_2, '收款账号出现提示信息') if msg15_2: msgInfo2 = menu.getValue(*menu.msg_list[5]) self.assertEqual(msgInfo2, '请输入有效的数字', '提示信息正确') def test_singlePay_18(self): '''不输入新收款方户名支付验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1]) # 选择村居 time.sleep(1) menu.cBtn(menu.button_list[4]) # 点击添加新收款方 menu.inputValue(menu.input_list[1], menu.valueList[0]) # 输入账号 menu.inputValue(menu.input_list[3], menu.valueList[1]) # 输入联行号 menu.inputValue(menu.input_list[4], menu.valueList[2]) # 输入金额 menu.inputValue(menu.input_list[5], menu.reason) # 输入摘要 menu.cBtn(menu.button_list[5]) # 点击开始支付 msg18_1 = menu.isElementExist(menu.msg_list[7]) self.assertTrue(msg18_1, '收款户名提示信息') if msg18_1: msgInfo = menu.getValue(*menu.msg_list[7]) self.assertEqual(msgInfo, '不能为空', '提示信息正确') def test_singlePay_19(self): '''输入错误新增联行号支付验证''' menu = Pay_Page(self.driver) # 实例化单笔支付页面 self.login.loginFunc() # 登录 menu.insinglePay() # 进入单笔支付页面 time.sleep(2) menu.cBtn(menu.button_list[0]) menu.cBtn(menu.button_list[1]) # 选择村居 time.sleep(1) menu.cBtn(menu.button_list[4]) # 点击添加新收款方 menu.inputValue(menu.input_list[1], menu.valueList[0]) # 输入新增账号 menu.inputValue(menu.input_list[2], menu.reason) # 输入户名 menu.inputValue(menu.input_list[3], menu.reason) # 输入错误联行号 menu.inputValue(menu.input_list[4], menu.valueList[2]) # 输入金额 menu.inputValue(menu.input_list[5], menu.reason) # 输入摘要 menu.cBtn(menu.button_list[5]) # 点击开始支付 msg20_1 = menu.isElementExist(menu.msg_list[21]) self.assertTrue(msg20_1, '联行号错误信息') if msg20_1: msgInfo = menu.getValue(*menu.msg_list[21]) self.assertEqual(msgInfo, '请输入有效的数字', '提示信息正确') if __name__ == '__main__': pass
#执行测试用例
#! user/bin/python ''' Code description:auto run test case Create time: Developer: ''' import unittest import time from BeautifulReport import BeautifulReport from framfriend.config.conf import * from framfriend.test_case.models.sendmail import SendMail, getReceiverInfo from framfriend.test_case.models.testreport import testreport # TODO : will be use jenkins continuous intergration teachnology manage the auto project if __name__ == '__main__': # currTime = time.strftime('%Y-%m-%d %H_%M_%S') # filename = currTime + '.html' # # 第一种测试报告 # test_suite = unittest.defaultTestLoader.discover(tcPath, pattern='*Tc.py') # result = BeautifulReport(test_suite) # result.report(filename= filename, description='test report', log_psath=reportPath) # # 第二种测试报告 runner, fp, fileName = testreport() test_suite = unittest.defaultTestLoader.discover(tcPath, pattern='registerTc.py') runner.run(test_suite) fp.close() # read_msg = getReceiverInfo(r'E:python_testframfriend_Test_ProjectframfrienddataTestDatamail_receiver.txt') # sendmail = SendMail(read_msg) # sendmail.sendEmail(fileName)
报告展示
总结
年前,第一个实战项目,作为一个初学者学到了不少东西。有很多不足的地方,望大佬指导!现在在学习pytest,就当记笔记啦,过段时间再记录一下学习pytest心得。