版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、 20/20 python webdriver 項(xiàng)目實(shí)戰(zhàn)第5章 測(cè)試模型與測(cè)試腳本優(yōu)化第一節(jié)、測(cè)試模型介紹線性測(cè)試 通過錄制或編寫腳本,一個(gè)腳本完成用戶一套完整的操作,通過對(duì)腳本的回放來進(jìn)行自動(dòng)化測(cè)試。這是早期進(jìn)行自動(dòng)化測(cè)試的一種形式;我們?cè)谏弦徽轮芯毩?xí)使用webdriver API 所編寫的腳本也是這種形式。腳本一from selenium importwebdriverimporttimedriver = webdriver.Firefox()driver.get(w.xxx.)driver.find_element_by_id(tbUserName).send_keys(username
2、)driver.find_element_by_id(tbPassword).send_keys(123456)driver.find_element_by_id(btnLogin).click()#執(zhí)行具體用例操作 driver.quit ()腳本二from selenium importwebdriverimporttimedriver = webdriver.Firefox()driver.get(w.xxx.)driver.find_element_by_id(tbUserName).send_keys(username)driver.find_element_by_id(tbPass
3、word).send_keys(123456)driver.find_element_by_id(btnLogin).click()#執(zhí)行具體用例操作 driver.quit ()通過上面的兩個(gè)腳本,我們很明顯的發(fā)現(xiàn)它的問題:一個(gè)用例對(duì)應(yīng)一個(gè)腳本,假如界面發(fā)生變化,用戶名的屬性發(fā)生改變,不得不需要對(duì)每一個(gè)腳本進(jìn)行修改,測(cè)試用例形成一種規(guī)模,我們可能將大量的工作用于腳本的維護(hù),從而失去自動(dòng)化的意義。這種模式下數(shù)據(jù)和腳本是混在一起的,如果數(shù)據(jù)發(fā)生變也也需要對(duì)腳本進(jìn)行修改。這種模式下腳本的可重復(fù)使用率很低。模塊化與庫我們會(huì)清晰的發(fā)現(xiàn)在上面的腳本中,其實(shí)有不少內(nèi)容是重復(fù)的;于是就有了下面的改進(jìn)。log
4、in.py#登錄模塊deflogin(): driver.find_element_by_id(tbUserName).send_keys(username) driver.find_element_by_id(tbPassword).send_keys(456123) driver.find_element_by_id(btnLogin).click()quit.py#退出模塊def quit_(): 測(cè)試用例:#coding=utf-8from selenium importwebdriverimportlogin,quit_ #調(diào)用登錄、退出模塊driver = webdriver.Fi
5、refox()driver.get(w.xxx.)#調(diào)用登錄模塊login.login()#其它個(gè)性化操作 #調(diào)用退出模塊quit.quit()注意,上面代碼并非完整代碼,不能運(yùn)行。 通過上面的代碼發(fā)現(xiàn),我們可以把腳本中相同的部分獨(dú)立出來,形成模塊或庫;當(dāng)腳本需要進(jìn)行調(diào)用。這樣做有兩個(gè)好處:一方面提高了開發(fā)效率,不用重復(fù)的編寫相同的腳本;另一方面提高了代碼的復(fù)用。數(shù)據(jù)驅(qū)動(dòng)數(shù)據(jù)驅(qū)動(dòng)應(yīng)該是自動(dòng)化的一個(gè)進(jìn)步;從它的本意來講,數(shù)據(jù)的改變(更新)驅(qū)動(dòng)自動(dòng)化的執(zhí)行,從而引起結(jié)果改變。這顯然是一個(gè)非常高級(jí)的概念和想法。其實(shí),我們能做到的是下面的形式。d:abcdata.txt圖4.x#coding=utf-
6、8from selenium importwebdriverimportos,timesource = open(D:abcdata.txt, r)values = source.readlines()source.close()#執(zhí)行循環(huán)for serch invalues:driver= webdriver.Firefox()driver.get(.xxxx.)driver.find_element_by_id(kw).send_keys(serch)不管我們讀取的是txt 文件,還是csv、excel 文件的之類,又或者是數(shù)組、字典函數(shù)。我們實(shí)現(xiàn)了數(shù)據(jù)與腳本的分離,換句話說,我們實(shí)現(xiàn)了參
7、數(shù)化。我們?nèi)砸磺l數(shù)據(jù),通過腳本的執(zhí)行,可以返回一千條結(jié)果出來。同樣的腳本執(zhí)行不同的數(shù)據(jù)從而得到了不同的結(jié)構(gòu)。是不是增強(qiáng)的腳本的復(fù)用性呢!其實(shí),這對(duì)開發(fā)來說是完全沒有什么技術(shù)含量的;對(duì)于當(dāng)初QTP 自動(dòng)化工具來說確是一個(gè)買點(diǎn),因?yàn)樗鎸?duì)的大多是不懂開發(fā)的測(cè)試。關(guān)鍵字驅(qū)動(dòng)理解了數(shù)據(jù)驅(qū)動(dòng),無非是把“數(shù)據(jù)”換成“關(guān)鍵字”,關(guān)鍵字的改變引起測(cè)試結(jié)果的改變。關(guān)鍵字驅(qū)動(dòng)用編程方式就不太容易表現(xiàn)了。QTP 、 robot framework 等自動(dòng)化工具都提供了關(guān)鍵字驅(qū)動(dòng)(填表格)。好吧!我能說selenium IDE 也是關(guān)鍵字驅(qū)動(dòng)么?圖5.x轉(zhuǎn)化成表格是這樣的:圖4.xSelenium IDE 腳本分:
8、命令(mand)、對(duì)象(mand)、值(value)格式就那里不偏不移,通過這樣的格式去描述不同的對(duì)象,從而引起最終結(jié)果的改變。也就是說一切以對(duì)象為出發(fā)點(diǎn)。當(dāng)然,這樣的腳本,顯然對(duì)于不懂代碼的同學(xué)非常直觀!我要找誰(對(duì)象)?怎么做(命令)?做什么(值)?更高級(jí)的關(guān)鍵字驅(qū)動(dòng),可以自己定義keyword然后“注冊(cè)”到框架;從而實(shí)現(xiàn)更強(qiáng)大的功能和擴(kuò)展性。關(guān)鍵字更詳細(xì)的理解可以看我偶像的那偏文章。這里簡(jiǎn)單介紹了自動(dòng)化測(cè)試的幾種不同的模型,雖然簡(jiǎn)單闡述了他們的優(yōu)缺點(diǎn),但他們并非后后者淘汰前者的關(guān)系,在實(shí)施自動(dòng)化更多的是以需求為出發(fā)點(diǎn),混合的來使用以上模型去解決問題;使我們的腳本更易于開發(fā)與維護(hù)。第二節(jié)、
9、登錄模塊化通過上一節(jié)對(duì)測(cè)試模型的學(xué)習(xí)可以看到,在我們的目前的腳本中還是有很多可以模塊化的地方,比如登錄模塊。我們的每一個(gè)用例的執(zhí)行都需要登錄腳本,那可我們是否可以將登錄腳本獨(dú)立到單獨(dú)的文件調(diào)用。下面以快播私有云的登錄退出測(cè)試用例為例:webcloud.py#coding=utf-8from selenium import webdriverfrom selenium.webdriver.mon.by import Byfrom selenium.webdriver.mon.keys import Keysfrom selenium.webdriver.support.ui import Sel
10、ectfrom selenium.mon.exceptions import NoSuchElementExceptionimport unittest, timeclass Login(unittest.TestCase): def setUp(self): self.driver = webdriver.Firefox() self.driver.implicitly_wait(30) self.base_url = passport.kuaibo. self.verificationErrors = self.accept_next_alert = True #私有云登錄用例 def t
11、est_login(self): driver = self.driver driver.get(self.base_url + /login/?referrer=http%3A%2F%2Fwebcloud.kuaibo.%2F) driver.maximize_window() #登陸 driver.find_element_by_id(user_name).clear() driver.find_element_by_id(user_name).send_keys(username) driver.find_element_by_id(user_pwd).clear() driver.fi
12、nd_element_by_id(user_pwd).send_keys(123456) driver.find_element_by_id(dl_an_submit).click() time.sleep(3) #新功能引導(dǎo) driver.find_element_by_class_name(guide-ok-btn).click() time.sleep(3) #退出 driver.find_element_by_class_name(Usertool).click() time.sleep(2) driver.find_element_by_link_text(退出).click() t
13、ime.sleep(2) def tearDown(self): self.driver.quit() self.assertEqual(, self.verificationErrors)if _name_ = _main_: unittest.main()從業(yè)務(wù)流程及用例分析,每一個(gè)自動(dòng)化測(cè)試用例的執(zhí)行過程為:先執(zhí)行登錄操作,然后執(zhí)行具體的操作(如文件/文件夾的創(chuàng)建、刪除、移動(dòng)、重命名等操作),最后執(zhí)行退出操作。如上面的測(cè)試用例,登錄與退出操作是相對(duì)固定的,那么我們可以把登錄與退出操作模塊化出去,然后調(diào)用,一方面不用寫重復(fù)代碼,另一方面可以使測(cè)試用例更關(guān)注具體的用例代碼。login.py在
14、與webcloud.py相同的文件夾下創(chuàng)建login.py 文件:#coding=utf-8from selenium import webdriverfrom selenium.mon.exceptions import NoSuchElementExceptionimport unittest, timedef login(self): driver = self.driver driver.maximize_window() driver.find_element_by_id(user_name).clear() driver.find_element_by_id(user_name).
15、send_keys(username) driver.find_element_by_id(user_pwd).clear() driver.find_element_by_id(user_pwd).send_keys(123456) driver.find_element_by_id(dl_an_submit).click() time.sleep(3)webcloud.py#coding=utf-8from selenium import webdriverfrom selenium.webdriver.mon.by import Byfrom selenium.webdriver.mon
16、.keys import Keysfrom selenium.webdriver.support.ui import Selectfrom selenium.mon.exceptions import NoSuchElementExceptionimport unittest, timeimport login #導(dǎo)入登錄文件class Login(unittest.TestCase): def setUp(self): self.driver = webdriver.Firefox() self.driver.implicitly_wait(30) self.base_url = passp
17、ort.kuaibo. self.verificationErrors = self.accept_next_alert = True #私有云登錄用例 def test_login(self): driver = self.driver driver.get(self.base_url + /login/?referrer=http%3A%2F%2Fwebcloud.kuaibo.%2F) #調(diào)用登錄模塊 login.login(self) #新功能引導(dǎo) driver.find_element_by_class_name(guide-ok-btn).click() time.sleep(3)
18、 #退出 driver.find_element_by_class_name(Usertool).click() time.sleep(2) driver.find_element_by_link_text(退出).click() time.sleep(2) def tearDown(self): self.driver.quit() self.assertEqual(, self.verificationErrors)if _name_ = _main_: unittest.main()進(jìn)行到這里,我們有必要補(bǔ)充一下python語言中函數(shù)、類、方法的使用,這將有助于我們自動(dòng)化測(cè)試腳本的開發(fā)。
19、下面打開python IDLE:函數(shù)的使用:#例1 def add(a,b):c=a+bprint c add(1,3)4#例2 def add2(a=1,b=3):c=a+breturn c d=add2() print d4通過def 關(guān)鍵字可創(chuàng)建函數(shù),在例1中我們創(chuàng)建了add()函數(shù),默認(rèn)接收兩個(gè)參數(shù)化a、b,對(duì)a、b相加結(jié)果給c,并將結(jié)果函數(shù)內(nèi)打印。例2中創(chuàng)建了add2()函數(shù),這一次對(duì)a、b設(shè)置了默認(rèn)值,同樣對(duì)a、b做加法,并將結(jié)果用return返回;d在接收add2()時(shí)用的是默認(rèn)值,將后將d接收的結(jié)果打印。類與方法的使用: class Counter: def add(self,
20、a,b): c=a+b print c def subtract(self,a,b): c=a-b print c d=Counter() d.add(5,3)8 d.subtract(5,3)2通過class關(guān)鍵字我們創(chuàng)建了一個(gè)Counter類,定義了add()和subtract()兩個(gè)方法分別來完成加法和減法運(yùn)算,并將計(jì)算結(jié)果打印。通過上面的例子我們明顯的發(fā)現(xiàn)類的方法與函數(shù)有一個(gè)明顯的區(qū)別,在類的方法中必須有個(gè)額外的第一個(gè)參數(shù)(self),但在調(diào)用類的方法時(shí)卻不必為這個(gè)參數(shù)賦值。self參數(shù)所指的是對(duì)象本身,所以習(xí)慣性地命名為self。為何Python給self賦值而你不必給self賦值?
21、創(chuàng)建了一個(gè)類MyClass,實(shí)例化MyClass得到了MyObject這個(gè)對(duì)象,然后調(diào)用這個(gè)對(duì)象的方法MyObject.method(a,b),在這個(gè)過程中,Python會(huì)自動(dòng)轉(zhuǎn)為Myclass.method(MyObject,a,b),這就是Python的self的原理。即使你的類的方法不需要任何參數(shù),但還是得給這個(gè)方法定義一個(gè)self參數(shù),雖然我們?cè)趯?shí)例化調(diào)用的時(shí)候不用理會(huì)這個(gè)參數(shù)。下面回到用例本身來討論如何模塊化和調(diào)用的,在login.py 文件中:def login(self): driver = self.driver這里用到的是方法,(driver = self.driver)dr
22、iver 為對(duì)象身的driver,這一句很重要,否則我們無法在ligin()方法中使用driver操作瀏覽器。在webdriver.py 文件中:#導(dǎo)入登錄文件import login . #調(diào)用登錄模塊 login.login(self).首先導(dǎo)入login文件,然后對(duì)文件中的login()方法進(jìn)行調(diào)用。下面筆者動(dòng)手把退出的相關(guān)操作也模塊化出去吧!第三節(jié)、數(shù)據(jù)驅(qū)動(dòng)(參數(shù)化)在測(cè)試模型一節(jié)的數(shù)據(jù)驅(qū)動(dòng)中我們已經(jīng)介紹了如何通過python的readlines()函數(shù)對(duì)百度輸入信息進(jìn)行參數(shù)化設(shè)置,將其它循環(huán)的讀取data.txt文件中每一行數(shù)據(jù)。這里再回顧一下實(shí)現(xiàn)參數(shù)化的方式。baidu_read_
23、data.py#coding=utf-8from selenium import webdriverimport os,timesource = open(D:abcdata.txt, r) values = source.readlines() source.close()# 執(zhí)行循環(huán)for serch in values: browser = webdriver.Firefox() browser.get(.baidu.) browser.find_element_by_id(kw).send_keys(serch) browser.find_element_by_id(su).click
24、() browser.quit()open方法以只讀方式(r)打開本地的data.txt 文件,readlines方法是逐行的讀取文件內(nèi)容。通過for循環(huán),serch 可以每次獲取到文件中的一行數(shù)據(jù),在定位到百度的輸入框后,將數(shù)據(jù)傳入send_keys(serch)。這樣通過循環(huán)調(diào)用,直到文件的中的所有內(nèi)容全被讀取。登錄參數(shù)化(讀取txt文件)現(xiàn)在按照上面的思路,對(duì)自動(dòng)化腳本中用戶、名密碼進(jìn)行參數(shù)化,通過python文檔我們發(fā)現(xiàn)python讀取文件的方式有:整個(gè)文件讀取、逐行讀取、固定字節(jié)讀取。并沒有找到一次讀取兩條數(shù)據(jù)的好方法。創(chuàng)建兩個(gè)文件,分別存放用戶名密碼,如圖6.x:圖6.x打開之前編
25、寫的login.py文件,做如下修改:#coding=utf-8from selenium import webdriverfrom selenium.mon.exceptions import NoSuchElementExceptionimport unittest, time, ossource = open(D:selenium_pythondatausername.txt, r) #用戶名文件un = source.read() #讀取用戶名source.close()source2 = open(D:selenium_pythondatapassword.txt, r) #密碼文件
26、pw = source2.read() #讀取密碼source2.close()def login(self): driver = self.driver driver.maximize_window() driver.find_element_by_id(user_name).clear() driver.find_element_by_id(user_name).send_keys(un) driver.find_element_by_id(user_pwd).clear() driver.find_element_by_id(user_pwd).send_keys(pw) driver.
27、find_element_by_id(dl_an_submit).click() time.sleep(3)分別打開兩個(gè)txt文件,通過un 和pw來接收用戶名和密碼信息,將接收的數(shù)據(jù)通過send_key(xx)轉(zhuǎn)入到執(zhí)行程序中。運(yùn)行我們前面創(chuàng)建的webcloud.py文件,程序可以正常的執(zhí)行。雖然這樣做比較丑,但是確實(shí)達(dá)到了數(shù)據(jù)與腳本分離的目的。缺點(diǎn):雖然目的達(dá)到了這,但這樣的實(shí)現(xiàn)有很多問題:用戶名密碼分別在不同的文件里,修改用戶名和密碼比較麻煩。username.txt和password.txt文件中只能保存一個(gè)用戶密碼,無能很好的循環(huán)讀取。登錄參數(shù)化(函數(shù))函數(shù)是我們前面剛介紹的pyth
28、on知識(shí),函數(shù)可以預(yù)先給參數(shù)化賦值,借助這個(gè)特性,我們可以通過調(diào)用函數(shù)的方式對(duì)用戶名密碼進(jìn)行參數(shù)化userinfo.pydef fun(un=testing,pw=123456): print success reader username and password! return un,pw 我們?yōu)閮蓚€(gè)參數(shù)un和pw賦了初值,賦值內(nèi)容如果是字符串需要加引號(hào),如果是數(shù)字可以不需要引號(hào)。再次打開login.py文件,做如下修改:#coding=utf-8from selenium import webdriverfrom selenium.mon.exceptions import NoSuch
29、ElementExceptionimport unittest, timeimport userinfo #導(dǎo)入函數(shù)#通過兩個(gè)變量,來接收調(diào)用函數(shù)獲得用戶名&密碼us,pw = userinfo.fun()#打印兩個(gè)變量print us,pwdef login(self): driver = self.driver driver.maximize_window() driver.find_element_by_id(user_name).clear() driver.find_element_by_id(user_name).send_keys(un) driver.find_element_
30、by_id(user_pwd).clear() driver.find_element_by_id(user_pwd).send_keys(pw) driver.find_element_by_id(dl_an_submit).click() time.sleep(3)單獨(dú)運(yùn)行l(wèi)ogin.py 文件: = RESTART = success reader username and password!testing 123456說明我們對(duì)函數(shù)的參數(shù)調(diào)用是成功的,將un、pw兩個(gè)變量的值傳入用戶名密碼的send_keys()方法中即可。登錄參數(shù)化(讀取字典)既然我們是固定的讀取用戶名和密碼兩個(gè)值,
31、那么可以借助python字典的方式來完成這個(gè)需求。字典由大括號(hào)內(nèi)的多鍵值對(duì)組成;下面繼續(xù)在python IDLE交互模式下演示字典的創(chuàng)建與使用。 data = abc:123,def:456 print dataabc: 123, def: 456 data.keys()abc, def data.values()123, 456 data.items()(abc, 123), (def, 456)創(chuàng)建字典用大括號(hào),數(shù)據(jù)由key/value 鍵值對(duì)組成,keys()方法返回字典中的鍵列表。values()返回字典中的值列表,items()返回(key,value)元組。下面創(chuàng)建一個(gè)存放字典的函
32、數(shù) 文件userinfo.py :def zidian(): data=username:123456,testing360:123123 print success reader username and password! return data字典的可以方便的存放k,v 鍵值對(duì),一個(gè)鍵對(duì)應(yīng)一個(gè)值;注意,如果密碼中有非數(shù)字,需要加引號(hào)。需要說明的是我們的需求并不適合循環(huán)的讀取用戶名密碼,不過我們可以寫一小程序單獨(dú)驗(yàn)證這種循環(huán)讀取的方式:loop_reader.py#coding=utf-8import userinfo #導(dǎo)入函數(shù)#獲取字典數(shù)據(jù)info = userinfo.zidian(
33、)#通過items()循環(huán)讀取元組(鍵/值對(duì))for us,pw in info.items(): print us print pw運(yùn)行結(jié)果如下: = RESTART = success reader username and password!username123456testing360123456在實(shí)際使用中,可以將un、pw兩個(gè)變量循環(huán)獲得的值傳入相應(yīng)的send_keys()方法中。目前方式解決了兩個(gè)問題:一次傳入兩個(gè)值,以及循環(huán)讀取。表單參數(shù)化(csv)假如我有自動(dòng)化腳本中要參數(shù)化一X表單,表單需要填寫用戶名、,年齡,性別等信息,使用上面的方法就很難來解決這個(gè)問題,下面通過讀取csv文件的方法來解決這個(gè)問題。創(chuàng)建userinfo.csv文件,如圖5.x圖5.x通過WPS 或exc
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年石油化工產(chǎn)品購(gòu)銷合同6篇
- 二零二五年度汽車報(bào)廢車輛運(yùn)輸合同3篇
- 二零二五年度環(huán)保節(jié)能型建筑材料安裝與檢測(cè)合同范本2篇
- 二零二五版海運(yùn)出口運(yùn)輸代理合同貨物跟蹤協(xié)議3篇
- 二零二五版網(wǎng)絡(luò)安全項(xiàng)目反擔(dān)保合同規(guī)定3篇
- 二零二五版二手房買賣合同貸款流程解析3篇
- 二零二五年數(shù)字電影后期制作聘用合同2篇
- 2025年度國(guó)際承包工程合同安全責(zé)任及防護(hù)措施規(guī)定3篇
- 二零二五版工業(yè)園區(qū)消防安全管理綜合服務(wù)合同3篇
- 二零二五版建筑工地勞務(wù)人員臨時(shí)住宿及伙食合同3篇
- 2025寒假散學(xué)典禮(休業(yè)式)上校長(zhǎng)精彩講話:以董宇輝的創(chuàng)新、羅振宇的堅(jiān)持、馬龍的熱愛啟迪未來
- 安徽省示范高中2024-2025學(xué)年高一(上)期末綜合測(cè)試物理試卷(含答案)
- 安徽省合肥市包河區(qū)2023-2024學(xué)年九年級(jí)上學(xué)期期末化學(xué)試題
- 《酸堿罐區(qū)設(shè)計(jì)規(guī)范》編制說明
- PMC主管年終總結(jié)報(bào)告
- 售樓部保安管理培訓(xùn)
- 倉(cāng)儲(chǔ)培訓(xùn)課件模板
- 2025屆高考地理一輪復(fù)習(xí)第七講水循環(huán)與洋流自主練含解析
- GB/T 44914-2024和田玉分級(jí)
- 2024年度企業(yè)入駐跨境電商孵化基地合作協(xié)議3篇
- 《形勢(shì)與政策》課程標(biāo)準(zhǔn)
評(píng)論
0/150
提交評(píng)論