selenium實例:unittest框架+PO開發模式

這是《selenium2+python學習總結》的升級版。html

 

  1. 1.         項目結構

 

 

  1. 2.         項目代碼

 

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()
相關文章
相關標籤/搜索