赞
踩
前言
之前的文章说过, 要写一篇自动化实战的文章, 这段时间比较忙再加回家过清明一直没有更新,今天整理一下实战项目的代码共大家学习。(注:项目是针对我们公司内部系统的测试,只能内部网络访问,外部网络无法访问)
问:
1.外部网络无法访问,代码也无法运行,那还看这个项目有啥用
2.如何学习本项目
3.如何学习自动化测试(python+selenium)
答:
1.其实代码并不重要,希望大家完完整整的看完这个项目后,自己会有思路有想法,学会这个项目的框架结构和设计思想,把这些能应用到自己的项目中,那么目的就达到了(项目中涉及到的一些公共方法是可以单独运行的,大家可以拿来执行用到自己的项目中)
2.首先希望大家带着目标来学习这个项目1. 项目的目录结构(每个目录中存放什么东西)2.项目如何使用框架(本项目使用的是unittest框架)3.设计模式是如何应用在本项目中的(本项目应用page
object设计模式)
3.个人而言
1)如果你没有任何的编程基础,建议先学习一门编程语言,包括环境的搭建,自己动手写代码,遇到问题多想多琢磨,这样一定会加深自己的印象。如果你有一定的编程基础那么直接看看python的基础语法和selenium就ok(我的自动化测试经验也有限,可能给不了大家太多的建议
,当然会的越多越好 呵!)
2)自己动手搭个框架,手写一个实战的项目,这时候你会发现你还有好多东西不会,那么线路就来了,哪里不会就去学哪里,边学边写,直到你的项目完成,再次回味就会发现你会了好多,当然不会的东西更多了因为你的思路慢慢的扩宽了,你会想到无人值守,集成等等的想法
3)可以参加培训机构的培训,说实话现在的培训机构越来越多,个人认为有些机构的老师确实是没什么水准的,因为他们教的是基础没有太多的拔高内容,但是有一点是好了,你可以很系统的学习一系列的自动化知识
ok 说了很多废话,大家不要介意!直接上项目
Retail_TestPro
Docs# 存放项目的相关文档
01测试计划
02测试大纲
03测试用例
04测试报告
05测试进度
06技术文档
07测试申请
Package# 存放第三方插件
HTMLTestRunner.py
Retail
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# 测试模块
Activerule_page.py
Base_page.py
Company_page.py
Createrule_page.py
Memberquery_page.py
Modifypw_page.py
Pointquery_page.py
ActiveRuleTc.py
CompanyQueryTc.py
CreateRuleTc.py
LoginTc.py
MemberQueryTc.py
ModifyPwTc.py
PointQueryTc.py
runTc.py# 执行测试用例
我们在写自动化测试项目的时候一定要想好你的脚本都要哪些功能,页面元素平凡改动的时候是否需要大批量的修改脚本,及测试不同数据时是否也要修改脚本,那么能想到这些我们的初始目标差不多就有了
config.ini # 存放项目跟路径
- [project]
-
- project_path = D:\Petrochina_Retail_Test_Project
conf.py
- 1 '''
- 2 Code description:read config.ini, get path
- 3 Create time:
- 4 Developer:
- 5 '''
- 6 import os
- 7 import sys
- 8 from retail.test_case.models.doconfIni import DoConfIni
- 9
- 10 # 获取当前路径
- 11 currPath= \
- 12 os.path.split(os.path.realpath(__file__))[0]
- 13
- 14 # 读配置文件获取项目路径
- 15 readConfig = \
- 16 DoConfIni()
- 17 proPath = \
- 18 readConfig.getConfValue(os.path.join(currPath,'config.ini'),'project','project_path')
- 19
- 20 # 获取日志路径
- 21 logPath= \
- 22 os.path.join(proPath,'retail','report','Log')
- 23
- 24 # 测试用例路径
- 25 tcPath = \
- 26 os.path.join(proPath,'retail','test_case')
- 27
- 28 # 获取报告路径
- 29 reportPath= \
- 30 os.path.join(proPath,'retail','report','TestReport')
- 31
- 32 # 获取测试数据路径
- 33 dataPath= \
- 34 os.path.join(proPath,'retail','data','TestData')
- 35
- 36 # 保存截图路径
- 37 # 错误截图
- 38 failImagePath = os.path.join(proPath, 'retail', 'report', 'image','fail')
- 39 # 成功截图
- 40 passImagePath = os.path.join(proPath, 'retail', 'report', 'image','pass')
- 41
- 42 # 被调函数名称
- 43 funcName = sys._getframe().f_code.co_name
- 44 # 被调函数所在行号
- 45 funcNo = sys._getframe().f_back.f_lineno
- 46
- 47 # 被调函数所在文件名称
- 48 funcFile= sys._getframe().f_code.co_filename
elementData.xlsx # 存放所有的测试数据及元素
一个excel文件,不方便贴里面内容(先过,别管里面是啥了 哈哈 后面再找吧)
mail_receiver.txt# 存放邮件接收者的账号 , 可以添加多个账号以‘,’号分割
**@qq.com
公共方法models下面的文件:
doconfini.py
- 1 '''
- 2 Code description:read conf file
- 3 Create time:
- 4 Developer:
- 5 '''
- 6
- 7 import logging
- 8 import configparser
- 9 from retail.config.conf import *
- 10 from retail.test_case.models.log import Logger
- 11
- 12 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)
- 13 class DoConfIni(object):
- 14
- 15 def __init__(self):
- 16 """
- 17
- 18 :param filename:
- 19 """
- 20 self.cf = configparser.ConfigParser()
- 21
- 22 # 从ini文件中读数据
- 23 def getConfValue(self,filename,section,name):
- 24 """
- 25
- 26 :param config:
- 27 :param name:
- 28 :return:
- 29 """
- 30 try:
- 31 self.cf.read(filename)
- 32 value = self.cf.get(section,name)
- 33 except Exception as e:
- 34 log.logger.exception('read file [%s] for [%s] failed , did not get the value' %(filename,section))
- 35 raise e
- 36 else:
- 37 log.logger.info('read excel value [%s] successed! ' %value)
- 38 return value
- 39 # 向ini文件中写数据
- 40 def writeConfValue(self,filename, section, name, value):
- 41 """
- 42
- 43 :param section: section
- 44 :param name: value name
- 45 :param value: value
- 46 :return: none
- 47 """
- 48 try:
- 49 self.cf.add_section(section)
- 50 self.cf.set(section, name, value)
- 51 self.cf.write(open(filename, 'w'))
- 52 except Exception :
- 53 log.logger.exception('section %s has been exist!' %section)
- 54 raise configparser.DuplicateSectionError(section)
- 55 else:
- 56 log.logger.info('write section'+section+'with value '+value+' successed!')
- 57
- 58 if __name__ == '__main__':
- 59 file_path = currPath
- 60 print(file_path)
- 61 read_config = DoConfIni()
- 62
- 63 value = read_config.getConfValue(os.path.join(currPath,'config.ini'),'project','project_path')
- 64 print(value)
- 65
- 66 read_config.writeConfValue(os.path.join(currPath,'config.ini'),'tesesection', 'name', 'hello word')
doexcel.py
- 1 '''
- 2 Code description:read excel.xlsx, get values
- 3 Create time:
- 4 Developer:
- 5 '''
- 6
- 7 import xlrd
- 8 import os
- 9 import logging
- 10 from retail.config import conf
- 11 from retail.test_case.models.log import Logger
- 12
- 13 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)
- 14
- 15 class ReadExcel(object):
- 16
- 17 def __init__(self,fileName='elementDate.xlsx',sheetName='elementsInfo'):
- 18 """
- 19
- 20 :param fileName:
- 21 :param sheetName:
- 22 """
- 23 try:
- 24 self.dataFile = os.path.join(conf.dataPath, fileName)
- 25 self.workBook = xlrd.open_workbook(self.dataFile)
- 26 self.sheetName = self.workBook.sheet_by_name(sheetName)
- 27 except Exception:
- 28 log.logger.exception('init class ReadExcel fail', exc_info=True)
- 29 raise
- 30 else:
- 31 log.logger.info('initing class ReadExcel')
- 32 # 读excel中的数据
- 33 def readExcel(self,rownum,colnum):
- 34 """
- 35
- 36 :param rownum:
- 37 :param colnum:
- 38 :return:
- 39 """
- 40 try:
- 41 value = self.sheetName.cell(rownum,colnum).value
- 42 except Exception:
- 43 log.logger.exception('read value from excel file fail', exc_info=True)
- 44 raise
- 45 else:
- 46 log.logger.info('reading value [%s] from excel file [%s] completed' %(value, self.dataFile))
- 47 return value
- 48
- 49 if __name__ == '__main__':
- 50 cellValue = ReadExcel().readExcel(1,3)
- 51 print((cellValue))
log.py
- 1 '''
- 2 Code description:log info
- 3 Create time:
- 4 Developer:
- 5 '''
- 6
- 7 import logging
- 8 import time
- 9
- 10
- 11 class Logger(object):
- 12 def __init__(self, logger, CmdLevel=logging.INFO, FileLevel=logging.INFO):
- 13 """
- 14
- 15 :param logger:
- 16 :param CmdLevel:
- 17 :param FileLevel:
- 18 """
- 19 self.logger = logging.getLogger(logger)
- 20 self.logger.setLevel(logging.DEBUG) # 设置日志输出的默认级别
- 21 # 日志输出格式
- 22 fmt = logging.Formatter('%(asctime)s - %(filename)s:[%(lineno)s] - [%(levelname)s] - %(message)s')
- 23 # 日志文件名称
- 24 # self.LogFileName = os.path.join(conf.log_path, "{0}.log".format(time.strftime("%Y-%m-%d")))# %H_%M_%S
- 25 currTime = time.strftime("%Y-%m-%d")
- 26 self.LogFileName = r'D:\Petrochina_Retail_Test_Project\retail\report\Log\log'+currTime+'.log'
- 27 # 设置控制台输出
- 28 # sh = logging.StreamHandler()
- 29 # sh.setFormatter(fmt)
- 30 # sh.setLevel(CmdLevel)# 日志级别
- 31
- 32 # 设置文件输出
- 33 fh = logging.FileHandler(self.LogFileName)
- 34 fh.setFormatter(fmt)
- 35 fh.setLevel(FileLevel)# 日志级别
- 36
- 37 # self.logger.addHandler(sh)
- 38 self.logger.addHandler(fh)
- 39
- 40 # def debug(self, message):
- 41 # """
- 42 #
- 43 # :param message:
- 44 # :return:
- 45 # """
- 46 # self.logger.debug(message)
- 47 #
- 48 # def info(self,message):
- 49 # """
- 50 #
- 51 # :param message:
- 52 # :return:
- 53 # """
- 54 # self.logger.info(message)
- 55 #
- 56 # def warn(self,message):
- 57 # """
- 58 #
- 59 # :param message:
- 60 # :return:
- 61 # """
- 62 # self.logger.warning(message)
- 63 #
- 64 # def error(self,message):
- 65 # """
- 66 #
- 67 # :param message:
- 68 # :return:
- 69 # """
- 70 # self.logger.error(message)
- 71 #
- 72 # def criti(self,message):
- 73 # """
- 74 #
- 75 # :param message:
- 76 # :return:
- 77 # """
- 78 # self.logger.critical(message)
- 79
- 80 if __name__ == '__main__':
- 81 logger = Logger("fox",CmdLevel=logging.DEBUG, FileLevel=logging.DEBUG)
- 82 logger.logger.debug("debug")
- 83 logger.logger.log(logging.ERROR,'%(module)s %(info)s',{'module':'log日志','info':'error'}) #ERROR,log日志 error
sendmail.py
- 1 '''
- 2 Code description:send email
- 3 Create time:
- 4 Developer:
- 5 '''
- 6
- 7 import smtplib
- 8 from email.mime.text import MIMEText
- 9 from email.header import Header
- 10 import os
- 11 from retail.config import conf
- 12 from retail.test_case.models.log import Logger
- 13
- 14 log = Logger(__name__)
- 15 # 邮件发送接口
- 16 class SendMail(object):
- 17 '''
- 18 邮件配置信息
- 19 '''
- 20 def __init__(self,
- 21 receiver,
- 22 subject='Retail 系统测试报告',
- 23 server='smtp.qq.com',
- 24 fromuser='281754043@qq.com',
- 25 frompassword='gifhhsbgqyovbhhc',
- 26 sender='281754043@qq.com'):
- 27 """
- 28
- 29 :param receiver:
- 30 :param subject:
- 31 :param server:
- 32 :param fromuser:
- 33 :param frompassword:
- 34 :param sender:
- 35 """
- 36
- 37 self._server = server
- 38 self._fromuser = fromuser
- 39 self._frompassword = frompassword
- 40 self._sender = sender
- 41 self._receiver = receiver
- 42 self._subject = subject
- 43
- 44 def sendEmail(self, fileName):
- 45 """
- 46
- 47 :param filename:
- 48 :return:
- 49 """
- 50 # 打开报告文件读取文件内容
- 51 try:
- 52 f = open(os.path.join(conf.reportPath, fileName), 'rb')
- 53 fileMsg = f.read()
- 54 except Exception:
- 55 log.logger.exception('open or read file [%s] failed,No such file or directory: %s' %(fileName, conf.reportPath))
- 56 log.logger.info('open and read file [%s] successed!' %fileName)
- 57 else:
- 58 f.close()
- 59 # 邮件主题
- 60 subject = 'Python test report' #
- 61 # 邮件设置
- 62 msg = MIMEText(fileMsg, 'html', 'utf-8')
- 63 msg['subject'] = Header(subject, 'utf-8')
- 64 msg['from'] = self._sender
- 65 # 连接服务器,登录服务器,发送邮件
- 66 try:
- 67 smtp = smtplib.SMTP()
- 68 smtp.connect(self._server)
- 69
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。