1. 程式人生 > >《一頭扎進》系列之Python+Selenium框架設計篇3- 價值好幾K的框架,狼來了,狼來了....,狼沒來,框架真的來了

《一頭扎進》系列之Python+Selenium框架設計篇3- 價值好幾K的框架,狼來了,狼來了....,狼沒來,框架真的來了

1. 簡介

  前邊巨集哥一邊一邊的喊框架,就如同一邊一邊的喊狼來了!狼來了!.....這回是狼沒有來,框架真的來了。從本文開始巨集哥將會一步一步介紹,如何從無到有地建立自己的第一個自動化測試框架。這一篇,我們介紹,如何封裝自己的日誌類和瀏覽器引擎類。

2. 建立專案層級結構

  如何建立,怎麼建立。這個就需要我們前邊介紹的框架概要設計以及框架的詳細設計的思維導圖,巨集哥就是根據那個圖,輕鬆地、清楚的、思路清晰地一步一步建立專案層級結構。

相關步驟:

1. 開啟PyCharm,建立如下格式的專案層級結構,為了避免不必要的麻煩檔名稱建議和巨集哥保持一樣;

3. 相關檔案程式碼

3.1 config.ini 配置檔案

配置檔案config.ini相關設計如下:

3.1.1 程式碼實現:

3.1.2 參考程式碼:
# this is config file, only store browser type and server URL

[browserType]
#browserName = Firefox
browserName = Chrome
#browserName = IE

[testServer]
URL = https://www.baidu.com
#URL = www.google.com

3.2 封裝瀏覽器驅動(引擎)類

3.2.1 browser_engine.py 檔案

主要目前常用的Chrome、Firefox和IE三大瀏覽器引擎的封裝。

瀏覽器引擎類browser_engine.py相關指令碼程式碼如下:

3.2.2 程式碼實現:

3.2.3 參考程式碼:
# -*- coding:utf-8 -*-

# 1.先設定編碼,utf-8可支援中英文,如上,一般放在第一行

# 2.註釋:包括記錄建立時間,建立人,專案名稱。
'''
Created on 2019-12-19
@author: 北京-巨集哥   QQ交流群:705269076
Project: 《《一頭扎進》系列之Python+Selenium框架設計篇3- 價值好幾K的框架,不看別後悔,過時不候
'''

# 3.匯入模組
import configparser
import os.path
from selenium import webdriver
from automation_framework_demo.framework.logger import Logger

logger = Logger(logger="BrowserEngine").getlog()


class BrowserEngine(object):
    dir = os.path.dirname(os.path.abspath('.'))  # 注意相對路徑獲取方法
    chrome_driver_path = dir + '/tools/chromedriver.exe'
    ie_driver_path = dir + '/tools/IEDriverServer.exe'

    def __init__(self, driver):
        self.driver = driver

    # read the browser type from config.ini file, return the driver
    def open_browser(self, driver):
        config = configparser.ConfigParser()
        # file_path = os.path.dirname(os.getcwd()) + '/config/config.ini'
        file_path = os.path.dirname(os.path.abspath('.')) + '/config/config.ini'
        config.read(file_path)

        browser = config.get("browserType", "browserName")#獲取瀏覽器型別、名字
        logger.info("You had select %s browser." % browser)  #日誌列印你選擇的瀏覽器
        url = config.get("testServer", "URL") #獲取測試的URL地址
        logger.info("The test server url is: %s" % url) #日誌列印測試的URL地址

        #判斷你所選擇的瀏覽器
        if browser == "Firefox":
            driver = webdriver.Firefox()
            logger.info("Starting firefox browser.")
        elif browser == "Chrome":
            driver = webdriver.Chrome(self.chrome_driver_path)#初始化一個例項
            logger.info("Starting Chrome browser.")
        elif browser == "IE":
            driver = webdriver.Ie(self.ie_driver_path)
            logger.info("Starting IE browser.")

        driver.get(url)#訪問URL
        logger.info("Open url: %s" % url)
        driver.maximize_window()  #將視窗放大
        logger.info("Maximize the current window.")
        driver.implicitly_wait(10)
        logger.info("Set implicitly wait 10 seconds.")
        print(driver)
        return driver

    #關閉瀏覽器
    def quit_browser(self):
        logger.info("Now, Close and quit the browser.")
        self.driver.quit()

3.3 封裝日誌類

3.3.1 logger.py檔案

日誌類logger.py相關指令碼程式碼如下:

3.3.2 程式碼實現:

3.3.3 參考程式碼:
# -*- coding:utf-8 -*-

# 1.先設定編碼,utf-8可支援中英文,如上,一般放在第一行

# 2.註釋:包括記錄建立時間,建立人,專案名稱。
'''
Created on 2019-12-19
@author: 北京-巨集哥   QQ交流群:705269076
Project: 《《一頭扎進》系列之Python+Selenium框架設計篇3- 價值好幾K的框架,不看別後悔,過時不候
'''

# 3.匯入模組
import logging
import logging.handlers
import os.path
import time


