這是《selenium2+python學習總結》的升級版。html
1) globalparameter.pypython
# coding:utf-8 __author__ = 'helen' import time,os ''' 配置全局參數 ''' # 項目的絕對路徑(由於 windows執行時須要絕對路徑才能執行經過) # project_path = "D:\\for2017\\SPframework-Helen_2.0\\" # 獲取項目路徑 project_path = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)[0]), '.')) print project_path # 測試用例代碼存放路徑(用於構建suite,注意該文件夾下的文件都應該以test開頭命名) test_case_path = project_path+"\\src\\test_case" # excel測試數據文檔存放路徑 test_data_path = project_path+"\\data\\testData.xlsx" # 日誌文件存儲路徑 log_path = project_path+"\\log\\mylog.log" print u'日誌路徑:'+log_path # 測試報告存儲路徑,並以當前時間做爲報告名稱前綴 report_path = project_path+"\\report\\" report_name = report_path+time.strftime('%Y%m%d%H%S', time.localtime()) # 異常截圖存儲路徑,並以當前時間做爲圖片名稱前綴 img_path = project_path+"\\error_img\\"+time.strftime('%Y%m%d%H%S', time.localtime()) # 設置發送測試報告的公共郵箱、用戶名和密碼 smtp_sever = 'mail.**.com' # 郵箱SMTP服務,各大運營商的smtp服務能夠在網上找,而後能夠在foxmail這些工具中驗正 email_name = "SDS@**.com" # 發件人名稱 email_password = "****" # 發件人登陸密碼 email_To = '5047**0@qq.com;54*0016@qq.com;hel**ter@163.com' # 收件人
2) log.pyweb
# coding:utf-8 __author__ = 'helen' import logging from config import globalparameter as gl ''' 配置日誌文件,輸出INFO級別以上的日誌 ''' class log: def __init__(self): self.logname = "mylog" def setMSG(self, level, msg): # 以前把下面定義log的一大段代碼寫在了__init__裏面,形成了日誌重複輸出 # 此大坑,謹記謹記!!!! logger = logging.getLogger() # 定義Handler輸出到文件和控制檯 fh = logging.FileHandler(gl.log_path) ch = logging.StreamHandler() # 定義日誌輸出格式 formater = logging.Formatter("%(asctime)s %(levelname)s %(message)s' ") fh.setFormatter(formater) ch.setFormatter(formater) # 添加Handler logger.addHandler(fh) logger.addHandler(ch) # 添加日誌信息,輸出INFO級別的信息 logger.setLevel(logging.INFO) if level=='debug': logger.debug(msg) elif level=='info': logger.info(msg) elif level=='warning': logger.warning(msg) elif level=='error': logger.error(msg) # 移除句柄,不然日誌會重複輸出 logger.removeHandler(fh) logger.removeHandler(ch) fh.close() def debug(self, msg): self.setMSG('debug', msg) def info(self, msg): self.setMSG('info', msg) def warning(self, msg): self.setMSG('warning', msg) def error(self, msg): self.setMSG('error', msg)
3) send_mail.pywindows
# coding:utf-8 __author__ = 'helen' import os,smtplib,os.path from config import globalparameter as gl from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from src.common import log ''' 郵件發送最新的測試報告 ''' class send_email: def __init__(self): self.mylog = log.log() # 定義郵件內容 def email_init(self,report,reportName): with open(report,'rb')as f: mail_body = f.read() # 建立一個帶附件的郵件實例 msg = MIMEMultipart() # 以測試報告做爲郵件正文 msg.attach(MIMEText(mail_body,'html','utf-8')) report_file = MIMEText(mail_body,'html','utf-8') # 定義附件名稱(附件的名稱能夠隨便定義,你寫的是什麼郵件裏面顯示的就是什麼) report_file["Content-Disposition"] = 'attachment;filename='+reportName msg.attach(report_file) # 添加附件 msg['Subject'] = '自動化測試報告:'+reportName # 郵件標題 msg['From'] = gl.email_name #發件人 msg['To'] = gl.email_To #收件人列表 try: server = smtplib.SMTP(gl.smtp_sever) server.login(gl.email_name,gl.email_password) server.sendmail(msg['From'],msg['To'].split(';'),msg.as_string()) server.quit() except smtplib.SMTPException: self.mylog.error(u'郵件發送測試報告失敗 at'+__file__) def sendReport(self): # 找到最新的測試報告 report_list = os.listdir(gl.report_path) report_list.sort(key=lambda fn: os.path.getmtime(gl.report_path+fn) if not os.path.isdir(gl.report_path+fn) else 0) new_report = os.path.join(gl.report_path,report_list[-1]) # 發送郵件 self.email_init(new_report,report_list[-1])
4) excel_data.pyapp
# coding:utf-8 __author__ = 'helen' import xlrd from src.common import log from config.globalparameter import test_data_path ''' 讀取excel文件 ''' class excel: def __init__(self): self.mylog = log.log() def open_excel(self,file): u'''讀取excel文件''' try: data = xlrd.open_workbook(file) return data except Exception, e: self.mylog.error(u"打開excel文件失敗") def excel_table(self,file, sheetName): u'''裝載list''' data = self.open_excel(file) # 經過工做表名稱,獲取到一個工做表 table = data.sheet_by_name(sheetName) # 獲取行數 Trows = table.nrows # 獲取 第一行數據 Tcolnames = table.row_values(0) lister = [] for rownumber in range(1,Trows): row = table.row_values(rownumber) if row: app = {} for i in range(len(Tcolnames)): app[Tcolnames[i]] = row[i] lister.append(app) return lister def get_list(self,sheetname): try: data_list = self.excel_table(test_data_path, sheetname) assert len(data_list)>=0,u'excel標籤頁:'+sheetname+u'爲空' return data_list except Exception as e: self.mylog.error(u'excel標籤頁:'+sheetname+u'爲空') raise e
5) Base_Page.py工具
# coding:utf-8 __author__ = 'helen' from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from src.common import log from config.globalparameter import img_path ''' project:封裝頁面公用方法 ''' class BasePage(object): def __init__(self, selenium_driver, base_url, page_title): self.driver = selenium_driver self.url = base_url self.title = page_title self.mylog = log.log() # 打開頁面,並校驗連接是否加載正確 def _open(self, url, page_title): try: self.driver.get(url) self.driver.maximize_window() # 經過斷言輸入的title是否在當前title中 assert page_title in self.driver.title, u'打開頁面失敗:%s' % url except: self.mylog.error(u'未能正確打開頁面:'+url) # 重寫find_element方法,增長定位元素的健壯性 def find_element(self, *loc): try: WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(loc)) return self.driver.find_element(*loc) except: self.mylog.error(u'找不到元素:'+str(loc)) # 重寫send_keys方法 def send_keys(self, value, clear=True, *loc): try: if clear: self.find_element(*loc).clear() self.find_element(*loc).send_keys(value) except AttributeError: self.mylog.error(u'輸入失敗,loc='+str(loc)+u';value='+value) # 截圖 def img_screenshot(self, img_name): try: self.driver.get_screenshot_as_file(img_path+img_name+'.png') except: self.mylog.error(u'截圖失敗:'+img_name)
6) baidu_page.py學習
# coding:utf-8 __author__ = 'helen' from selenium.webdriver.common.by import By from src.common.Base_Page import BasePage from selenium.webdriver.common.action_chains import ActionChains class BaiduPage(BasePage): # 定位器 keywords_loc = (By.ID, 'kw') submit_loc = (By.ID, 'su') hao123_loc = (By.NAME, 'tj_trhao123') more_loc = (By.LINK_TEXT, u'更多產品') zhidao_loc = (By.NAME,'tj_zhidao') # 打開頁面 def open(self): self._open(self.url, self.title) # 輸入關鍵詞 def input_keywords(self, keywords): self.find_element(*self.keywords_loc).send_keys(keywords) # 點擊搜索按鈕 def click_submit(self): self.find_element(*self.submit_loc).click() # 點擊hao123連接 def click_hao123(self): self.find_element(*self.hao123_loc).click() # 鼠標懸停在"更多產品"上 def ActionChains_more(self): mouse = self.find_element(*self.more_loc) ActionChains(self.driver).move_to_element(mouse).perform() # 點擊「所有產品」 def click_zhidao(self): self.find_element(*self.zhidao_loc).click()
7) test_baidu.py測試
# coding:utf-8 __author__ = 'helen' import unittest from selenium import webdriver from src.pages.baidu_page import BaiduPage from time import sleep ''' project:百度頁面測試 ''' class TestBaiduSearch(unittest.TestCase): def setUp(self): self.driver = webdriver.Firefox() self.url = 'https://www.baidu.com/' self.keyword = 'python' self.baidu_page = BaiduPage(self.driver, self.url, u'百度') def test_baidu_search(self): u'''百度搜索''' try: self.baidu_page.open() self.baidu_page.input_keywords(self.keyword) self.baidu_page.click_submit() sleep(2) self.assertIn(self.keyword, self.driver.title) except Exception as e: self.baidu_page.img_screenshot(u'百度搜索') raise e def test_baidu_changeto_hao123(self): u'''從百度首頁打開hao123''' try: self.baidu_page.open() self.baidu_page.click_hao123() self.assertEqual(self.driver.current_url, 'https://www.hao123.com/') except Exception as e: self.baidu_page.img_screenshot(u'從百度首頁打開hao123') raise e def test_baidu_more(self): u'''打開百度知道''' try: self.baidu_page.open() self.baidu_page.ActionChains_more() self.baidu_page.click_zhidao() self.assertEqual(self.driver.current_url, 'https://zhidao.baidu.com/') except Exception as e: self.baidu_page.img_screenshot(u'打開百度知道') raise e def tearDown(self): self.driver.close()
8) sogou_page.pyui
# coding:utf-8 __author__ = 'helen' from selenium.webdriver.common.by import By from src.common.Base_Page import BasePage ''' project:sogo頁面元素管理 ''' class sogou_page(BasePage): # 定位 keyword_loc = (By.ID, 'query') sumit_loc = (By.ID, 'stb') def open(self): self._open(self.url,self.title) # 輸入關鍵詞 def input_keyword(self, value): self.find_element(*self.keyword_loc).send_keys(value) # 點擊搜索 def click_sumit(self): self.find_element(*self.sumit_loc).click()
9) test_sogou.pyurl
# coding:utf-8 __author__ = 'helen' import unittest from selenium import webdriver from src.pages.sogou_page import sogou_page from src.common.log import log from src.common import excel_data '''sogou頁面測試 ''' class test_sogou(unittest.TestCase): def setUp(self): self.mylog = log() self.driver = webdriver.Firefox() self.url = 'https://www.sogou.com/' self.sogou_page = sogou_page(self.driver,self.url,u'搜狗') self.excel = excel_data.excel() def test_search(self): u'''搜狗搜索:excel數據驅動''' keyword_list = self.excel.get_list('sogou_search') for i in range(0, len(keyword_list)): keyword = keyword_list[i]["keyword"] try: self.sogou_page.open() self.sogou_page.input_keyword(keyword) self.sogou_page.click_sumit() # 由於assert對比是的str因此要判斷keyword類型如何不是str, 就要進行轉換 if type(keyword)!=str: keyword = str(keyword) self.assertIn(keyword,self.driver.title) except Exception as e: self.mylog.error('error for search keyword:'+str(keyword)) self.sogou_page.img_screenshot(u'搜狗搜索') raise e def tearDown(self): self.driver.close() if __name__=='__main__': unittest.main()
10) runtest.py
# coding:utf-8 __author__ = 'helen' import unittest,time,HTMLTestRunner from config.globalparameter import test_case_path,report_name from src.common import send_email ''' 構建測試套件,並執行測試 ''' # 構建測試集,包含src/test_case目錄下的全部以test開頭的.py文件 suite = unittest.defaultTestLoader.discover(start_dir=test_case_path,pattern='test*.py') # 執行測試 if __name__=="__main__": report = report_name+"Report.html" fb = open(report,'wb') runner = HTMLTestRunner.HTMLTestRunner( stream=fb, title=u'自動化測試報告', description=u'項目描述。………' ) runner.run(suite) fb.close() # 發送郵件 time.sleep(10) # 設置睡眠時間,等待測試報告生成完畢(這裏被坑了==) email = send_email.send_email() email.sendReport()