Selenium 是一套廣泛使用的網頁自動化測試工具,搭配 Python 更能發揮其強大功能。本文從 Selenium 的安裝與基本操作開始,逐步深入講解如何操作網頁元素、擷取網頁資訊,並示範如何設定瀏覽器選項、隱式等待時間等技巧。同時也涵蓋了錯誤處理機制、命令列引數的應用,以及如何將 Selenium 應用於網頁爬蟲的開發。最後,文章也探討瞭如何將 Selenium 整合到 Docker 容器中,實作更便捷、一致的測試環境,並簡要介紹了組態管理與軟體物料清單(SBOM)的重要性。

使用Selenium與Python進行網頁自動化測試

網頁自動化測試是確保網頁應用程式功能正確性的重要步驟。Selenium是一個流行的工具,能夠模擬使用者操作瀏覽器,進行自動化測試。本章將介紹如何使用Selenium與Python進行網頁自動化測試。

Selenium與Python的基本使用

首先,我們需要安裝Selenium。可以使用pip進行安裝:

pip install selenium

接下來,我們將使用Selenium控制Firefox瀏覽器進行網頁操作。以下是範例程式碼:

from selenium import webdriver
from selenium.webdriver.firefox.options import Options

# 設定Firefox選項
opts = Options()
opts.add_argument('--headless')  # 以無頭模式執行

# 建立webdriver物件
driver = webdriver.Firefox(options=opts)

# 設定隱式等待時間為10秒
driver.implicitly_wait(10)

# 開啟網頁
proto_scheme = "https://"
url = "www.example.com"
driver.get(proto_scheme + url)

# 擷取網頁截圖
driver.get_screenshot_as_file('screenshot.png')

# 取得網頁原始碼
result_file = 'page-source_' + url.replace("://", "_").replace("/", "_")
with open(result_file, 'w') as f:
    f.write(driver.page_source)

# 關閉瀏覽器
driver.close()
driver.quit()

內容解密:

  1. Selenium設定:使用webdriver.FirefoxOptions()設定Firefox瀏覽器的執行選項。在此範例中,我們使用--headless引數使瀏覽器在背景執行,而不顯示圖形介面。
  2. webdriver建立:透過webdriver.Firefox(options=opts)建立一個Firefox的webdriver物件,並將之前設定的選項傳入。
  3. 網頁操作:使用driver.get()開啟指定的網頁。driver.implicitly_wait(10)設定隱式等待時間為10秒,確保網頁有足夠時間載入。
  4. 截圖與原始碼擷取:使用driver.get_screenshot_as_file()擷取網頁截圖,並將網頁原始碼寫入檔案中。
  5. 資源釋放:最後使用driver.close()driver.quit()關閉瀏覽器並釋放資源。

擷取網頁特定元素

在進行網頁測試時,我們經常需要檢查特定的網頁元素。例如,檢查登入後頁面是否顯示正確的歡迎訊息。以下範例展示如何擷取包含「Copyright」文字的段落元素:

from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.common.by import By

# 設定Firefox選項
opts = Options()
opts.add_argument('--headless')

# 建立webdriver物件
driver = webdriver.Firefox(options=opts)
driver.implicitly_wait(10)

# 開啟網頁
proto_scheme = "https://"
url = "www.braingia.org"
driver.get(proto_scheme + url)

# 擷取包含「Copyright」文字的元素
copyright_element = driver.find_element(By.XPATH, "//p[contains(text(),'Copyright')]")

# 列印元素的文字內容
print(copyright_element.text)

# 關閉瀏覽器
driver.close()
driver.quit()

內容解密:

  1. 元素定位:使用driver.find_element(By.XPATH, "//p[contains(text(),'Copyright')]")透過XPath定位包含「Copyright」文字的段落元素。
  2. 文字擷取:使用copyright_element.text取得元素的文字內容,並列印出來。
  3. 資源釋放:同樣在最後關閉瀏覽器並釋放資源。

改善與進階應用

  1. 錯誤處理:將程式碼放在try/except區塊中,可以捕捉並處理執行過程中可能發生的錯誤,避免程式意外終止。
  2. 命令列引數:可以將初始URL作為命令列引數傳入程式,使其更具彈性。
  3. 爬蟲功能:可以進一步開發爬蟲功能,自動收集網頁中的連結並進行存取。

Selenium 自動化測試流程

  graph LR
    A[開始] --> B[建立webdriver]
    B --> C[開啟網頁]
    C --> D[擷取截圖]
    D --> E[擷取網頁原始碼]
    E --> F[檢查特定元素]
    F --> G[關閉瀏覽器]
    G --> H[結束]

圖表翻譯: 此圖示展示了使用Selenium進行自動化測試的主要流程。首先建立webdriver物件,接著開啟指定的網頁,然後擷取網頁截圖與原始碼,並檢查特定的網頁元素。最後關閉瀏覽器,完成測試流程。

  1. 整合CI/CD流程:將Selenium測試整合到CI/CD流程中,實作自動化測試與佈署。
  2. 多瀏覽器支援:擴充套件測試範圍,支援多種瀏覽器,確保網頁應用在不同環境下的相容性。
  3. 智慧測試:結合機器學習技術,使測試更加智慧化,能夠自動偵測並修復問題。

透過這些進階應用,可以進一步提升網頁自動化測試的效率與準確性,為開發團隊提供更強大的支援。

組態管理作為程式碼和軟體物料清單(SBOM)

在現代化的IT基礎設施中,組態管理扮演著至關重要的角色。伺服器的行為、監聽的埠、可用站點以及其他行為都由組態決定。就像原始碼的變更一樣,服務的組態也會隨著新功能的新增和開發人員或其他類別似原因對組態變更的需求而變化。使用源控制管理(SCM)來管理組態檔案與管理原始碼具有相同的優點。變更可以在時間上被追蹤,使用佈署工具進行管理,並且在需要時可以回復到已知良好的版本。

組態檔案倉函式庫結構

組態檔案的倉函式庫結構根據操作環境和基礎設施的不同而有很大差異。例如,可能存在需要與生產環境相同的組態檔案的品質保證環境,但某些組態(如生產資料函式庫的憑證和主機名)除外。

一種倉函式庫結構方法是根據環境儲存組態檔案。這種結構可能導致組態檔案無意中不同。例如,如果需要在測試環境中的Web伺服器組態中進行更改,則該更改需要手動傳播到其他環境。如果未包含該更改,則在專案邁向生產時可能會導致其他環境的停機。

每應用倉函式庫結構

可以使用每應用倉函式庫結構來緩解每環境倉函式庫的環境問題。例如,管理Web伺服器組態,將頂層目錄命名為webserver,並使用分支和標籤來變更檔案,這樣既利用了SCM的優勢,又保持了檔案的簡單性。結果是,當專案需要新版本的組態檔案時,可以對該檔案進行標記。隨著專案從開發到測試再到生產,可以有意使用該標記作為組態。考慮以下目錄結構:

configs/
webserver/
common/
host-specific/
databaseserver/
common/
host-specific/
firewall/
common/
host-specific/

Apache 組態檔案範例

儲存在通用Web伺服器組態目錄中的檔案的一個例子是Debian安裝中的apache2.conf檔案,該檔案包含通用組態項並參照其他組態檔案和目錄:

Mutex file:${APACHE_LOCK_DIR} default
PidFile ${APACHE_PID_FILE}
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
HostnameLookups Off
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf
Include ports.conf
<Directory />
    Options FollowSymLinks
    AllowOverride None
    Require all denied
</Directory>
<Directory /usr/share>
    AllowOverride None
    Require all granted
</Directory>
<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>
AccessFileName .htaccess
<FilesMatch "^\.ht">
    Require all denied
</FilesMatch>
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
IncludeOptional conf-enabled/*.conf
IncludeOptional sites-enabled/*.conf

內容解密:

此組態檔案定義了Apache伺服器的基本組態,包括日誌格式、目錄存取許可權等。LogFormat指令定義了日誌記錄的格式,可以根據需要進行修改。例如,可以新增%{X-Forwarded-For}i指令來捕捉使用負載平衡或雲端服務提供商時的客戶端IP地址。

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D %v %{X-Forwarded-For}i" xforward

主機特定組態

對於基礎設施中的不同伺服器和微服務,可能需要特定的組態。這些組態檔案儲存在主機特定的目錄中。例如,在host-specific目錄下,可能會有公共面對的Web伺服器、身份驗證Web服務和產品Web服務的組態:

host-specific/
public-web/
authentication-ws/
product-ws/

主機特定組態檔案範例

一個Web伺服器的組態檔案(來自預設的Debian安裝)是應用特定組態的一個例子,它受益於這種層次結構:

<VirtualHost *:80>
    ServerName www.example.com
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

內容解密:

此組態檔案定義了一個虛擬主機,指定了伺服器名稱、檔案根目錄和日誌檔案的位置。對於不同的服務(如身份驗證Web服務),這些組態項需要根據服務的具體需求進行更改。

<VirtualHost *:80>
    ServerName ws-auth.example.com
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/ws-auth
    ErrorLog ${APACHE_LOG_DIR}/ws-auth-error.log
    CustomLog ${APACHE_LOG_DIR}/ws-auth-access.log combined
</VirtualHost>

版本控制下的組態管理

將這些組態檔案置於版本控制之下(如Git),可以追蹤任何更改,從而實作回復和歷史記錄功能。然而,上述結構並未解決不同環境(如開發環境和生產環境)之間的差異。

處理不同環境的組態

與測試環境相關的細節可以透過兩種方式處理,具體取決於流程中自動化的程度和複雜性。手動過程涉及在每個應用特定目錄結構中建立另一層目錄,每個環境對應一個目錄,例如:

host-specific/
public-web/
dev/
internal-test/
integration/
user-qa/
production/
authentication-ws/
dev/
internal-test/
integration/
user-qa/
production/

內容解密:

這種結構允許根據不同的環境進行組態管理,從而使得組態檔案的管理更加靈活和可控。

自動化佈署與容器化技術的整合應用

在現代軟體開發與佈署流程中,如何有效管理不同環境之間的組態差異是一項重要的挑戰。組態偏差(configuration skew)可能導致非預期的問題,特別是在開發、測試和生產環境之間。本文將探討組態管理、軟體物料清單(SBOM)、容器化技術(特別是 Docker)等關鍵概念,並分析其在自動化 DevSecOps 中的應用。

組態管理與自動化

組態管理是確保軟體系統在不同環境中穩定執行的關鍵。傳統的根據環境的組態結構(per-environment structure)可能導致組態偏差的問題。例如,在開發環境中啟用的除錯選項可能意外地被帶入生產環境,從而引起問題。

組態偏差的挑戰

組態偏差可能源於不同環境之間的組態差異。例如,開發環境可能需要更詳細的日誌記錄或效能調優選項,而這些組態變更可能不會被同步到其他環境的組態檔案中。這種不一致性可能導致不可預見的問題,並增加了維護的複雜度。

動態組態管理

為瞭解決組態偏差的問題,現代組態管理工具提供了動態組態檔案的構建能力。組態檔案儲存在原始碼管理的倉函式庫中,但環境特定的資訊在佈署時動態取得。這種方法可以有效避免組態偏差,並提高自動化程度。

import os

def generate_config(env):
    config = {
        'logging': {
            'level': 'DEBUG' if env == 'development' else 'INFO'
        },
        'performance': {
            'tuning': True if env in ['development', 'test'] else False
        }
    }
    return config

# 使用範例
env_config = generate_config('development')
print(env_config)

內容解密:

上述 Python 程式碼展示瞭如何根據不同的環境動態生成組態。generate_config 函式接受環境名稱作為輸入,並傳回一個包含環境特定組態的字典。開發環境中,日誌級別被設定為 DEBUG,而在其他環境中則為 INFO。此外,效能調優選項僅在開發和測試環境中啟用。

軟體物料清單(SBOM)與供應鏈安全

軟體物料清單(SBOM)是一種用於跟蹤軟體元件及其依賴關係的重要工具。SBOM 包含了每個軟體元件的詳細資訊,如供應商名稱、元件名稱、版本號、依賴關係等。這些資訊對於確保軟體供應鏈的安全至關重要。

SBOM 的重要性

SBOM 可以幫助開發者驗證和驗收應用程式的每個組成部分。當發現新的漏洞時,SBOM 可以用來檢查應用程式是否使用了受影響的元件,從而採取相應的修復措施。

{
  "components": [
    {
      "name": "express",
      "version": "4.17.1",
      "supplier": "npm",
      "dependencies": ["body-parser", "cookie-parser"]
    },
    {
      "name": "react",
      "version": "17.0.2",
      "supplier": "npm",
      "dependencies": ["react-dom"]
    }
  ]
}

內容解密:

上述 JSON 示例展示了一個簡化的 SBOM 結構。該 SBOM 列出了應用程式使用的兩個主要元件:expressreact,並包含了它們的版本號、供應商以及依賴的其他元件。這種詳細的記錄有助於管理和維護軟體供應鏈的安全。

Docker 與容器化技術

Docker 是目前最流行的容器化技術之一。容器化技術使得應用程式能夠在隔離的環境中執行,從而提高了佈署的靈活性和安全性。

容器與映像的概念

容器是一種用於抽象硬體資源的軟體環境,類別似於虛擬機器,但更輕量。容器從映像(image)啟動,映像包含了作業系統和應用程式的檔案。與虛擬機器不同,容器分享主機的作業系統核心,因此啟動更快,資源佔用更少。

# 使用官方 Node.js 映像作為基礎
FROM node:14

# 設定工作目錄
WORKDIR /app

# 複製 package.json 並安裝依賴
COPY package*.json ./
RUN npm install

# 複製應用程式碼
COPY . .

# 暴露埠
EXPOSE 3000

# 執行應用程式
CMD ["node", "app.js"]

內容解密:

上述 Dockerfile 展示瞭如何構建一個 Node.js 應用程式的 Docker 映像。該 Dockerfile 使用官方的 Node.js 映像作為基礎,設定工作目錄,安裝依賴,複製應用程式碼,並暴露應用程式執行的埠。最後,定義了容器啟動時執行的命令。

自動化 DevSecOps 的實踐

容器化技術是實作自動化 DevSecOps 的重要工具之一。透過將應用程式及其依賴封裝到容器中,可以確保應用程式在不同環境中的一致性,從而簡化了佈署和管理的過程。

容器化的優勢

容器化技術提供了多項優勢,包括:

  • 環境一致性:容器確保了開發、測試和生產環境的一致性。
  • 快速佈署:容器啟動速度快,可以快速佈署和擴充套件。
  • 資源隔離:容器提供了應用程式之間的資源隔離,提高了安全性和穩定性。
  graph LR
    A[開發] -->|程式碼提交|> B[CI/CD 管道]
    B -->|構建|> C[容器映像]
    C -->|推播|> D[容器倉函式庫]
    D -->|佈署|> E[生產環境]
    E -->|執行|> F[容器化應用]

圖表翻譯: 此圖示展示了從開發到佈署的 CI/CD 流程。首先,開發者提交程式碼到版本控制系統,觸發 CI/CD 管道。管道負責構建容器映像,並將其推播到容器倉函式庫。最後,容器映像被佈署到生產環境中執行。