前言
之前的文章說過, 要寫一篇自動化實(shí)戰(zhàn)的文章, 這段時(shí)間比較忙再加回家過清明一直沒有更新,今天整理一下實(shí)戰(zhàn)項(xiàng)目的代碼共大家學(xué)習(xí)。(注:項(xiàng)目是針對我們公司內(nèi)部系統(tǒng)的測試,只能內(nèi)部網(wǎng)絡(luò)訪問,外部網(wǎng)絡(luò)無法訪問)
問:
1.外部網(wǎng)絡(luò)無法訪問,代碼也無法運(yùn)行,那還看這個(gè)項(xiàng)目有啥用
2.如何學(xué)習(xí)本項(xiàng)目
3.如何學(xué)習(xí)自動化測試(python+selenium)
答:
1.其實(shí)代碼并不重要,希望大家完完整整的看完這個(gè)項(xiàng)目后,自己會有思路有想法,學(xué)會這個(gè)項(xiàng)目的框架結(jié)構(gòu)和設(shè)計(jì)思想,把這些能應(yīng)用到自己的項(xiàng)目中,那么目的就達(dá)到了(項(xiàng)目中涉及到的一些公共方法是可以單獨(dú)運(yùn)行的,大家可以拿來執(zhí)行用到自己的項(xiàng)目中)
2.首先希望大家?guī)е繕?biāo)來學(xué)習(xí)這個(gè)項(xiàng)目1. 項(xiàng)目的目錄結(jié)構(gòu)(每個(gè)目錄中存放什么東西)2.項(xiàng)目如何使用框架(本項(xiàng)目使用的是unittest框架)3.設(shè)計(jì)模式是如何應(yīng)用在本項(xiàng)目中的(本項(xiàng)目應(yīng)用page
object設(shè)計(jì)模式)
3.個(gè)人而言
1)如果你沒有任何的編程基礎(chǔ),建議先學(xué)習(xí)一門編程語言,包括環(huán)境的搭建,自己動手寫代碼,遇到問題多想多琢磨,這樣一定會加深自己的印象。如果你有一定的編程基礎(chǔ)那么直接看看python的基礎(chǔ)語法和selenium就ok(我的自動化測試經(jīng)驗(yàn)也有限,可能給不了大家太多的建議
,當(dāng)然會的越多越好 呵!)
2)自己動手搭個(gè)框架,手寫一個(gè)實(shí)戰(zhàn)的項(xiàng)目,這時(shí)候你會發(fā)現(xiàn)你還有好多東西不會,那么線路就來了,哪里不會就去學(xué)哪里,邊學(xué)邊寫,直到你的項(xiàng)目完成,再次回味就會發(fā)現(xiàn)你會了好多,當(dāng)然不會的東西更多了因?yàn)槟愕乃悸仿臄U(kuò)寬了,你會想到無人值守,集成等等的想法
3)可以參加培訓(xùn)機(jī)構(gòu)的培訓(xùn),說實(shí)話現(xiàn)在的培訓(xùn)機(jī)構(gòu)越來越多,個(gè)人認(rèn)為有些機(jī)構(gòu)的老師確實(shí)是沒什么水準(zhǔn)的,因?yàn)樗麄兘痰氖腔A(chǔ)沒有太多的拔高內(nèi)容,但是有一點(diǎn)是好了,你可以很系統(tǒng)的學(xué)習(xí)一系列的自動化知識
ok 說了很多廢話,大家不要介意!直接上項(xiàng)目
?
項(xiàng)目簡介
- 項(xiàng)目名稱:**公司電子零售會員系統(tǒng)
- 項(xiàng)目目的:實(shí)現(xiàn)電子零售會員系統(tǒng)項(xiàng)目自動化測試執(zhí)行
- 項(xiàng)目版本:v1.0
項(xiàng)目目錄
Retail_TestPro
Docs# 存放項(xiàng)目的相關(guān)文檔
01測試計(jì)劃
02測試大綱
03測試用例
04測試報(bào)告
05測試進(jìn)度
06技術(shù)文檔
07測試申請
Package# 存放第三方插件
HTMLTestRunner.py
Retail
Config
init.py
Conf.py# 讀配置文件獲取項(xiàng)目跟目錄路徑 并獲取所有欲使用的目錄文件的路徑
Config.ini# 存放項(xiàng)目跟目錄的路徑
Data
TestData
init.py
elementDate.xlsx# 存放項(xiàng)目中所有的元素信息及測試數(shù)據(jù)
Email_receiver.txt# 存放郵件的接受者信息
Report# 測試報(bào)告
Image
Fail# 存放用例執(zhí)行失敗時(shí)的截圖
Pass# 存放用例執(zhí)行成功時(shí)的截圖
Log# 存放用例執(zhí)行過程中的log信息
TestReport# 存放測試用例執(zhí)行完成后生成的測試報(bào)告
Test_case# 測試用例信息
Models # 存放一些公共方法
Doconfini.py# 讀配置文件
Doexcel.py# 讀excel文件
Driver.py# 存放driver
Log.py# 生成log
Myunit.py# 繼承unittest.Testcase
Sendmail.py# 發(fā)送郵件
Strhandle.py# 字符串處理
Tcinfo.py# 測試用例基本信息
Testreport.py# 測試報(bào)告
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# 執(zhí)行測試用例
項(xiàng)目環(huán)境
- 本版
- python 36
- pip insatll selenium
- PyCharm 2017.2.4
- Windows 10 10.0
- HTMLTestRunner.py
項(xiàng)目框架
- unittest單元測試框架
- pageobject 設(shè)計(jì)模式
- UI對象庫思想
項(xiàng)目設(shè)計(jì)
- 一個(gè)模塊(被測項(xiàng)目的頁面)對應(yīng)一個(gè)py文件及一個(gè)測試類(測試文件)
- 每一個(gè)測試頁面(系統(tǒng)的頁面)中存儲頁面元素及此頁面中涉及到的功能
- 每一個(gè)用例組合在一個(gè)測試類里面生成一個(gè)py文件
項(xiàng)目目標(biāo)
我們在寫自動化測試項(xiàng)目的時(shí)候一定要想好你的腳本都要哪些功能,頁面元素平凡改動的時(shí)候是否需要大批量的修改腳本,及測試不同數(shù)據(jù)時(shí)是否也要修改腳本,那么能想到這些我們的初始目標(biāo)差不多就有了
- 生成測試用例執(zhí)行結(jié)果報(bào)告
- 生成測試用例執(zhí)行日志
- 用例執(zhí)行失敗或者執(zhí)行完成后自動發(fā)送郵件報(bào)告
- 用例執(zhí)行失敗或者成功時(shí)截取圖片
- 數(shù)據(jù)驅(qū)動(讀取測試數(shù)據(jù),減少腳本維護(hù)成本)
?
項(xiàng)目代碼
config.ini # 存放項(xiàng)目跟路徑
[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 # 獲取當(dāng)前路徑
11 currPath= \
12 os.path.split(os.path.realpath(__file__))[0]
13
14 # 讀配置文件獲取項(xiàng)目路徑
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 # 獲取報(bào)告路徑
29 reportPath= \
30 os.path.join(proPath,'retail','report','TestReport')
31
32 # 獲取測試數(shù)據(jù)路徑
33 dataPath= \
34 os.path.join(proPath,'retail','data','TestData')
35
36 # 保存截圖路徑
37 # 錯(cuò)誤截圖
38 failImagePath = os.path.join(proPath, 'retail', 'report', 'image','fail')
39 # 成功截圖
40 passImagePath = os.path.join(proPath, 'retail', 'report', 'image','pass')
41
42 # 被調(diào)函數(shù)名稱
43 funcName = sys._getframe().f_code.co_name
44 # 被調(diào)函數(shù)所在行號
45 funcNo = sys._getframe().f_back.f_lineno
46
47 # 被調(diào)函數(shù)所在文件名稱
48 funcFile= sys._getframe().f_code.co_filename
elementData.xlsx # 存放所有的測試數(shù)據(jù)及元素
一個(gè)excel文件,不方便貼里面內(nèi)容(先過,別管里面是啥了 哈哈 后面再找吧)
mail_receiver.txt# 存放郵件接收者的賬號 , 可以添加多個(gè)賬號以‘,’號分割
**@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文件中讀數(shù)據(jù)
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文件中寫數(shù)據(jù)
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中的數(shù)據(jù)
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文章來源:http://www.zghlxwxcb.cn/news/detail-642766.html
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) # 設(shè)置日志輸出的默認(rèn)級別
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 # 設(shè)置控制臺輸出
28 # sh = logging.StreamHandler()
29 # sh.setFormatter(fmt)
30 # sh.setLevel(CmdLevel)# 日志級別
31
32 # 設(shè)置文件輸出
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文章來源地址http://www.zghlxwxcb.cn/news/detail-642766.html
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 # 郵件發(fā)送接口
16 class SendMail(object):
17 '''
18 郵件配置信息
19 '''
20 def __init__(self,
21 receiver,
22 subject='Retail 系統(tǒng)測試報(bào)告',
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 # 打開報(bào)告文件讀取文件內(nèi)容
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 # 郵件設(shè)置
62 msg = MIMEText(fileMsg, 'html', 'utf-8')
63 msg['subject'] = Header(subject, 'utf-8')
64 msg['from'] = self._sender
65 # 連接服務(wù)器,登錄服務(wù)器,發(fā)送郵件
66 try:
67 smtp = smtplib.SMTP()
68 smtp.connect(self._server)
69
到了這里,關(guān)于Python+selenium自動化測試實(shí)戰(zhàn)項(xiàng)目(全面,完整,詳細(xì))的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!