溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Python+selenium+unittest的GUI自動(dòng)化框架實(shí)現(xiàn)

發(fā)布時(shí)間:2020-07-04 04:45:17 來(lái)源:網(wǎng)絡(luò) 閱讀:5798 作者:xiao_long66 欄目:數(shù)據(jù)庫(kù)


框架設(shè)計(jì)說(shuō)明圖:

Python+selenium+unittest的GUI自動(dòng)化框架實(shí)現(xiàn)


框架實(shí)現(xiàn)前的準(zhǔn)備工作:

1.Python版本為2.7.11的Windows下的安裝。

2.命令行下的selenium最新版本(編者使用版本為2.53.0,可兼容最新火狐、IE、chrome等瀏覽器版本)pip安裝。

3.版本為Version: Mars.1 Release (4.5.1)的eclipse安裝(編者Python開(kāi)發(fā)使用工具),jdk1.7。

4.eclipse下Python開(kāi)發(fā)插件PyDev 4.5.1(高版本不一定兼容當(dāng)前eclipse版本與Java版本,高版本安裝成功后,eclipse中找不到對(duì)應(yīng)PyDev插件)。

5.Python下的MySQL數(shù)據(jù)庫(kù)(編者使用數(shù)據(jù)為MySQL)模塊安裝MySQL-python-1.2.4b4.win32-py2.7(注意模塊版本與系統(tǒng)位數(shù),要與安裝Python相同)。

6.Python反編譯模塊uncompyle-master安裝(或許會(huì)用到)。

7.Python可執(zhí)行打包模塊py2exe-0.6.9.win32-py2.7安裝(或許會(huì)用到)。


框架實(shí)現(xiàn)的可行性:

1.擴(kuò)展方便,類似于Python的模塊化安裝。

2.易于維護(hù),針對(duì)selenium的最新版本升級(jí)(兼容瀏覽器的最新版本等)只需命令行下執(zhí)行:pip install -U selenium即可實(shí)現(xiàn)。

3.實(shí)現(xiàn)語(yǔ)言簡(jiǎn)單易學(xué),針對(duì)Python的學(xué)習(xí)只要是不過(guò)于追求高大上(重構(gòu)、復(fù)雜多態(tài)等),基本很快時(shí)間內(nèi)即可搞定。

4.各瀏覽器均可兼容使用(編者的其它文章中有介紹IE、chrome等瀏覽器的調(diào)用)。


框架實(shí)現(xiàn)思路說(shuō)明:


開(kāi)篇啰嗦:

    思路說(shuō)明前,啰嗦兩句(毛病是改不掉了)。小編同事過(guò)很多大牛,寫(xiě)出的代碼非常牛叉(功能、性能、可讀性等),設(shè)計(jì)的項(xiàng)目框架各種優(yōu)秀,但是至于很多項(xiàng)目開(kāi)發(fā)人員,很難達(dá)到框架設(shè)計(jì)之初的實(shí)現(xiàn)思路,按照初始的框架設(shè)計(jì)做項(xiàng)目實(shí)現(xiàn)。歸根結(jié)底是由于項(xiàng)目從事人員未能達(dá)到思想上的一致,即框架設(shè)計(jì)人員未能將框架設(shè)計(jì)思想很好的傳達(dá)給項(xiàng)目從事人員,不能讓項(xiàng)目人員統(tǒng)一實(shí)現(xiàn)思想,導(dǎo)致后面項(xiàng)目可能出現(xiàn)的無(wú)法進(jìn)行以及實(shí)現(xiàn)過(guò)程中的各種困難(項(xiàng)目人員A認(rèn)為按照框架能夠?qū)崿F(xiàn)沙發(fā)的制作、項(xiàng)目人員B卻認(rèn)為按照框架只能設(shè)計(jì)出板凳來(lái),思想上的不統(tǒng)一)。更多的事框架的設(shè)計(jì)未能較好的被理解。不管做什么,編者始終認(rèn)為思路是第一位的。


測(cè)試用例代碼實(shí)現(xiàn)存放模塊:

import unittest
from time import sleep
from common.driverElement import driverElement

class CrmLoginTest(unittest.TestCase):
    def setUp(self):
        self.driverElement=driverElement()
        self.driver=self.driverElement.webdriverInit('http://crm.#/login')
    def tearDown(self):
        self.driver.quit()
    def testName(self):
        self.driverElement.webdriverLogin(self.driver)
        sleep(4)

    代碼很簡(jiǎn)單,定義了系統(tǒng)登錄測(cè)試的一個(gè)實(shí)現(xiàn)類CrmLoginTest,該實(shí)現(xiàn)類繼承了unittest模塊的TestCase接口定義的多個(gè)方法:setUp、tearDown、testName。

    unittest類似于Java的TestNg,都是用于各自語(yǔ)言單元測(cè)試用。只不過(guò)實(shí)現(xiàn)方式不同罷了。具體看測(cè)試實(shí)現(xiàn)類繼承的方法,setUp用于測(cè)試用例執(zhí)行前的準(zhǔn)備工作,包括數(shù)據(jù)庫(kù)的連接建立、用例需用數(shù)據(jù)的預(yù)制準(zhǔn)備等。testName方法定了用例具體實(shí)現(xiàn)用到的一些操作,對(duì)頁(yè)面用戶名、密碼輸入,點(diǎn)擊頁(yè)面【登錄】按鈕等一系列的手工測(cè)試操作。tearDown方法,用于用例運(yùn)行完成后的垃圾數(shù)據(jù)回收、數(shù)據(jù)庫(kù)連接斷開(kāi)等用例結(jié)束操作。

    測(cè)試實(shí)現(xiàn)類中setUp、tearDown、testName三方法的執(zhí)行順序不以出現(xiàn)的先后順序做執(zhí)行,不管三方法出現(xiàn)的順序?yàn)楹?,均?yōu)先執(zhí)行setUp,在執(zhí)行testName、testName1.。。最后執(zhí)行tearDown

    上面是介紹的測(cè)試用例實(shí)現(xiàn)思路,測(cè)試用例代碼實(shí)現(xiàn)存放模塊實(shí)現(xiàn)思路是,該模塊下只允許存放測(cè)試用例方法(CRMResourcesTest)與測(cè)試用例數(shù)據(jù)文件(Login.json)以及目錄(用于標(biāo)示測(cè)試用例所屬不同層級(jí))。此處區(qū)分測(cè)試用例方法與測(cè)試用例數(shù)據(jù)文件是自動(dòng)化實(shí)現(xiàn)思想中“數(shù)據(jù)與腳本分離的重要實(shí)現(xiàn)”。數(shù)據(jù)與腳本分離后便于自動(dòng)化用例維護(hù)(只需維護(hù)json文件即可實(shí)現(xiàn)用例的維護(hù),無(wú)需修改測(cè)試腳本)。隨著自動(dòng)化越做越多,你會(huì)發(fā)現(xiàn)數(shù)據(jù)與腳本分離是多么重要的一件事情。


公共邏輯代碼封裝存放模塊:

    上面代碼中testName方法中只用到了self.driverElement.webdriverLogin方法,即實(shí)現(xiàn)了系統(tǒng)登錄。實(shí)際的手工測(cè)試操作,登錄頁(yè)面的完成需要“輸入用戶名”、“輸入密碼”、“點(diǎn)擊【登錄】按鈕”三步實(shí)現(xiàn)系統(tǒng)登錄操作。此處只用到了“一步”即實(shí)現(xiàn)了系統(tǒng)登錄,怎么看能,查看公共邏輯代碼封裝存放模塊下的driverElement.py文件,可以看到webdriverLogin方法具體為:

def webdriverLogin(self,driver):
        elementaction=ElementActionutil()
        elementaction.textinput(driver, elementname='js_uname', method='Class', text=self.f.getGlobalFileattrs('Login.json', 'username'), timeout=2)#用戶名輸入
        elementaction.textinput(driver, elementname='js_upwd', method='Class', text='123456')#密碼輸入
        elementaction.singleclick(driver,elementname='btnsend',method='Id')#點(diǎn)擊【登錄】按鈕
        print 'System login successfully!'

    通過(guò)上面代碼可以看到,看到的“一步”,其實(shí)際為三個(gè)步驟的一個(gè)封裝,此處針對(duì)上述三個(gè)步驟做封裝,是因?yàn)榇巳齻€(gè)步驟很多用例中都會(huì)用到,封裝之后,各個(gè)測(cè)試用例直接調(diào)用“一步”方法即可實(shí)現(xiàn)系統(tǒng)登錄,無(wú)需每個(gè)用例中均寫(xiě)三個(gè)步驟,代碼美觀易讀,且方便實(shí)現(xiàn)。這就是“公共邏輯代碼封裝存放模塊”的存在意義,針對(duì)代碼中重復(fù)用到的公共步驟封裝存放。當(dāng)然針對(duì)公共步驟的封裝實(shí)現(xiàn)用到的測(cè)試數(shù)據(jù),有公共數(shù)據(jù)文件存放,如:baseaction下的Login.json文件,存放的就是公共邏輯代碼中用到的數(shù)據(jù)。


GUI頁(yè)面動(dòng)作代碼存放模塊:

    具體看模塊下elementActionUtil.py文件中singleclick方法:

def singleclick(self,webdriver,elementname='',method='Id',timeout=2):
        'method value:Id,Name,Class,xpath;webdriver value Firefox,Ie'
        element1=waitforElementPresentAction.waitforElementPresentAction(webdriver, elementname, method, timeout)
        element1.click()

    公共邏輯代碼封裝存放模塊中 elementaction.singleclick步驟,其實(shí)現(xiàn)就是以上代碼,實(shí)際手工測(cè)試中鼠標(biāo)單擊操作,在代碼實(shí)現(xiàn)中并不是一個(gè)底層方法就可實(shí)現(xiàn)的,往往實(shí)現(xiàn)起來(lái)可能需要N多操作。對(duì)誰(shuí)執(zhí)行、執(zhí)行什么等等。特別是涉及到網(wǎng)絡(luò)較差的情況,手工測(cè)試知道等待多長(zhǎng)時(shí)間即可執(zhí)行單擊操作,但是自動(dòng)化代碼卻要想方設(shè)法完成手工操作的智能化,其實(shí)現(xiàn)可想而知。

    此處“GUI頁(yè)面動(dòng)作代碼存放模塊”中,只需包含elementActionUtil.py單文件即可,文件中定義各種頁(yè)面操作:鼠標(biāo)單擊動(dòng)作、鼠標(biāo)雙擊動(dòng)作、文本輸入動(dòng)作、單選按鈕選擇動(dòng)作、復(fù)選按鈕選擇動(dòng)作、頁(yè)面元素是否可見(jiàn)、元素控件是否存在等等。各種頁(yè)面動(dòng)作的集合,即實(shí)現(xiàn)了頁(yè)面自動(dòng)化所需的各種手工實(shí)現(xiàn)。


底層代碼模塊:

    底層代碼模塊定義了 公共邏輯代碼封裝存放模塊中 各個(gè)動(dòng)作步驟用到的核心代碼,包括動(dòng)作執(zhí)行時(shí)間、如何查找元素控件(類似于人眼識(shí)別)、針對(duì)何種控件執(zhí)行識(shí)別等等,舉例代碼如下:

def waitforElementPresentAction(webdriver,elementname='',method='Id',timeout=2):
    'method value:Id,Name,Class,xpath;webdriver value Firefox,Ie,takes a WebDriver instance and timeout in seconds'
    element1=None
    end_time = time.time() + timeout
    while True:
        try:
            if method=='Id':
                element1=webdriver.find_element_by_id(elementname)
            elif method=='Name':
                element1=webdriver.find_element_by_name(elementname)
            elif method=='Class':
                element1=webdriver.find_element_by_class_name(elementname)
            elif method=='Xpath':
                element1=webdriver.find_element_by_xpath(elementname)
            if element1:
                return element1
        except Exception:
            pass
        if time.time()>end_time:
            assert False,'NoSuchElementException '+elementname+' with the method '+method#此處為何如此實(shí)現(xiàn),請(qǐng)讀者朋友給個(gè)回復(fù)。


文件操作代碼存放模塊:

    該模塊存放了如何實(shí)現(xiàn)測(cè)試用例數(shù)據(jù)文件內(nèi)容讀取操作的各個(gè)方法,方法實(shí)現(xiàn)的同時(shí),也定義了測(cè)試數(shù)據(jù)文件的儲(chǔ)存格式,數(shù)據(jù)文件不同后綴形式的讀取等等操作,均存放在“文件操作代碼存放模塊”中。


數(shù)據(jù)庫(kù)代碼存放模塊:

    該模塊定義了針對(duì)數(shù)據(jù)庫(kù)的各種操作實(shí)現(xiàn):增、刪、改、查,建表、調(diào)用存儲(chǔ)過(guò)程等等的數(shù)據(jù)庫(kù)操作。該模塊存在意義就是,手工測(cè)試過(guò)程中,針對(duì)前臺(tái)頁(yè)面操作完成后,后臺(tái)數(shù)據(jù)庫(kù)入表的正確性驗(yàn)證操作的自動(dòng)化代碼實(shí)現(xiàn),以及測(cè)試用例執(zhí)行前的測(cè)試數(shù)據(jù)預(yù)制實(shí)現(xiàn)等等。


日志文件代碼存放模塊:

    日志文件代碼存放模塊定義了日志文件生成如何實(shí)現(xiàn),針對(duì)測(cè)試用例級(jí)實(shí)現(xiàn),運(yùn)行多個(gè)用例、套件級(jí)用例運(yùn)行測(cè)試,如何分析用例運(yùn)行情況,通過(guò)用例運(yùn)行輸出日志即可實(shí)現(xiàn)用例運(yùn)行正確性的檢查。此處代碼編者暫未實(shí)現(xiàn),后面時(shí)間允許會(huì)加以完成。


框架不足以及待優(yōu)化:

    1.單個(gè)測(cè)試方法如何實(shí)現(xiàn)多個(gè)測(cè)試用例,即如何定義數(shù)據(jù)文件層級(jí)結(jié)構(gòu)等。

    2.日志文件如何定義實(shí)現(xiàn)。

    3.單個(gè)用例測(cè)試執(zhí)行、多用例測(cè)試執(zhí)行(套件測(cè)試執(zhí)行)測(cè)試報(bào)告的輸出等。

    4.代碼傻瓜式實(shí)現(xiàn)等。

。。。。。。。。

                                未完、已完、待續(xù)。。。。?;蛟S

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI