WebDriver+Selenium實現瀏覽器自動化 環境準備 開發 總結 參考

前言

Selenium是一款可以自動化操作瀏覽器的開源項目,最初的目的是瀏覽器功能的自動化測試,但是隨着項目的發展,人們根據它的特性也用來做一些更多的有意思的功能而不僅僅是UI的自動化測試工具。就像Selenium官方網站上描述的那樣,Selenium可以自動化操縱瀏覽器。完了!你想用它的能力做什麼事情完全取決於你。

使用場景

針對瀏覽器的自動化測試有三個場景:

  • Selenium WebDriver:如果您想創建健壯的、基於瀏覽器的迴歸自動化套件和測試、在許多環境中擴展和分發腳本,那麼您需要使用 Selenium WebDriver,它是一組特定於語言的綁定來驅動瀏覽器——這就是它的本意驅動的
  • Selenium IDE:如果您想創建快速的錯誤重現腳本,創建腳本以幫助自動化輔助探索性測試,那麼您想使用 Selenium IDE; Chrome、Firefox 和 Edge 插件,可以對與瀏覽器的交互進行簡單的記錄和回放
  • Selenium Grid:如果您想通過在多臺機器上分發和運行測試來擴展並從一箇中心點管理多個環境,從而可以輕鬆地針對大量瀏覽器/操作系統組合運行測試,那麼您需要使用 Selenium Grid

原理

早期的Selenium目的是實現web應用的UI自動化測試,實現方式是通過三方的服務器注入js達到控制瀏覽器行爲的目的,核心的組件叫Selenium-RC(Remote Control)
包含兩個部分:

  • 客戶端側的編寫控制瀏覽器邏輯的庫
  • 實現控制瀏覽器啓動和關閉的服務器

架構如下

這種架構被證明是複雜的,而且有諸多限制,比如:

  • 複雜的架構
  • 執行測試腳本非常耗時,因爲 Selenium RC 使用 JavaScript 命令作爲瀏覽器的指令。這會導致性能下降
  • API不太面向對象
  • 不支持 Headless HTMLUnit 瀏覽器(不可見的瀏覽器)

Selenium RC 的侷限性導致了新的自動化框架 Selenium WebDriver 的開發。在 2006 年引入 WebDriver 後,RC 中出現的複雜問題可以得到解決和解決
Selenium 結合WebDriver簡化了瀏覽器的控制行爲,將中間環節的服務器去掉,直接在系統層級本地化控制瀏覽器,優化後的架構如下:


環境準備

如果你不想在編碼層實現你的功能,可以下載Selenium IDE插件,支持錄製回放,過程腳本導出。

如果需要通過代碼實現更多靈活自定義功能,建議使用python,環境準備
python3、pip3

brew install python3

selenium

pip3 install selenium

install browser drivers
設置您的系統以允許瀏覽器自動化。
通過 WebDriver,Selenium 支持市場上所有主流瀏覽器,例如 Chrome/Chromium、Firefox、Internet Explorer、Edge、Opera 和 Safari。在可能的情況下,WebDriver 使用瀏覽器的內置自動化支持來驅動瀏覽器


開發

First Script

通過webdriver實現控制瀏覽器自動訪問功能


def test_eight_components():
    driver = webdriver.Chrome()
    
    driver.get("https://google.com")
    
    title = driver.title
    assert title == "Google"
    
    driver.implicitly_wait(0.5)
    
    search_box = driver.find_element(by=By.NAME, value="q")
    search_button = driver.find_element(by=By.NAME, value="btnK")
    
    search_box.send_keys("Selenium")
    search_button.click()
    
    search_box = driver.find_element(by=By.NAME, value="q")
    value = search_box.get_attribute("value")
    assert value == "Selenium"
    
    driver.quit()

WebDriver API

webDriver操縱瀏覽器的API大致可以分爲兩個部分,控制瀏覽器行爲的比如,打開、關閉、前進、後退、刷新等和控制頁面元素的如,點擊、輸入、獲取元素內容等

瀏覽器

獲取瀏覽器信息

// title
driver.getTitle(); 
// url
driver.getCurrentUrl();

導航

//打開
driver.get("https://selenium.dev");

//跳轉
driver.navigate().to("https://selenium.dev");

// 後退
driver.navigate().back();

// 前進
driver.navigate().forward();

// 刷新
driver.navigate().refresh();

彈框

//根據條件找到頁面中的彈框並點擊
driver.findElement(By.linkText("See an example alert")).click();

//等待彈框展示並保存到變量中
Alert alert = wait.until(ExpectedConditions.alertIsPresent());

