我們知道膊升,selenium是一個(gè)很優(yōu)秀的web框架观蓄,提供了很豐富的API址愿,使用它結(jié)合進(jìn)行做web的自動(dòng)化測(cè)試真的很完美该镣,但是在實(shí)際的情況中,理想與現(xiàn)實(shí)總是存在那么一點(diǎn)距離响谓,這點(diǎn)距離主要是難維護(hù)损合,難維護(hù)的最核心是頁面元素經(jīng)常改變省艳,測(cè)試過程中數(shù)據(jù)很多,不知道怎么進(jìn)行維護(hù)嫁审,頁面元素確實(shí)經(jīng)常改變跋炕,很難改變,另外一個(gè)就是數(shù)據(jù)問題律适,比如我們驗(yàn)證N個(gè)表單在不同輸入情況下的提示信息辐烂,會(huì)有不同的提示信息,都得需要驗(yàn)證捂贿,那么我們就先來解決元素屬性怎么來方便的維護(hù)開始棉圈。
? ? 我們知道,By類中提供了對(duì)元素定位眷蜓,總共是8個(gè)方法分瘾,單個(gè)元素定位是8個(gè),多個(gè)元素元素也是8個(gè)吁系,具體見By類的源碼:
class By(object):
? ? """
? ? Set of supported locator strategies.
? ? """
? ? ID = "id"
? ? XPATH = "xpath"
? ? LINK_TEXT = "link text"
? ? PARTIAL_LINK_TEXT = "partial link text"
? ? NAME = "name"
? ? TAG_NAME = "tag name"
? ? CLASS_NAME = "class name"
? ? CSS_SELECTOR = "css selector"
至于具體的元素定位以及方法德召,這里我就不解釋了,理由很簡單的汽纤,那是因?yàn)槲覀円獙懸粋€(gè)方法上岗,來包含頁面元素定位所有的,在框架的層面蕴坪,元素定位是沒有id,name這些東西的肴掷,我們的心中只有By類,那么如何解決寫一個(gè)方法背传,可以對(duì)這8個(gè)類型的元素定位呆瞻,單個(gè),多個(gè)包含了径玖,見基礎(chǔ)的代碼:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from? selenium.webdriver.support.expected_conditions import NoSuchElementException
class WebDriver(object):
? def __init__(self,driver):
? ? ? self.driver=driver
? def findElement(self, *loc):
? ? ? try:
? ? ? ? return self.driver.find_element(*loc)
? ? ? except NoSuchElementException as e:
? ? ? ? print 'Error details :%s' % (e.args[0])
? def findsElement(self, *loc):
? ? ? try:
? ? ? ? return self.driver.find_elements(*loc)
? ? ? except NoSuchElementException as e:
? ? ? ? print 'Error details :%s' % (e.args[0])
見如上的代碼痴脾,二個(gè)方法搞定,OK梳星,就把這些代碼叫基礎(chǔ)框架的代碼吧赞赖,下來我們要編寫對(duì)象層面的東西,也就是在一個(gè)地方維護(hù)頁面元素的屬性冤灾,OK前域,就已百度首頁的搜索為案例,對(duì)象層需要繼承我們編寫的基礎(chǔ)類WebDriver韵吨,見對(duì)象層面的代碼:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from selenium.webdriver.common.by import? By
from base import? WebDriver
class BaiduTest(WebDriver):
? so_loc=(By.ID,'kw')
? def type(self,keyword):
? ? ? self.findElement(*self.so_loc).send_keys(keyword)
? def getElement(self):
? ? ? return? self.findElement(*self.so_loc)
在對(duì)象層面中匿垄,獲取了搜索input的元素屬性,編寫了搜索輸入關(guān)鍵字的方法,下來就是測(cè)試了年堆,測(cè)試類繼承我們的對(duì)象層的類吧,見實(shí)現(xiàn)的測(cè)試代碼:
#!/usr/bin/env python
#-*-coding:utf-8-*-
import? unittest
from selenium import? webdriver
from baidu import? BaiduTest
class UiTest(unittest.TestCase,BaiduTest):
? @classmethod
? def setUpClass(cls):
? ? ? cls.driver=webdriver.Firefox()
? ? ? cls.driver.maximize_window()
? ? ? cls.driver.implicitly_wait(30)
? ? ? cls.driver.get('http://www.baidu.com')
? def test_so_001(self):
? ? ? self.type(u'搜索關(guān)鍵字')
? @classmethod
? def tearDownClass(cls):
? ? ? cls.driver.quit()
if __name__=='__main__':
? unittest.main(verbosity=2)
但是在測(cè)試用例中盏浇,沒有斷言变丧,另外一點(diǎn),存在數(shù)據(jù)绢掰,心里總感覺不美氣痒蓬,OK,把數(shù)據(jù)存在文件中滴劲,測(cè)試用例添加斷言吧攻晒,見修改后的代碼:
#!/usr/bin/env python
#-*-coding:utf-8-*-
import? unittest
from selenium import? webdriver
from baidu import? BaiduTest
def readFile(fileName):
? import? os
? f=open(os.path.join(os.path.dirname(__file__),fileName))
? return f.read()
class UiTest(unittest.TestCase,BaiduTest):
? @classmethod
? def setUpClass(cls):
? ? ? cls.driver=webdriver.Firefox()
? ? ? cls.driver.maximize_window()
? ? ? cls.driver.implicitly_wait(30)
? ? ? cls.driver.get(readFile('url.txt'))
? def test_so_001(self):
? ? ? self.type(readFile('so.txt'))
? ? ? self.assertEqual(self.getElement().get_attribute('value'),readFile('so.txt'))
? ? ?
? @classmethod
? def tearDownClass(cls):
? ? ? cls.driver.quit()
if __name__=='__main__':
? unittest.main(verbosity=2)
OK,測(cè)試用例很干凈班挖,維護(hù)元素屬性在一個(gè)地方了鲁捏,數(shù)據(jù)也是在一個(gè)地方了,只不過我們使用的是txt萧芙。