selenium 自动化测试
Selenium 是一個用于Web應用程序測試的工具,支持多平臺、多瀏覽器、多語言去實現自動化測試。目前在Web自動化領域應用越來越廣泛。
selenium 介紹
Selenium的特點如下:
selenium 的組成
selenium由selenium IDE,selenium Grid、Selenium RC、Webdriver組成。其中,Webdriver是在Selenium2.0加入的,可以將其看作Selenium RC的替代品。
測試環境搭建(略)
1、安裝python
2、安裝selenium
3、安裝對應的瀏覽器驅動(各個瀏覽器驅動下載地址)
WebDriver API
Webdriver屬于selenium中設計出的操作瀏覽器的一套API,因為Webdriver針對多種編程語言都實現了一遍這套API,所以它可以支持多種編程語言,在此處我使用python語言進行程序編寫。
從定位元素開始
自動化要做的就是模擬鼠標和鍵盤來操作這些元素,或單擊,或輸入,或鼠標懸停,拖拽等。
但操作這些元素的前提是需要找到它們,自動化測試工具無法像測試人員一樣通過肉眼分辨這些元素,那么如何找到它們呢?通過查看網頁代碼,我們可以發現每一個元素都是由一行行代碼組成的,它們之間有層級地組織起來,每個元素都有自己的標簽名和屬性值,Webdriver就可以通過這些信息來找到不同元素。
WebDriver提供了八種元素定位方法 find_element_by_id() find_element_by_name() find_element_by_class_name() find_element_by_tag_name() find_element_by_link_text() find_element_by_partial_link_text() find_element_by_xpath() find_element_by_css_selector()id定位
HTML規定id屬性在HTML文檔中必須是唯一的,這類似于公民的身份證號,具有很強的唯一性。通過id定位百度輸入框與百度搜索按鈕,用法如下:
find_element_by_id("kw") find_element_by_id("su")name定位
HTML規定name來指定元素的名稱,因此它的作用更像是人的姓名。可以不唯一。通過name定位百度輸入框:
find_element_by_name("wd")百度搜索按鈕并沒有提供name屬性,因此我們不能通過name屬性來定位。
class定位
class指定元素的類名,用法與id、name類似
find_element_by_class_name("s_ipt") find_element_by_class_name("bg s_btn")tag定位
HTML的本質就是通過tag來定義實現不同的功能,每一個元素本質上就是一個tag對象。因為一個tag往往用來定義一類功能,所以通過tag來識別某一個元素的概率很低。
通過tag查找百度輸入框和百度按鈕會發現它們完全相同。
link定位
link定位與前面介紹的幾種定位方法有所不同,它專門用來定位文本鏈接,用 find_element_by_link_text 方式定位,標簽必須是的元素,才能成功。
partial link 定位
partial link定位是對link定位的一種補充,有些文本鏈接會比較長,這時候我們可以取文本鏈接的一部分定位,只需要一部分信息就可以唯一標識這個鏈接。
XPath 定位
前面介紹的幾種定位方式相對來說比較簡單,但如果有時候一個元素沒有id、name屬性,或者多個元素屬性值相同,又或者每次刷新頁面,id屬性值會隨機變化,這些情況下,我們如何定位元素?
Xpath是一種在XML文檔中定位元素的語言,因為HTML可以看作XML的一種實現,所以可以使用xpath在web應用中定位元素。
絕對路徑定位:元素的絕對路徑,從最外層html一級一級往下查找,這種方式寫出來一般可讀性不強,但比較簡單。
元素屬性定位:即通過結合屬性值來定位,一般使用這種方式查找元素(如果不想指定標簽名,則可以用星號*代替)
使用邏輯運算符
有時候一個屬性不能唯一區分一個元素,我們還可以使用邏輯運算符 and 連接多個條件來查找元素。
find_element_by_xpath('//input[@name="xxx" and @class="xxx"]')CSS 定位
CSS用來描述HTML文檔的表現,CSS使用選擇器來為頁面元素綁定屬性。這些選擇器可以被Selenium用作另外的定位策略。一般情況下定位速度比XPath快,但難度稍高。
通過 By 來定位元素
針對前面介紹的幾種定位方法,WebDriver還提供了另一套寫法,即同一調用find_element()方法。通過By來聲明定位的方法,并且傳入對應定位方法的定位參數。(上面的方法可能被棄用了)
find_element(By.ID, 'xxx') find_element(By.NAME, 'xxx') find_element(By.CLASS_NAME, 'xxx') find_element(By.TAG_NAME, 'xxx') find_element(By.LINK_TEXT, 'xxx') find_element(By.PARTIAL_LINK_TEXT, 'xxx') find_element(By.XPATH, 'xxx') find_element(By.CSS_SELECTOR, 'xxx')該方法需要兩個參數,第一個是定位的類型,第二個是定位的具體方式,在使用之前需要將By類導入。
from selenium.webdriver.common.by import By控制瀏覽器
WebDriver 主要提供的是操作頁面上各種元素的方法,但也提供了操作瀏覽器的一些方法,如控制瀏覽器大小,操作瀏覽器前進后退等。
set_window_size() 方法設置瀏覽器大小 maximize_window() 最大化 back() 后退 forward() 前進 refresh() 刷新當前頁面簡單元素操作
定位到元素之后就需要對元素進行操作,或點擊或輸入,常用方法如下:
clear() 清除文本 send_keys() 模擬輸入 click() 單擊元素 submit() 提交表單 get_attribute(name) 獲取元素屬性值 is_displayed() 返回元素是否可見 size 返回1元素尺寸 text 獲取元素文本ActionChains 鼠標事件
在WebDriver中,關于鼠標操作的方法封裝在ActionChains類中,我們可以通過ActionChains類來執行這些方法。
click(on_element=None) ——單擊鼠標左鍵 context_click(on_element=None) ——點擊鼠標右鍵 double_click(on_element=None) ——雙擊鼠標左鍵 drag_and_drop(source, target) ——拖拽到某個元素然后松開 drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某個坐標然后松開 key_down(value, element=None) ——按下某個鍵盤上的鍵 key_up(value, element=None) ——松開某個鍵 move_by_offset(xoffset, yoffset) ——鼠標從當前位置移動到某個坐標 move_to_element(to_element) ——鼠標移動到某個元素 move_to_element_with_offset(to_element, xoffset, yoffset) ——移動到距某個元素(左上角坐標)多少距離的位置 perform() ——執行鏈中的所有動作 send_keys_to_element(element, *keys_to_send) ——發送某個鍵到指定元素對于ActionChains類所提供的鼠標方法與前面學過的click()方法的用法有所不同,首先需要引入ActionChains類,然后將所有的操作按順序放在一個隊列里,在調用perform()方法時,隊列中的操作會依次執行。
# 鏈式寫法 menu = driver.find_element_by_css_selector(".nav") hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1") ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()# 分步寫法 menu = driver.find_element_by_css_selector(".nav") hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1") actions = ActionChains(driver) actions.move_to_element(menu) actions.click(hidden_submenu) actions.perform()鍵盤事件
Keys()類提供了鍵盤上按鍵的方法。send_keys()方法不僅可以模擬鍵盤輸入,還可以用來輸入鍵盤上的按鍵,包括組合鍵。使用前需引入Keys類。
send_keys(Keys.BACK_SPACE) 刪除鍵 send_keys(Keys.SPACE) 空格鍵 send_keys(Keys.TAB) 制表符 send_keys(Keys.ENTER) 回車鍵 send_keys(Keys.CONTROL,'a') 全選 send_keys(Keys.CONTROL,'c') 復制 send_keys(Keys.CONTROL,'x') 剪切 send_keys(Keys.CONTROL,'v') 粘貼 send_keys(Keys.F1) 鍵盤F1 send_keys(Keys.F12) 鍵盤F12元素等待
在瀏覽器加載頁面時,頁面上的元素可能并不是同時被加載完成的,會給元素定位增加困難。此時,我們可以通過設置元素等待改善這種問題造成的不穩定。
顯式等待
顯式等待使WebDriver等待某個條件成立時繼續執行,否則在達到最大時長時拋出異常。一般由until()或until_not()方法配合使用。
WebDriverWait(driver, timeout, poll_frequency=0.5,ignore_exception=None) # driver:瀏覽器驅動 timeout:最長超時時間,單位默認為秒 poll_frequrncy:檢測的間隔,默認0.5S ignored_exceptions:超時后的異常信息,默認拋出沒有元素的異常excepted_conditions 類提供的與其條件判斷方法
隱式等待
WebDriver 提供了implicitly_wait()方法來實現隱式等待。它相對于顯式等待并沒有明確的條件。
sleep 休眠方式
有時候我們希望腳本在執行到某一位置時做固定時間的休眠,這時可以使用sleep()方法。
多表單切換
在Web應用中經常會用到frame/iframe表單嵌套頁面的應用,但WebDriver只能在一個頁面上對元素識別與定位。此時就需要通過 switch_to.frame()方法將當前定位的主體切換為 frame/iframe表單的內嵌頁面中。
switch_to.frame()默認可以直接取表單的id或name屬性,如果沒有這兩個屬性,則可以通過其他方法先定位到元素然后傳遞給switch_to.iframe()方法進行定位。多窗口切換
類似于多表單切換,我們可以通過window_handles屬性來查看當前所有打開的窗口句柄。current_window_handle 獲得當前窗口的句柄。
警告框處理
處理JavaScript所生成的alert、confirm以及prompt 十分簡單,可以使用 switch_to_alert() 方法定位到 alert/confirm/prompt,然后使用accept/dismiss/send_keys 等方法進行操作。
text:返回文字信息 accept():接受現有警告框 dismiss:解散現有警告框 send_keys():發送文本至警告框操作 Cookie
WebDriver 操作 cookie 的方法:
get_cookies() 獲取所有cookie信息 get_cookie(name) 返回字典的key為name的cookie信息 add_cookie(cookie_dict) 添加cookie,字典對象 delete_cookie(name) 刪除指定cookiexinxi delete_all_cookies() 刪除所有cookie信息調用 JavaScript(功能強大)
WebDriver 對于瀏覽器滾動條并沒有提供相應的操作方法。在這種情況下,我們可以通過 JavaScript 來控制瀏覽器滾動條。WebDriver 提供了 execute_script() 方法來執行 JavaScript 代碼(最好是了解一下js)。
window.scrollTo('左邊距', '上邊距') 設置窗口滾動條位置窗口截圖
在自動化測試過程中,我們有時候需要對當前窗口進行截圖保存。WebDriver 提供了 get_screenshot_as_file() 來截取當前窗口。
driver.get_screenshot_as_file('文件路徑')驗證碼處理(機器學習,打碼平臺)
1、驗證碼識別技術,例如提供 Python-tesseract 來識別圖片驗證碼(光學字符識別)
2、記錄 cookie ,繞過驗證碼
Selenium IDE(略)
Selenium IDE 結合瀏覽器提供了腳本的錄制、回放以及編輯腳本功能,可以幫助我們學習自動化測試。還可以生成相應代碼。
selenium IDE 文檔
HTML 測試報告
HTMLTestRunner 是Python 標準庫 unittest 單元測試框架的一個擴展,它可以生成易于使用的HTML測試報告。下載地址,并將下載的文件保存到python Lib目錄下。
HTMLTestRunner.py 是基于Python 2 開發的,為了使其支持 Python 3 的環境,要對其進行部分修改。
第 94 行改為:import io 第 539 行改為:self.outputBuffer = io.StringIO() 第 631 行:2.x和3.x print()函數的區別 第 642 行改為:if not cls in ramp: 第 766 行改為:uo = e 第 772 行改為:ue = e具體實例如下:
import unittest from selenium import webdriver from HTMLTESTRunner import HTMLTestRunnerclass Baidu(unittest.TestCase):def setUp(self):self.driver = webdriver.Firefox()self.base_url = "http://www.baidu.com"def test_baidu_search(self):driver = self.driverdriver.get(self.base_url)driver.find_element_by_id("kw").send_keys("HTMLTestRunner")driver.find_element_by_id("su").click()def tearDown(self):self.driver.quit()if __name__ == "__main__":testunit = unittest.TestSuite()testunit.addTest(Baidu("test_baidu_search"))fp = open("./result.html", "wb")runner = HTMLTestRunner(stream=fp, title='百度搜索測試報告', description='用例執行情況:')runner.run(testunit)fp.close()selenium 項目實戰
最近在登錄慕課網時發現之前學的網課練習題沒刷,就考慮寫一個自動化程序作題,代碼如下。目前代碼功能還不夠完善(選擇填空),并不能保證正確率。僅供參考。
import time import random import selenium from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as ECstart_time = time.time() driver = webdriver.Chrome() driver.get('https://www.icourse163.org/?from=study') driver.maximize_window() driver.implicitly_wait(20)driver.find_element_by_xpath('//div[@class="unlogin"]/a').click() driver.find_element_by_xpath('//span[@class="ux-login-set-scan-code_ft_back"]').click() driver.find_element_by_xpath('//ul[@class="ux-tabs-underline_hd"]/li[2]').click() time.sleep(2)driver.switch_to.frame(driver.find_element_by_xpath('//div[@class="ux-login-urs-phone-wrap f-pr"]//iframe')) driver.find_element_by_xpath('//input[@id="phoneipt"]').send_keys('username') time.sleep(2)driver.find_element_by_xpath('//div[@class="m-container"]/div[4]/div[2]/input[2]').send_keys('password') time.sleep(2) driver.find_element_by_xpath('//div[@class="f-cb loginbox"]/a').click() WebDriverWait(driver,10).until(EC.title_is('中國大學MOOC(慕課)_國家精品課程在線學習平臺')) print('登陸成功') time.sleep(3) driver.find_element_by_xpath('//div[@class="u-navLogin-myCourse-t"]//a').click()driver.find_element_by_xpath('//div[@class="course-panel-body-wrapper"]//div[@class="box"]').click() time.sleep(5)for _ in driver.window_handles:if _ != driver.current_window_handle:driver.switch_to.window(_)time.sleep(2) driver.find_element_by_xpath('//ul[@id="j-courseTabList"]/li[4]/a').click() time.sleep(2) for xh in driver.find_elements_by_link_text('前往測驗'):xh.click()time.sleep(2)try:driver.find_element_by_link_text('開始測驗').click()except selenium.common.exceptions.NoSuchElementException as e:print(e)time.sleep(2)num = len(driver.find_elements_by_xpath('//div[@class="j-list"]/div[1]/div//ul'))for i in range(num):max_num = len(driver.find_elements_by_xpath('//div[@class="j-list"]/div[1]/div[' + str(i+1) + ']//ul/li'))r = random.randint(1,max_num)driver.find_element_by_xpath('//div[@class="j-list"]/div[1]/div[' + str(i+1) + ']//ul' + '/li[' + str(r) + ']').click()time.sleep(0.5)driver.find_element_by_xpath('//div[@class="m-quizDoing u-learn-modulewidth"]//div[@class="m-quizDoing"]/a').click()time.sleep(1)driver.find_element_by_xpath('//span[@class="j-ok-txt"]').click()time.sleep(1)driver.back()time.sleep(0.8)driver.back()time.sleep(1)driver.quit() end_time = time.time()print('cost_time:'+str(end_time-start_time))總結
以上是生活随笔為你收集整理的selenium 自动化测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手写操作系统之helloOS
- 下一篇: shell实现加密压缩文件自动解压