class Logger(object):

    def __init__(self, logger):
        '''''
            指定儲存日誌的檔案路徑,日誌級別,以及呼叫檔案
            將日誌存入到指定的檔案中
        '''

        # 建立一個日誌器logger,並設定其日誌級別為DEBUG
        self.logger = logging.getLogger(logger)
        self.logger.setLevel(logging.DEBUG)

        # 建立一個handler,用於寫入日誌檔案
        rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time()))
        # log_path = os.path.dirname(os.getcwd()) + '/Logs/'  # 專案根目錄下/Logs 儲存日誌
        log_path = os.path.dirname(os.path.abspath('.')) + '/logs/'
        # 如果case組織結構式 /testsuit/featuremodel/xxx.py , 那麼得到的相對路徑的父路徑就是專案根目錄
        log_name = log_path + rq + '.log'
        # 建立一個檔案處理器handler並設定其日誌級別為INFO
        #fh = logging.FileHandler(log_name, maxBytes=1024 * 1024, backupCount=5,
         #                                               encoding='utf-8')

        fh = logging.handlers.RotatingFileHandler(log_name, maxBytes=1024 * 1024, backupCount=5,
                                                         encoding='utf-8')  # 例項化handler

        #fh = logging.FileHandler(log_name)
        fh.setLevel(logging.INFO)

        # 再建立一個handler,用於輸出到控制檯
        '''
        建立一個流處理器handler並設定其日誌級別為INFO
        '''
        ch = logging.StreamHandler()
        ch.setLevel(logging.INFO)

        # 定義handler的輸出格式
        #handler = logging.handlers.RotatingFileHandler(fh, maxBytes=1024 * 1024, backupCount=5,
        #                                                 encoding='utf-8')  # 例項化handler
        '''
        建立一個格式器formatter並將
        '''
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        fh.setFormatter(formatter)
        ch.setFormatter(formatter)

        # 給日誌處理器logger新增上面建立的handler
        self.logger.addHandler(fh)
        self.logger.addHandler(ch)

    def getlog(self):
        return self.logger  

頁面物件pageobject這裡暫不用,其實上一篇微博那個小例子已經介紹過了,計劃下一篇巨集哥再做詳細地介紹。

4. 新建測試指令碼

4.1 測試指令碼baidu_search.py

測試指令碼baidu_search.py相關指令碼如下:

4.2 程式碼實現:

4.3 參考程式碼:

# -*- coding:utf-8 -*-

# 1.先設定編碼,utf-8可支援中英文,如上,一般放在第一行

# 2.註釋:包括記錄建立時間,建立人,專案名稱。
'''
Created on 2019-12-19
@author: 北京-巨集哥   QQ交流群:705269076
Project: 《《一頭扎進》系列之Python+Selenium框架設計篇3- 價值好幾K的框架,不看別後悔,過時不候
'''

# 3.匯入模組
import time
import unittest
from automation_framework_demo.framework.browser_engine import BrowserEngine


class BaiduSearch(unittest.TestCase):


    def setUp(self):
        """
        測試韌體的setUp()的程式碼,主要是測試的前提準備工作
        :return:
        """
        browse = BrowserEngine(self)
        self.driver = browse.open_browser(self)


    def tearDown(self):
        """
        測試結束後的操作,這裡基本上都是關閉瀏覽器
        :return:
        """
        self.driver.quit()

    def test_baidu_search(self):
        """
        這裡一定要test開頭,把測試邏輯程式碼封裝到一個test開頭的方法裡。
        :return:
        """
        self.driver.find_element_by_id('kw').send_keys('selenium')
        time.sleep(1)
        self.driver.find_element_by_id('su').click()
        time.sleep(5)
        try:
            assert 'selenium' in self.driver.title
            print ('Test Pass.')
        except Exception as e:
            print ('Test Fail.', format(e))

if __name__ == '__main__':
    unittest.main()

4.4 執行結果:

執行程式碼後,控制檯列印如下圖的結果

工具包,這裡把三個瀏覽器的driver檔案都放根目錄一個資料夾裡,這樣別人拷貝這個專案也不需要去下載這些檔案。

執行測試指令碼baidu_search.py,會在根目錄下的logs檔案生成日誌檔案,例如巨集哥的檔案內容:

5.小結

5.1 遇到的一個小問題

問題描述:主要是在斷言的時候fail的了,原因是輸入selenium後,沒有點選查詢,於是巨集哥加上這段程式碼

self.driver.find_element_by_id('su').click()

執行後仍然fail的,巨集哥猜測是點選後沒有出現元素,就去斷言,因此又加上了等待的出現的程式碼,結果pass了

 time.sleep(5)

在實踐和寫程式碼,執行的過程中,遇到問題就出現在下邊的程式碼裡。有興趣的小夥伴或者童鞋們可以自己註釋掉實驗一下

    def test_baidu_search(self):
        """
        這裡一定要test開頭,把測試邏輯程式碼封裝到一個test開頭的方法裡。
        :return:
        """
        self.driver.find_element_by_id('kw').send_keys('selenium')
        time.sleep(1)
        self.driver.find_element_by_id('su').click()
        time.sleep(5)
        try:
            assert 'selenium' in self.driver.title
            print ('Test Pass.')
        except Exception as e:
            print ('Test Fail.', format(e))

 

好了,今天的分享就到這裡吧!!!謝謝各位的耐心閱讀。有問題加群交流討論

 

您的肯定就是我進步的動力。如果你感覺還不錯,就請鼓勵一下吧!記得隨手點波  推薦  不要忘記哦!!!

別忘了點 推薦 留下您來過的痕跡