python介面自動化(四十二)- 專案結構設計之大結局(超詳解)
簡介
這一篇主要是將前邊的所有知識做一個整合,把各種各樣的磚塊---模組(post請求,get請求,logging,引數關聯,介面封裝等等)壘起來,搭建一個房子。並且有很多小夥伴對於介面專案測試的框架一籌莫展,吵吵著什麼時候才可以看到一篇相對於比較完整的專案原始碼,但是由於完整的專案屬於公司內部的程式碼,這個是說句大實話是沒法分享的,這個想必大家都知道吧,不知道入職的時候都簽過保密協議吧。所以由於種種原因沒辦法給小夥伴們分享公司內部的專案原始碼,就算別人分享了,也只適用於本公司內部的業務。你拿過來也不能用的,需要修修補補。所以用例的程式碼還是得自己去一個個寫,這個巨集哥只能分享專案框架,自己在框架裡新增自己公司的業務測試用例,使她變的豐滿充實,適合自己公司的業務。希望對小夥伴們有所指導或者是啟發,好了時間不早了,廢話少說,還是儘快進入今天的主題吧---介面專案測試結構(框架)設計。
一、專案結構
1、新建一個工程(一定要建立工程),工程名稱自己定義,如:hongge_jiekou
2、在工程的跟目錄新建一個指令碼:run_main.py,用來執行全部用例
3、在工程下建立以下幾個pakage包:
--case:這個包放test開頭的測試用例,也可以放一些封裝介面的方法,如:login(如果封裝的介面比較多,也可以單獨放一個包,可以命名為:framework,當然了可以隨便但是要見名知義,不要奇葩、不要關鍵字等等)
--common:這個包放一些公共的方法,如:讀取excel檔案方法,讀取mysql、oracle,logger.py這個是封裝日誌的輸入
--config:cfg.ini這裡是配置檔案,如郵箱的一些引數:收件人,發件人,密碼等,readConfig.py用於讀取配置檔案
--logs:這裡存放日誌資訊
--report:這裡存放測試報告
二、run_main
第一步:用discover方法載入所有的測試用例
1、cur_path這個引數是讀取當前這個指令碼的真實路徑,也就是run_main.py的真實路徑
2、caseName="case"這個case是存放測試用例的資料夾,如果沒有的話,自動建立。如果想執行其它資料夾的用例,就改下caseName這個引數值
3、rule="test*.py"這個是匹配用例指令碼名稱的規則,預設匹配test開頭的所有用例
第二步:生成HTML報告
1.把上一步載入到用例的引數傳入這個函式,測試報告的檔名稱預設report資料夾:reportName="report
2.如果沒有這個report資料夾也沒關係,可以自動建立的
第三步:獲取最新的測試報告
1.如果第二步生成的測試報告加了時間戳,想找到最新的檔案就用第三步
2.如果第二步不加時間戳,只是生成result.html,那這一步其實沒卵用,可以忽略
(個人覺得報告用一個名稱result.html就行,新的自動覆蓋舊的)
第四步:傳送測試報告到郵箱
1、像QQ郵箱這種ssl加密的就走SMTP_SSL,用授權碼登入
2、其它郵箱就正常賬號密碼登入,走SMTP
3、最後執行程式碼
這裡郵箱的內容讀的配置檔案
三、config配置
1、cfg.ini開啟,這裡寫配置檔案內容
2、用readConfig.py讀取配置檔案
3、讀取的內容就是傳入第二步操作裡面需要呼叫郵箱的配置資訊
四、logger
1、logger.py這個檔案放到common目錄下,封裝日誌檔案的讀取
2、日誌儲存到logs資料夾
3、參開程式碼:
1 # -*- coding:utf-8 -*- 2 # 1.先設定編碼,utf-8可支援中英文,如上,一般放在第一行 3 4 # 2.註釋:包括記錄建立時間,建立人,專案名稱。 5 ''' 6 Created on 2019-5-30 7 @author: 杜巨集 QQ交流群:984942724 8 Project:專案結構設計 9 ''' 10 # 3.匯入模組 11 import logging, time 12 import os 13 14 # log_path是存放日誌的路徑 15 cur_path = os.path.dirname(os.path.realpath(__file__)) 16 log_path = os.path.join(os.path.dirname(cur_path), 'logs') 17 # 如果不存在這個logs資料夾,就自動建立一個 18 if not os.path.exists(log_path): os.mkdir(log_path) 19 20 21 class Log(): 22 def __init__(self): 23 # 檔案的命名 24 self.logname = os.path.join(log_path, '%s.log' % time.strftime('%Y_%m_%d')) 25 self.logger = logging.getLogger() 26 self.logger.setLevel(logging.DEBUG) 27 # 日誌輸出格式 28 self.formatter = logging.Formatter('[%(asctime)s] - %(filename)s] - %(levelname)s: %(message)s') 29 30 def __console(self, level, message): 31 # 建立一個FileHandler,用於寫到本地 32 # fh = logging.FileHandler(self.logname, 'a') # 追加模式 這個是python2的 33 fh = logging.FileHandler(self.logname, 'a', encoding='utf-8') # 這個是python3的 34 fh.setLevel(logging.DEBUG) 35 fh.setFormatter(self.formatter) 36 self.logger.addHandler(fh) 37 38 # 建立一個StreamHandler,用於輸出到控制檯 39 ch = logging.StreamHandler() 40 ch.setLevel(logging.DEBUG) 41 ch.setFormatter(self.formatter) 42 self.logger.addHandler(ch) 43 44 if level == 'info': 45 self.logger.info(message) 46 elif level == 'debug': 47 self.logger.debug(message) 48 elif level == 'warning': 49 self.logger.warning(message) 50 elif level == 'error': 51 self.logger.error(message) 52 # 這兩行程式碼是為了避免日誌輸出重複問題 53 self.logger.removeHandler(ch) 54 self.logger.removeHandler(fh) 55 # 關閉開啟的檔案 56 fh.close() 57 58 def debug(self, message): 59 self.__console('debug', message) 60 61 def info(self, message): 62 self.__console('info', message) 63 64 def warning(self, message): 65 self.__console('warning', message) 66 67 def error(self, message): 68 self.__console('error', message) 69 70 71 if __name__ == "__main__": 72 log = Log() 73 log.info("---測試開始----") 74 log.info("操作步驟1,2,3") 75 log.warning("----測試結束----")
五、case放用例
1、常用的介面,需要檢查被呼叫的單獨封裝處理,如登入等
2、test開頭的用例
六、logs日誌檢視
1、執行完後日志都會收集到logs資料夾以日期命名
七、生成測試報告
1、這裡呼叫的是HTMLTestRunner生成html的測試報告
八、傳送報告到郵箱
1、執行run_main.py就會自動生成報告,然後傳送到郵箱了
(這裡QQ郵箱的展示是有問題的,一般用企業郵箱的話,是可以正常展示的)
九、小結
1、問題:在python3.7中使用sendmail進行郵件傳送,mailInfo["to"]為逗號分隔的str型別,結果只有第一個郵件地址能收到郵件。將郵箱前後對調後,還是第一個郵箱可以收到測試報告,後邊的郵箱收不到郵件。
折騰好久,郵件裡可以看到收件人有多個,實際上始終只能第一個收件人可以收到郵件。經多次搜尋,發現是這樣:email中收件人和sendmail中的收件人是沒啥聯絡的。
sendmail中收件人,它的格式應該為list。這個為實際的收件人地址。
而msg['To'] 格式是字串(str)。這個只是為了郵件中打印出來而已。
sendmail查原始碼,python/lib/smtplib.py大概690行左右,或者搜尋tolist。
解決方法:經過多次測試發現MIMEText()["to"]的資料型別與sendmail(from_addrs,to_addrs,...)的to_addrs不同;前者為str型別,多個地址使用逗號分隔,後者為list型別。
知道這個原因後,將這一行程式碼:
smtp.sendmail(sender, receiver, msg.as_string())
替換為下邊這樣就可以了:
smtp.sendmail(sender, receiver.split(','), msg.as_string())
當然了,以上是個人的愚見,如果你有更巧妙的解決辦法,歡迎指教和討論。
2、問題:在邊寫邊做的過程中,遇到的另為一個奇葩的問題就是,在配置檔案里加上中文的註釋之後,老是報編碼錯誤,報錯如下:
這個也折騰了好久,由於時間太晚了,實在是不想折騰了,所以就想著,那我不加註釋了,先讓程式碼跑起來再說了,但是這個問題一直困擾著我,如果不解決,以後遇到類似的問題,人家非要你加註釋,你繞都繞不過,怎麼辦???吾日三省吾身,自己問自己。完了還
是沒辦法,自己放不過自己,還是解決吧。完了自己 冷靜了一下,靜下心來捋了一下思路,由於鬍子不夠長,所有就只能摸摸自己頭,冷靜分析了一下:
(1)分析問題(bug)--------讀取配置檔案報編碼錯誤,那就一定是在讀取配置檔案的時候,沒有注意編碼的問題導致出錯
(2)解決問題(bug)--------讀取配置檔案的時候,加上編碼encoding="utf-8" 即可
(3)定位問題(bug)--------全部程式碼,讀取配置檔案的只有郵箱資訊,郵箱資訊又在readconfig.py檔案裡,問題範圍有縮小了,懷疑物件有縮小了,目標嫌疑人已經鎖定,下一步找出證據,判他死刑
(4)用證據說話----------------檢視讀取配置檔案時,是否有編碼問題,沒有注意,果不其然是這個問題 :
(5)彈藥上膛-------------加上編碼 encoding="utf-8" 即可
(6)下令開槍,判處死刑----------執行程式碼,順利通過,郵件發出,大功告成
嘿嘿,時光穿越,當了一回狄仁傑,過了一把神探的癮,不過那個時候沒有槍,應該是大刀舉起,砍下人頭,但是大晚上一個人害怕,又太血腥,還是穿越到現代拿把槍過去再行刑。好了,時間太晚了。這時候我是不是應該說:“元芳,你怎麼看”。。。。。。