[Python]基於Splinter的自動化回歸/測試腳本


總結來說就是用一種自動化回歸腳本的方式,可以重復性的回歸現有功能,並給出回歸測試報告

 基於這個想法,我開發了這個腳本,定義了一套開發模式,基於這個模式,只要針對每個case添加如下的腳本代碼:

caseBegin('輸入關鍵字執行搜索')  ——>測試開始,其實就是打印一個日志  
  
reset(__url)                  ——>重置訪問指定URL,如s.etao.com  
  
addQ('nokia')           ——>添加Q參數,搜索框只有一個固定的q參數可以輸入  
  
submit()                ——>提交搜索表單  
  
jumpUrl('auctions.htm')   
  
——>我們期望結果會跳轉到auctions.htm,也可以指定在頁面什么區域顯示什么內容,  
  
目前支持三種:  
  
1、結果外跳到某個頁面,這個內部會根據指定的頁面名稱生成一個匹配正則;  
  
2、本頁面提示某個信息;  
  
3、跳轉到外部某個頁面提示某個信息;  
  
caseEnd()               ——>測試結束,其實沒有做什么,只是打了日志保存結果,可以擴展成郵件發送之類  

通過現在的自動腳本跑出來的結果:

 

檢查[http://m.etao.com能否正常訪問]:

pass.

-------------------[End]-----------------------

檢查[未輸入關鍵字執行搜索]:

期望結果:在本頁面中提示信息請輸入品牌或型號進行比價

pass.

-------------------[End]-----------------------

檢查[輸入關鍵字執行搜索]:

期望結果:頁面跳轉到auctions.htm

pass.

-------------------[End]-----------------------

檢查[搜索列表頁輸入空關鍵字搜索]:

期望結果:跳轉到頁面:index.htm,提示信息:請輸入品牌或型號進行比價

期望結果:頁面跳轉到index.htm

pass.

期望結果:在本頁面中提示信息請輸入品牌或型號進行比價

pass.

-------------------[End]-----------------------

檢查[輸入關鍵字搜索]:

期望結果:頁面跳轉到auctions.htm

pass.

-------------------[End]-----------------------

 

可以較為清晰的看到回歸了哪些功能,結果是怎樣的。將人肉從重復性的工作中解放出來。例子是在一淘項目中使用的代碼,但是具體的步驟庫是通用的。

現在腳本的開發上可能比較復雜,需要涉及python,splinter,正則甚至是jquery的部分語法,后續打算采用自動生成的方式來做。

如果大家有其他好的想法,非常歡迎一起交流碰撞

 

#!/user/bin/python  
# -*- coding: utf8 -*-  
  
import sys  
import re  
from splinter.browser import Browser  
  
#####################################################  
# global instance  
CLOASE_AFTER_TEST = True # 測試完畢是否自動關閉瀏覽器  
  
GBK = "gbk"  
UTF8 = "utf8"  
  
#####################################################  
# encoding for console  
reload(sys)  
sys.setdefaultencoding(UTF8)  
  
#####################################################  
# small method  
encoding = lambda x:x.encode(GBK)  
  
#####################################################  
# Method output  
def output(x):  
    """ 
        encode and print 
    """  
    print encoding(x)  
  
# Method resultMsg  
def resultMsg(x, msg=''):  
    """ 
        judge result and print, x : True or False 
    """  
    if x == True:  
        output('pass.')  
    else:  
        output('[X]not pass.'+msg)  
  
# Method infoMsgThisPage  
def infoMsgThisPage(espectMsg, positionPattern, getPositionMethodName):  
    """ 
        在本頁面提示信息 
        espectMsg:期望提示的信息 
        positionPattern:位置匹配串,根據getPositionMethodName參數的不同而不同類型 
        getPositionMethodName:獲取位置的方法,有Splinter提供,可選擇列表 
            使用CSS方式查找: find_by_css 
            使用Xpath查詢語言: find_by_xpath 
            使用Tag查找:find_by_tag 
            使用name查找:find_by_name 
            使用id查找:find_by_id 
            使用value查找:find_by_value 
    """  
    output('期望結果:在本頁面中提示信息'+espectMsg)  
  
    function = getattr(browser, getPositionMethodName)  
    if callable(function):  
        errorbox = function(positionPattern)  
        if errorbox is not None and len(errorbox) == 1:  
            resultMsg(espectMsg == errorbox[0].value)  
        elif len(errorbox) > 1:  
            resultMsg(False, '根據您指定的錯誤信息位置匹配串,頁面含有一個以上的錯誤顯示區域,請檢查頁面')  
        else:  
            resultMsg(False, '根據您指定的錯誤信息位置匹配串,頁面沒有找到錯誤顯示區域,請檢查頁面')  
    else:  
        resultMsg(False, 'ERROR:method'+function+'is not callable.')  
  
# Method jumpUrl  
def jumpUrl(urlPattern):  
    """ 
        頁面跳轉出去到新的頁面提示信息,使用本方法不關注頁面提示內容,僅僅關注跳轉頁面是否正常 
        urlPattern:期望跳轉到的頁面的匹配串,可以是普通頁面名稱 
    """  
    output('期望結果:頁面跳轉到'+urlPattern)  
  
    if urlPattern[-1] != '/':  
        pattern = "^("+urlPattern+"\?).*"  
        urlPattern = urlPattern + "?" # 截取出來的會帶有一個?,所以這里也要加一個,否則無法相等  
    else:  
        pattern = "^("+urlPattern+").*"  
  
    r = re.search(re.compile(pattern, re.IGNORECASE), browser.url)  
    if r is not None and len(r.groups()) == 1:  
        resultMsg(urlPattern == "".join(["%s" % s for s in r.groups()]), '未跳轉到指定結果頁面')  
    elif r is not None and len(r.groups()) > 1:  
        resultMsg(False, '在跳轉結果URL中找到了兩個'+urlPattern+'相關的串,請檢查是否有問題')  
    else:  
        resultMsg(False, '跳轉結果URL中沒有找到'+urlPattern)  
  
# Method : jumpUrlAndInfoMsg  
def jumpUrlAndInfoMsg(urlPattern, espectMsg, positionPattern, getPositionMethodName):  
    """ 
        頁面跳轉到指定頁面,提示指定信息 
        具體參數請參見 jumpUrl 方法和 infoMsgThisPage 方法 
    """  
    output('期望結果:跳轉到頁面:'+urlPattern+',提示信息:'+espectMsg)  
    jumpUrl(urlPattern)  
    infoMsgThisPage(espectMsg, positionPattern, getPositionMethodName)  
  
#####################################################  
# 頁面錯誤提示文案  
ERROR_WITHOUT_Q = "請輸入品牌或型號進行比價"  
  
#####################################################  
# 開始執行測試邏輯部分  
browser = Browser()  
__url = 'http://m.etao.com'  
  
reset = lambda x:browser.visit(x)  
submit = lambda:browser.find_by_value('比價').first.click()  
addQ = lambda q:browser.fill('q', q.decode(UTF8))  
  
caseEnd = lambda:output('-------------------[End]-----------------------')  
caseBegin = lambda m:output('檢查['+m+']:')  
  
try:  
    # check service is ok or not  
    caseBegin(__url+"能否正常訪問")  
    reset(__url)  
    resultMsg(browser.status_code.is_success())  
    caseEnd()  
  
    # without q  
    caseBegin('未輸入關鍵字執行搜索')  
    addQ(' ')  
    submit()  
    infoMsgThisPage(ERROR_WITHOUT_Q, "div[class='detail blue-box Amazing']", 'find_by_css')  
    caseEnd()  
  
    # with q  
    caseBegin('輸入關鍵字執行搜索')  
    reset(__url)  
    addQ('nokia')  
    submit()  
    jumpUrl('http://s.m.etao.com/auctions.htm')  
    caseEnd()  
  
    caseBegin('搜索列表頁輸入空關鍵字搜索')  
    reset('http://s.m.etao.com/auctions.htm?q=nokia')  
    addQ(' ')  
    submit()  
    jumpUrlAndInfoMsg('http://s.m.etao.com/index.htm', ERROR_WITHOUT_Q, "div[class='detail blue-box Amazing']", 'find_by_css')  
    caseEnd()  
  
    caseBegin('輸入關鍵字搜索')  
    reset('http://s.m.etao.com/auctions.htm?q=nokia')  
    addQ('手機')  
    submit()  
    jumpUrl('http://s.m.etao.com/auctions.htm')  
    caseEnd()  
  
except Exception, e:  
    print e  
  
if CLOASE_AFTER_TEST:  
    browser.quit()  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM