Selenium 底層實現原理詳解

Selenium 簡介

Selenium 是目前主流的用於Web應用程序測試的工具,可以直接運行在瀏覽器中,就像真正的用戶在操作一樣。

Selenium 原理

Selenium工作的過程中有三個角色,其一便是跟我們最近的自動化測試代碼:自動化測試代碼發送請求給瀏覽器的驅動;其二便是瀏覽器的驅動:每個瀏覽器都有自己的驅動,均以exe文件形式存在,比如谷歌的chromedriver.exe、火狐的geckodriver.exe、IE的IEDriverServer.exe,它來解析這些自動化測試的代碼,解析後把它們發送給瀏覽器;其三便是瀏覽器:執行瀏覽器驅動發來的指令,並最終完成工程師想要的操作。

下面以谷歌瀏覽器爲例:

首先,selenium client 會初始化一個 service 服務,通過 Webdriver 啓動瀏覽器驅動程序 chromedriver.exe;

接着通過 RemoteWebDriver 向瀏覽器驅動程序發送 HTTP 請求,瀏覽器驅動程序解析請求,並獲得 sessionId,如果再次對瀏覽器操作需攜帶此 id;

接下來打開瀏覽器,綁定特定的端口,把啓動後的瀏覽器作爲 Webdriver 的Remote Server;

打開瀏覽器後,每一條 Selenium 腳本,一個 http 請求會被創建並且發送給瀏覽器,瀏覽器執行具體的測試步驟後再將步驟執行結果返回給 Remote Server,Remote Server 又將結果返回給 Selenium 的腳本,如果是錯誤的 http 代碼我們就會在控制檯看到對應的報錯信息。

WebDriver 和 Selenium-Server 區別

你可能需要,也可能不需要 Selenium Server,取決於你打算如何使用 Selenium-WebDriver。如果你僅僅需要使用 WebDriver API,那就不需要 Selenium-Server。如果你所有的測試和瀏覽器都在一臺機器上,那麼你僅需要 WebDriver API。WebDriver 將直接操作瀏覽器。

在有些情況下,你需要使用 Selenium-Server 來配合 Selenium-WebDriver 工作,例如:
你使用 Selenium-Grid 來分發你的測試給多個機器或者虛擬機。
你希望連接一臺遠程的機器來測試一個特定的瀏覽器。
你沒有使用 Java 綁定(例如 Python, C#, 或 Ruby),並且可能希望使用 HtmlUnit Driver。

底層實現原理

下面先寫一個通過火狐瀏覽器啓動百度首頁的腳本:

from selenium import webdriver
import logging

logging.basicConfig(level=logging.DEBUG)  # 打印源碼中的日誌
driver = webdriver.Firefox()
driver.get('https://www.baidu.com')

打印日誌如下:

DEBUG:selenium.webdriver.remote.remote_connection:POST http://127.0.0.1:61123/session {"desiredCapabilities": {"goog:chromeOptions": {"args": [], "extensions": []}, "version": "", "platform": "ANY", "browserName": "chrome"}, "capabilities": {"alwaysMatch": {"goog:chromeOptions": {"args": [], "extensions": []}, "browserName": "chrome", "platformName": "any"}, "firstMatch": [{}]}}
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): 127.0.0.1:61123
DEBUG:urllib3.connectionpool:http://127.0.0.1:61123 "POST /session HTTP/1.1" 200 888
DEBUG:selenium.webdriver.remote.remote_connection:Finished Request
DEBUG:selenium.webdriver.remote.remote_connection:POST http://127.0.0.1:61123/session/5f34300c89d868afb8907145fea1639d/url {"sessionId": "5f34300c89d868afb8907145fea1639d", "url": "https://www.baidu.com"}
DEBUG:urllib3.connectionpool:http://127.0.0.1:61123 "POST /session/5f34300c89d868afb8907145fea1639d/url HTTP/1.1" 200 72
DEBUG:selenium.webdriver.remote.remote_connection:Finished Request

可以看到,首先通過 Webdriver 啓動瀏覽器驅動程序 chromedriver.exe,打開瀏覽器,並獲得 sessionId,然後再向帶上 sessionId 向瀏覽器發送打開百度主頁的請求。

下面自己通過 requests 模塊來模擬這一系列過程(執行之前首先要打開selenium-server 服務,我是使用的 selenium-server 服務,你也可以使用瀏覽器服務):

# coding=utf-8
import requests


class MySelenium:
    def __init__(self):
        self.driver = self.my_webdriver_firefox()

    def my_webdriver_firefox(self):
        '''
        獲取driver
        :return:
        '''
        driver_url = 'http://127.0.0.1:4444/wd/hub/session/'
        # 打開瀏覽器的請求參數
        driver_value = {"capabilities":
                            {"alwaysMatch":
                                 {"browserName": "firefox", }
                             }
                        }

        # 發送求清
        response_session = requests.post(driver_url, json=driver_value)
        # 獲取返回的 sessionId
        my_sessionId = response_session.json()['value']['sessionId']
        return driver_url + my_sessionId

    def my_get(self, url):
        '''
        通過get方式訪問網址
        :param url:
        :return:
        '''
        temp_url = self.driver + '/url'
        value = {'url': url}
        requests.post(temp_url, json=value)


if __name__ == '__main__':
    obj_my_selenium = MySelenium()
    obj_my_selenium.my_get('https://www.baidu.com/')

我是「Super於」,立志做一個每天都有正反饋的人!

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