//獲得彈框內容文本
String text = alert.getText();

//點擊確定按鈕
alert.accept();
  

Alert、Confirm、Prompt功能類似
Cookies
可以支持cookies的添加刪除操作

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;

public class addCookie {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();
        try {
            driver.get("http://www.example.com");

            // Adds the cookie into current browser context
            driver.manage().addCookie(new Cookie("key", "value"));
        } finally {
            driver.quit();
        }
    }
}

Frames
支持針對Frames內元素的獲取及操作
Windows
WebDriver 不區分窗口和選項卡。如果您的站點打開一個新選項卡或窗口,Selenium 將允許您使用窗口句柄來處理它。每個窗口都有一個唯一標識符,該標識符在單個會話中保持不變。您可以使用以下方法獲取當前窗口的窗口句柄:

driver.getWindowHandle();

元素

識別和使用DOM中的元素
大多數人的 Selenium 代碼大部分都涉及使用 Web 元素。這部分功能和寫前端代碼的document.getElementById作用差不多,思想比較簡單,就是找到頁面中的元素然後執行模擬用戶行爲的操作
支持絕對定位和相對定位的策略,針對複雜頁面ID,Tag,Class不好定位的情況可以使用xPath方式,非常靈活,其實也不用死記硬背,當某元素不好定位時,可以去官網查API的方式去實現
相對定位


def relative():
    # Above
    email_locator = locate_with(By.TAG_NAME, "input").above({By.ID: "password"})
    # Below
    password_locator = locate_with(By.TAG_NAME, "input").below({By.ID: "email"})
    # Left of
    cancel_locator = locate_with(By.TAG_NAME, "button").to_left_of({By.ID: "submit"})
    # Right of
    submit_locator = locate_with(By.TAG_NAME, "button").to_right_of({By.ID: "cancel"})
    # Near
    email_locator = locate_with(By.TAG_NAME, "input").near({By.ID: "lbl-email"})
    # Chaining relative locators
    submit_locator = locate_with(By.TAG_NAME, "button").below({By.ID: "email"}).to_right_of({By.ID: "cancel"})

傳統定位

<ol id="vegetables" style="margin-top: 20px">
      <li class="potatoes">potatoes</li>
      <li class="onions">onions</li>
      <li class="tomatoes"><span>Tomato is a Vegetable</span></li>
    </ol>
    <ul id="fruits">
      <li class="bananas"></li>
      <li class="apples"></li>
      <li class="tomatoes"><span>Tomato is a Fruit</span></li>
     </ul>

def finders():
    # Evaluating entire DOM
    vegetable = driver.find_element(By.CLASS_NAME, "tomatoes")
    print(vegetable)
    # Evaluating a subset of the DOM
    fruits = driver.find_element(By.ID, "fruits")
    fruit = fruits.find_elements(By.CLASS_NAME, "tomatoes")
    print(fruit)
    # Optimized locator
    fruit = driver.find_element(By.CSS_SELECTOR, "#fruits .tomatoes")
    fruit2 = driver.find_element(By.CSS_SELECTOR, "ul .tomatoes")
    print(fruit == fruit2) # True
    # All matching elements
    plants = driver.find_elements(By.TAG_NAME, "li")
    print(plants)
    # Get all the elements available with tag name 'p'
    elements = driver.find_elements(By.TAG_NAME, 'span')
    for e in elements:
        print(e.text)


def xPath():
    ol = driver.find_element(By.XPATH, "/html/body/div/div/ol[1]")
    ol2 = driver.find_element(By.XPATH, "//ol[1]")
    ol3 = driver.find_element(By.XPATH, "//ol[@id='vegetables']")
    print(ol == ol2) # True
    print(ol == ol3) # True
    onions = driver.find_element(By.XPATH, "//ol[1]/li[2]")
    print(onions.text)

交互
5種基本命令:

  • click(任意元素)
  • send keys(僅用於文本塊和內容可編輯元素)
  • clear(同上)
  • submit (form 元素)
  • select (選擇列表元素)

獲取元素信息

總結

本次分享介紹了Selenium使用場景,簡單原理和一些的基礎用法。並列舉了一個小例子。掌握以上內容,你已經可以實現基本的UI自動化測試了。另外可以做一些爬蟲和自動化操縱瀏覽器的工具需求就需要根據個人場景化定製了,只要你有“懶”的天性,相信一定會找到挺多有意思場景使用去使用它。

參考

https://www.selenium.dev/
https://www.browserstack.com/guide/selenium-rc-tutorial

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章