一體化瀏覽器自動化框架:
網路爬行/測試/抓取/隱形
開始| ?特點| ?️ 選項 |範例 | ?腳本 |移動的
API | ?格式 | ?錄音機|儀表板| ?語言環境 |農場
?️ 圖形使用者介面 | ?測試頁 | ?統一通訊模式 | ? CDP模式| ?圖表|網格
? ?遷移 |案例計劃 | ♻️ 模板 | ?混合動力| ?旅遊
?持續整合/持續交付 | ?️ JSMgr | ?譯者|主持人| ?對話 | ?️ 視覺
SeleniumBase 是用於 Web 自動化活動的專業工具包。專為測試網站、繞過驗證碼、提高工作效率、完成任務和擴展業務而建置。
從SeleniumBase/examples/資料夾中的200 多個範例中學習。
?請注意, SeleniumBase UC 模式(隱形模式)有自己的自述文件。
?另請注意,Seleniumbase CDP 模式有其自己單獨的自述文件。
腳本可以透過python
調用,儘管某些語法格式需要pytest (SeleniumBase 中包含的 Python 單元測試框架,可以自動發現、收集和執行測試)。
?這是 my_first_test.py,它測試登入、購物和結帳:
pytest my_first_test.py
pytest
預設使用--chrome
,除非設定不同。
?這是 test_coffee_cart.py,它驗證電子商務網站:
pytest test_coffee_cart.py --demo
(
--demo
模式減慢測試速度並突出顯示操作)
?這是 test_demo_site.py,它涵蓋了幾個操作:
pytest test_demo_site.py
易於鍵入、點選、選擇、切換、拖放等。
(有關更多範例,請參閱 SeleniumBase/examples/ 資料夾。)
探索自述文件:
- 開始/安裝
- 基本範例/用法
- 常用測試方法
- 有趣的事實/了解更多
- 演示模式/調試
- 命令列選項
- 目錄配置
- SeleniumBase 儀表板
- 產生測試報告
SeleniumBase 是一個用於瀏覽器自動化和測試的 Python 框架。 SeleniumBase 使用 Selenium/WebDriver API 並behave
測試執行程式(例如pytest
、 pynose
),並提供有組織的結構、測試發現、測試執行、測試狀態(例如通過、失敗或跳過)以及用於更改的命令列選項預設設定(例如瀏覽器選擇)。使用原始 Selenium,您需要設定自己的選項解析器來從命令列配置測試。
SeleniumBase 的驅動程式管理員可讓您更好地控制自動驅動程式下載。 (在pytest
運行命令中使用--driver-version=VER
來指定版本。)預設情況下,如果未設置,SeleniumBase 將下載與您的主要瀏覽器版本匹配的驅動程式版本。
SeleniumBase 會自動偵測 CSS 選擇器和 XPath,這表示您不需要在命令中指定選擇器的類型(但您可以選擇指定)。
SeleniumBase 方法通常在單一方法呼叫中執行多個操作。例如, self.type(selector, text)
執行以下操作:
1. 等待元素可見。
2. 等待元素進行互動。
3. 清除文字字段。
4. 輸入新文字。
5. 如果文字以"n"
結尾,請按 Enter/Submit。
對於原始 Selenium,這些操作需要多個方法呼叫。
未設定時,SeleniumBase 使用預設逾時值:
✅ self.click("button")
使用原始 Selenium,如果元素需要更多時間加載,方法將立即失敗(預設):
self.driver.find_element(by="css selector", value="button").click()
(可靠的程式碼比不可靠的程式碼好。)
SeleniumBase 可讓您變更方法的明確逾時值:
✅ self.click("button", timeout=10)
使用原始 Selenium,需要更多程式碼:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable("css selector", "button")).click()
(簡單的程式碼比複雜的程式碼更好。)
當測試失敗時,SeleniumBase 會為您提供乾淨的錯誤輸出。使用原始 Selenium,錯誤訊息可能會變得非常混亂。
SeleniumBase 為您提供了產生儀表板和測試報告的選項。它還將失敗測試的螢幕截圖保存到./latest_logs/
資料夾。 Raw Selenium 沒有這些開箱即用的選項。
SeleniumBase 包括用於運行測試的桌面 GUI 應用程序,例如用於pytest
的 SeleniumBase Commander 和用於behave
的 SeleniumBase Behave GUI。
SeleniumBase 有自己的記錄器/測試產生器,用於從手動瀏覽器操作建立測試。
SeleniumBase 隨附測試案例管理軟體(「CasePlans」),用於組織測試和步驟描述。
SeleniumBase 包含用於建立資料應用程式的工具(「ChartMaker」),它可以從 Python 產生 JavaScript。
了解編寫測試的不同方法:
這是 test_simple_login.py,它使用BaseCase
類別繼承,並與 pytest 或 pynose 一起運行。 (使用self.driver
存取 Selenium 的原始driver
。)
from seleniumbase import BaseCase
BaseCase . main ( __name__ , __file__ )
class TestSimpleLogin ( BaseCase ):
def test_simple_login ( self ):
self . open ( "seleniumbase.io/simple/login" )
self . type ( "#username" , "demo_user" )
self . type ( "#password" , "secret_pass" )
self . click ( 'a:contains("Sign in")' )
self . assert_exact_text ( "Welcome!" , "h1" )
self . assert_element ( "img#image1" )
self . highlight ( "#image1" )
self . click_link ( "Sign out" )
self . assert_text ( "signed out" , "#top_message" )
?這是來自 sb_fixture_tests.py 的測試,它使用sb
pytest
夾具。使用 pytest 運行。 (使用sb.driver
存取 Selenium 的原始driver
。)
def test_sb_fixture_with_no_class ( sb ):
sb . open ( "seleniumbase.io/simple/login" )
sb . type ( "#username" , "demo_user" )
sb . type ( "#password" , "secret_pass" )
sb . click ( 'a:contains("Sign in")' )
sb . assert_exact_text ( "Welcome!" , "h1" )
sb . assert_element ( "img#image1" )
sb . highlight ( "#image1" )
sb . click_link ( "Sign out" )
sb . assert_text ( "signed out" , "#top_message" )
?這是 raw_login_sb.py,它使用SB
上下文管理器。使用純python
運行。 (使用sb.driver
存取 Selenium 的原始driver
。)
from seleniumbase import SB
with SB () as sb :
sb . open ( "seleniumbase.io/simple/login" )
sb . type ( "#username" , "demo_user" )
sb . type ( "#password" , "secret_pass" )
sb . click ( 'a:contains("Sign in")' )
sb . assert_exact_text ( "Welcome!" , "h1" )
sb . assert_element ( "img#image1" )
sb . highlight ( "#image1" )
sb . click_link ( "Sign out" )
sb . assert_text ( "signed out" , "#top_message" )
?這是 raw_login_context.py,它使用DriverContext
Manager。使用純python
運行。 (該driver
是Selenium原始driver
的改進版本,具有更多方法。)
from seleniumbase import DriverContext
with DriverContext () as driver :
driver . open ( "seleniumbase.io/simple/login" )
driver . type ( "#username" , "demo_user" )
driver . type ( "#password" , "secret_pass" )
driver . click ( 'a:contains("Sign in")' )
driver . assert_exact_text ( "Welcome!" , "h1" )
driver . assert_element ( "img#image1" )
driver . highlight ( "#image1" )
driver . click_link ( "Sign out" )
driver . assert_text ( "signed out" , "#top_message" )
?這是 raw_login_driver.py,它使用Driver
管理員。使用純python
運行。 (該driver
是Selenium原始driver
的改進版本,具有更多方法。)
from seleniumbase import Driver
driver = Driver ()
try :
driver . open ( "seleniumbase.io/simple/login" )
driver . type ( "#username" , "demo_user" )
driver . type ( "#password" , "secret_pass" )
driver . click ( 'a:contains("Sign in")' )
driver . assert_exact_text ( "Welcome!" , "h1" )
driver . assert_element ( "img#image1" )
driver . highlight ( "#image1" )
driver . click_link ( "Sign out" )
driver . assert_text ( "signed out" , "#top_message" )
finally :
driver . quit ()
這是login_app.feature,它使用behavior-BDD Gherkin 語法。以behave
運行。 (了解SeleniumBase 行為 BDD整合)
Feature : SeleniumBase scenarios for the Simple App
Scenario : Verify the Simple App (Login / Logout)
Given Open "seleniumbase.io/simple/login"
And Type "demo_user" into "#username"
And Type "secret_pass" into "#password"
And Click 'a:contains("Sign in")'
And Assert exact text "Welcome!" in "h1"
And Assert element "img#image1"
And Highlight "#image1"
And Click link "Sign out"
And Assert text "signed out" in "#top_message"
?將Python和Git加入您的系統路徑。
?建議使用 Python 虛擬環境。
您可以從 PyPI 或 GitHub 安裝seleniumbase
:
?如何從 PyPI 安裝seleniumbase
:
pip install seleniumbase
--upgrade
或-U
來升級 SeleniumBase。)--force-reinstall
以升級間接套件。)pip3
。) ?如何從 GitHub 複製安裝seleniumbase
:
git clone https://github.com/seleniumbase/SeleniumBase.git
cd SeleniumBase/
pip install -e .
?如何從 GitHub 複製升級現有安裝:
git pull
pip install -e .
?鍵入seleniumbase
或sbase
以驗證 SeleniumBase 是否已成功安裝:
___ _ _ ___
/ __ | ___ | | ___ _ _ (_)_ _ _ __ | _ ) __ _ ______
_ _ / -_) / -_) ' | | | | ' | _ / _ ` (_- < -_)
| ___/ _ __ | _ _ __ | _ || _ | _ | _ ,_ | _ | _ | _ | ___/ _ _,_/__ | ___ |
----------------------------------------------------
╭──────────────────────────────────────────────────╮
│ * USAGE: " seleniumbase [COMMAND] [PARAMETERS] " │
│ * OR: " sbase [COMMAND] [PARAMETERS] " │
│ │
│ COMMANDS: PARAMETERS / DESCRIPTIONS: │
│ get / install [DRIVER_NAME] [OPTIONS] │
│ methods (List common Python methods) │
│ options (List common pytest options) │
│ behave-options (List common behave options) │
│ gui / commander [OPTIONAL PATH or TEST FILE] │
│ behave-gui (SBase Commander for Behave) │
│ caseplans [OPTIONAL PATH or TEST FILE] │
│ mkdir [DIRECTORY] [OPTIONS] │
│ mkfile [FILE.py] [OPTIONS] │
│ mkrec / codegen [FILE.py] [OPTIONS] │
│ recorder (Open Recorder Desktop App.) │
│ record (If args: mkrec. Else: App.) │
│ mkpres [FILE.py] [LANG] │
│ mkchart [FILE.py] [LANG] │
│ print [FILE] [OPTIONS] │
│ translate [SB_FILE.py] [LANG] [ACTION] │
│ convert [WEBDRIVER_UNITTEST_FILE.py] │
│ extract-objects [SB_FILE.py] │
│ inject-objects [SB_FILE.py] [OPTIONS] │
│ objectify [SB_FILE.py] [OPTIONS] │
│ revert-objects [SB_FILE.py] [OPTIONS] │
│ encrypt / obfuscate │
│ decrypt / unobfuscate │
│ proxy (Start a basic proxy server) │
│ download server (Get Selenium Grid JAR file) │
│ grid-hub [start | stop] [OPTIONS] │
│ grid-node [start | stop] --hub=[HOST/IP] │
│ │
│ * EXAMPLE = > " sbase get chromedriver stable " │
│ * For command info = > " sbase help [COMMAND] " │
│ * For info on all commands = > " sbase --help " │
╰──────────────────────────────────────────────────╯
✅ SeleniumBase 根據需要自動下載 webdriver,例如chromedriver
。
*** chromedriver to download = 121.0.6167.85 (Latest Stable)
Downloading chromedriver-mac-arm64.zip from:
https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.85/mac-arm64/chromedriver-mac-arm64.zip ...
Download Complete !
Extracting [ ' chromedriver ' ] from chromedriver-mac-arm64.zip ...
Unzip Complete !
The file [chromedriver] was saved to:
/Users/michael/github/SeleniumBase/seleniumbase/drivers/chromedriver
Making [chromedriver 121.0.6167.85] executable ...
[chromedriver 121.0.6167.85] is now ready for use !
?如果您已複製 SeleniumBase,則可以從 Examples/ 資料夾執行測試。
這是 my_first_test.py:
cd examples/
pytest my_first_test.py
這是 my_first_test.py 的程式碼:
from seleniumbase import BaseCase
BaseCase . main ( __name__ , __file__ )
class MyTestClass ( BaseCase ):
def test_swag_labs ( self ):
self . open ( "https://www.saucedemo.com" )
self . type ( "#user-name" , "standard_user" )
self . type ( "#password" , "secret_sauce n " )
self . assert_element ( "div.inventory_list" )
self . assert_exact_text ( "Products" , "span.title" )
self . click ( 'button[name*="backpack"]' )
self . click ( "#shopping_cart_container a" )
self . assert_exact_text ( "Your Cart" , "span.title" )
self . assert_text ( "Backpack" , "div.cart_item" )
self . click ( "button#checkout" )
self . type ( "#first-name" , "SeleniumBase" )
self . type ( "#last-name" , "Automation" )
self . type ( "#postal-code" , "77123" )
self . click ( "input#continue" )
self . assert_text ( "Checkout: Overview" )
self . assert_text ( "Backpack" , "div.cart_item" )
self . assert_text ( "29.99" , "div.inventory_item_price" )
self . click ( "button#finish" )
self . assert_exact_text ( "Thank you for your order!" , "h2" )
self . assert_element ( 'img[alt="Pony Express"]' )
self . js_click ( "a#logout_sidebar_link" )
self . assert_element ( "div#login_button_container" )
self . open ( url ) # Navigate the browser window to the URL.
self . type ( selector , text ) # Update the field with the text.
self . click ( selector ) # Click the element with the selector.
self . click_link ( link_text ) # Click the link containing text.
self . go_back () # Navigate back to the previous URL.
self . select_option_by_text ( dropdown_selector , option )
self . hover_and_click ( hover_selector , click_selector )
self . drag_and_drop ( drag_selector , drop_selector )
self . get_text ( selector ) # Get the text from the element.
self . get_current_url () # Get the URL of the current page.
self . get_page_source () # Get the HTML of the current page.
self . get_attribute ( selector , attribute ) # Get element attribute.
self . get_title () # Get the title of the current page.
self . switch_to_frame ( frame ) # Switch into the iframe container.
self . switch_to_default_content () # Leave the iframe container.
self . open_new_window () # Open a new window in the same browser.
self . switch_to_window ( window ) # Switch to the browser window.
self . switch_to_default_window () # Switch to the original window.
self . get_new_driver ( OPTIONS ) # Open a new driver with OPTIONS.
self . switch_to_driver ( driver ) # Switch to the browser driver.
self . switch_to_default_driver () # Switch to the original driver.
self . wait_for_element ( selector ) # Wait until element is visible.
self . is_element_visible ( selector ) # Return element visibility.
self . is_text_visible ( text , selector ) # Return text visibility.
self . sleep ( seconds ) # Do nothing for the given amount of time.
self . save_screenshot ( name ) # Save a screenshot in .png format.
self . assert_element ( selector ) # Verify the element is visible.
self . assert_text ( text , selector ) # Verify text in the element.
self . assert_exact_text ( text , selector ) # Verify text is exact.
self . assert_title ( title ) # Verify the title of the web page.
self . assert_downloaded_file ( file ) # Verify file was downloaded.
self . assert_no_404_errors () # Verify there are no broken links.
self . assert_no_js_errors () # Verify there are no JS errors.
?有關 SeleniumBase 方法的完整列表,請參閱:方法摘要
✅ SeleniumBase 會自動處理常見的 WebDriver 操作,例如在測試前啟動 Web 瀏覽器、在失敗期間儲存螢幕截圖以及在測試後關閉 Web 瀏覽器。
✅ SeleniumBase 允許您透過命令列選項自訂測試。
✅ SeleniumBase 使用簡單的指令語法。例子:
self . type ( "input" , "dogs n " ) # (The "n" presses ENTER)
大多數 SeleniumBase 腳本可以使用pytest
、 pynose
或純python
運行。並非所有測試運行程序都可以運行所有測試格式。例如,使用sb
pytest 夾具的測試只能使用pytest
來運作。 (請參閱語法格式)還有一種與 Beecut 一起運行的 Gherkin 測試格式。
pytest coffee_cart_tests.py --rs
pytest test_sb_fixture.py --demo
pytest test_suite.py --rs --html=report.html --dashboard
pynose basic_test.py --mobile
pynose test_suite.py --headless --report --show-report
python raw_sb.py
python raw_test_scripts.py
behave realworld.feature
behave calculator.feature -D rs -D dashboard
✅ pytest
包含自動測試發現。如果您沒有指定要執行的特定檔案或資料夾, pytest
將根據以下條件自動搜尋所有子目錄以執行測試:
test_
開頭或以_test.py
結尾的 Python 檔案。test_
開頭的 Python 方法。有了 SeleniumBase pytest.ini 文件,您就可以修改預設發現設定。 Python類別名稱可以是任何名稱,因為seleniumbase.BaseCase
繼承unittest.TestCase
來觸發自動發現。
✅ 您可以進行飛行前檢查,以查看pytest
在實際運行之前會發現哪些測試:
pytest --co -q
✅ 在檔案上呼叫pytest
或pynose
時,您可以更具體:
pytest [FILE_NAME.py]::[CLASS_NAME]::[METHOD_NAME]
pynose [FILE_NAME.py]:[CLASS_NAME].[METHOD_NAME]
✅ 不再有不穩定的測試! SeleniumBase 方法在與頁面元素互動之前自動等待頁面元素完成載入(最多逾時限制)。這意味著您的腳本中不再需要隨機的time.sleep()
語句。
✅ SeleniumBase 支援所有主流瀏覽器和作業系統:
瀏覽器: Chrome、Edge、Firefox 和 Safari。
系統: Linux/Ubuntu、macOS 和 Windows。
✅ SeleniumBase 適用於所有流行的 CI/CD 平台:
✅ SeleniumBase 包含一個名為MasterQA的自動/手動混合解決方案,可在手動測試人員處理驗證的同時透過自動化加速手動測試。
✅ SeleniumBase 支援離線執行測試(假設先前在線上時下載了 webdrivers )。
✅ 有關 SeleniumBase 功能的完整列表,請按此處。
?演示模式可幫助您了解測驗正在做什麼。如果測試對於您的眼睛來說太快,請在演示模式下運行它,以在操作之間短暫暫停瀏覽器,突出顯示正在操作的頁面元素,並顯示斷言:
pytest my_first_test.py --demo
? time.sleep(seconds)
可用於在特定位置進行測試等待:
import time ; time . sleep ( 3 ) # Do nothing for 3 seconds.
?使用 Python 內建pdb庫的調試模式可協助您調試測試:
import pdb ; pdb . set_trace ()
import pytest ; pytest . set_trace ()
breakpoint () # Shortcut for "import pdb; pdb.set_trace()"
(
pdb
指令:n
、c
、s
、u
、d
=>next
、continue
、step
、up
、down
)
?若要暫停引發異常或錯誤的活動測試(並在控制台中開始偵錯模式時保持瀏覽器視窗開啟),請新增--pdb
作為pytest
選項:
pytest test_fail.py --pdb
?若要在偵錯模式下啟動測試,請新增--trace
作為pytest
選項:
pytest test_coffee_cart.py --trace
✅ 以下是pytest
附帶的一些有用的命令列選項:
-v # Verbose mode. Prints the full name of each test and shows more details.
-q # Quiet mode. Print fewer details in the console output when running tests.
-x # Stop running the tests after the first failure is reached.
--html=report.html # Creates a detailed pytest-html report after tests finish.
--co | --collect-only # Show what tests would get run. (Without running them)
--co -q # (Both options together!) - Do a dry run with full test names shown.
-n=NUM # Multithread the tests using that many threads. (Speed up test runs!)
-s # See print statements. (Should be on by default with pytest.ini present.)
--junit-xml=report.xml # Creates a junit-xml report after tests finish.
--pdb # If a test fails, enter Post Mortem Debug Mode. (Don't use with CI!)
--trace # Enter Debug Mode at the beginning of each test. (Don't use with CI!)
-m=MARKER # Run tests with the specified pytest marker.
✅ SeleniumBase 為測試提供了額外的pytest
命令列選項:
--browser=BROWSER # (The web browser to use. Default: "chrome".)
--chrome # (Shortcut for "--browser=chrome". On by default.)
--edge # (Shortcut for "--browser=edge".)
--firefox # (Shortcut for "--browser=firefox".)
--safari # (Shortcut for "--browser=safari".)
--settings-file=FILE # (Override default SeleniumBase settings.)
--env=ENV # (Set the test env. Access with "self.env" in tests.)
--account=STR # (Set account. Access with "self.account" in tests.)
--data=STRING # (Extra test data. Access with "self.data" in tests.)
--var1=STRING # (Extra test data. Access with "self.var1" in tests.)
--var2=STRING # (Extra test data. Access with "self.var2" in tests.)
--var3=STRING # (Extra test data. Access with "self.var3" in tests.)
--variables=DICT # (Extra test data. Access with "self.variables".)
--user-data-dir=DIR # (Set the Chrome user data directory to use.)
--protocol=PROTOCOL # (The Selenium Grid protocol: http|https.)
--server=SERVER # (The Selenium Grid server/IP used for tests.)
--port=PORT # (The Selenium Grid port used by the test server.)
--cap-file=FILE # (The web browser's desired capabilities to use.)
--cap-string=STRING # (The web browser's desired capabilities to use.)
--proxy=SERVER:PORT # (Connect to a proxy server:port as tests are running)
--proxy=USERNAME:PASSWORD@SERVER:PORT # (Use an authenticated proxy server)
--proxy-bypass-list=STRING # (";"-separated hosts to bypass, Eg "*.foo.com")
--proxy-pac-url=URL # (Connect to a proxy server using a PAC_URL.pac file.)
--proxy-pac-url=USERNAME:PASSWORD@URL # (Authenticated proxy with PAC URL.)
--proxy-driver # (If a driver download is needed, will use: --proxy=PROXY.)
--multi-proxy # (Allow multiple authenticated proxies when multi-threaded.)
--agent=STRING # (Modify the web browser's User-Agent string.)
--mobile # (Use the mobile device emulator while running tests.)
--metrics=STRING # (Set mobile metrics: "CSSWidth,CSSHeight,PixelRatio".)
--chromium-arg= " ARG=N,ARG2 " # (Set Chromium args, ","-separated, no spaces.)
--firefox-arg= " ARG=N,ARG2 " # (Set Firefox args, comma-separated, no spaces.)
--firefox-pref=SET # (Set a Firefox preference:value set, comma-separated.)
--extension-zip=ZIP # (Load a Chrome Extension .zip|.crx, comma-separated.)
--extension-dir=DIR # (Load a Chrome Extension directory, comma-separated.)
--disable-features= " F1,F2 " # (Disable features, comma-separated, no spaces.)
--binary-location=PATH # (Set path of the Chromium browser binary to use.)
--driver-version=VER # (Set the chromedriver or uc_driver version to use.)
--sjw # (Skip JS Waits for readyState to be "complete" or Angular to load.)
--wfa # (Wait for AngularJS to be done loading after specific web actions.)
--pls=PLS # (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".)
--headless # (The default headless mode. Linux uses this mode by default.)
--headless1 # (Use Chrome's old headless mode. Fast, but has limitations.)
--headless2 # (Use Chrome's new headless mode, which supports extensions.)
--headed # (Run tests in headed/GUI mode on Linux OS, where not default.)
--xvfb # (Run tests using the Xvfb virtual display server on Linux OS.)
--xvfb-metrics=STRING # (Set Xvfb display size on Linux: "Width,Height".)
--locale=LOCALE_CODE # (Set the Language Locale Code for the web browser.)
--interval=SECONDS # (The autoplay interval for presentations & tour steps)
--start-page=URL # (The starting URL for the web browser when tests begin.)
--archive-logs # (Archive existing log files instead of deleting them.)
--archive-downloads # (Archive old downloads instead of deleting them.)
--time-limit=SECONDS # (Safely fail any test that exceeds the time limit.)
--slow # (Slow down the automation. Faster than using Demo Mode.)
--demo # (Slow down and visually see test actions as they occur.)
--demo-sleep=SECONDS # (Set the wait time after Slow & Demo Mode actions.)
--highlights=NUM # (Number of highlight animations for Demo Mode actions.)
--message-duration=SECONDS # (The time length for Messenger alerts.)
--check-js # (Check for JavaScript errors after page loads.)
--ad-block # (Block some types of display ads from loading.)
--host-resolver-rules=RULES # (Set host-resolver-rules, comma-separated.)
--block-images # (Block images from loading during tests.)
--do-not-track # (Indicate to websites that you don't want to be tracked.)
--verify-delay=SECONDS # (The delay before MasterQA verification checks.)
--ee | --esc-end # (Lets the user end the current test via the ESC key.)
--recorder # (Enables the Recorder for turning browser actions into code.)
--rec-behave # (Same as Recorder Mode, but also generates behave-gherkin.)
--rec-sleep # (If the Recorder is enabled, also records self.sleep calls.)
--rec-print # (If the Recorder is enabled, prints output after tests end.)
--disable-cookies # (Disable Cookies on websites. Pages might break!)
--disable-js # (Disable JavaScript on websites. Pages might break!)
--disable-csp # (Disable the Content Security Policy of websites.)
--disable-ws # (Disable Web Security on Chromium-based browsers.)
--enable-ws # (Enable Web Security on Chromium-based browsers.)
--enable-sync # (Enable "Chrome Sync" on websites.)
--uc | --undetected # (Use undetected-chromedriver to evade bot-detection.)
--uc-cdp-events # (Capture CDP events when running in "--undetected" mode.)
--log-cdp # ("goog:loggingPrefs", {"performance": "ALL", "browser": "ALL"})
--remote-debug # (Sync to Chrome Remote Debugger chrome://inspect/#devices)
--ftrace | --final-trace # (Debug Mode after each test. Don't use with CI!)
--dashboard # (Enable the SeleniumBase Dashboard. Saved at: dashboard.html)
--dash-title=STRING # (Set the title shown for the generated dashboard.)
--enable-3d-apis # (Enables WebGL and 3D APIs.)
--swiftshader # (Chrome "--use-gl=angle" / "--use-angle=swiftshader-webgl")
--incognito # (Enable Chrome's Incognito mode.)
--guest # (Enable Chrome's Guest mode.)
--dark # (Enable Chrome's Dark mode.)
--devtools # (Open Chrome's DevTools when the browser opens.)
--rs | --reuse-session # (Reuse browser session for all tests.)
--rcs | --reuse-class-session # (Reuse session for tests in class.)
--crumbs # (Delete all cookies between tests reusing a session.)
--disable-beforeunload # (Disable the "beforeunload" event on Chrome.)
--window-position=X,Y # (Set the browser's starting window position.)
--window-size=WIDTH,HEIGHT # (Set the browser's starting window size.)
--maximize # (Start tests with the browser window maximized.)
--screenshot # (Save a screenshot at the end of each test.)
--no-screenshot # (No screenshots saved unless tests directly ask it.)
--visual-baseline # (Set the visual baseline for Visual/Layout tests.)
--wire # (Use selenium-wire's webdriver for replacing selenium webdriver.)
--external-pdf # (Set Chromium "plugins.always_open_pdf_externally":True.)
--timeout-multiplier=MULTIPLIER # (Multiplies the default timeout values.)
--list-fail-page # (After each failing test, list the URL of the failure.)
(請參閱此處的命令列選項定義的完整清單。有關命令列選項的詳細範例,請參閱customizing_test_runs.md )
?在測試失敗期間,最近測試運行的日誌和螢幕截圖將保存到latest_logs/
資料夾中。如果您將 --archive_logs 新增至命令列選項,或在 settings.py 中將ARCHIVE_EXISTING_LOGS
設為 True,這些日誌將被移至archived_logs/
,否則日誌檔案將在下一次測試執行開始時被清理。 test_suite.py
集合包含故意失敗的測試,以便您可以了解日誌記錄的工作原理。
cd examples/
pytest test_suite.py --chrome
pytest test_suite.py --firefox
覆蓋 seleniumbase/config/settings.py 的簡單方法是使用自訂設定檔。以下是新增至測試的命令列選項:(請參閱範例/custom_settings.py) --settings_file=custom_settings.py
(設定包括預設逾時值、雙重認證金鑰、資料庫憑證、S3 憑證和其他重要設定由測試使用。
?若要將附加資料從命令列傳遞到測試,請新增--data="ANY STRING"
。在測試中,您可以使用self.data
來存取它。
?使用pytest
執行測試時,您需要在根資料夾中儲存pytest.ini的副本。使用pynose
執行測試時,您需要在根資料夾中儲存setup.cfg的副本。這些文件指定測試的預設配置詳細資訊。測試資料夾還應包含一個空白的init .py文件,以允許您的測試文件從該資料夾匯入其他文件。
? sbase mkdir DIR
建立一個包含設定檔和範例測試的資料夾:
sbase mkdir ui_tests
該新資料夾將包含以下文件:
ui_tests/
├── __init__.py
├── my_first_test.py
├── parameterized_test.py
├── pytest.ini
├── requirements.txt
├── setup.cfg
├── test_demo_site.py
└── boilerplates/
├── __init__.py
├── base_test_case.py
├── boilerplate_test.py
├── classic_obj_test.py
├── page_objects.py
├── sb_fixture_test.py
└── samples/
├── __init__.py
├── google_objects.py
├── google_test.py
├── sb_swag_test.py
└── swag_labs_test.py
ProTip™:您也可以透過將-b
或--basic
新增至sbase mkdir
命令來建立一個不包含任何範例測試的樣板資料夾:
sbase mkdir ui_tests --basic
該新資料夾將包含以下文件:
ui_tests/
├── __init__.py
├── pytest.ini
├── requirements.txt
└── setup.cfg
在這些檔案中, pytest.ini
設定檔是最重要的,其次是空白的__init__.py
檔。還有一個setup.cfg
檔案(用於 pynose)。最後, requirements.txt
檔案可用於協助您將 seleniumbase 安裝到您的環境中(如果尚未安裝)。
讓我們嘗試一個失敗的測試範例:
""" test_fail.py """
from seleniumbase import BaseCase
BaseCase . main ( __name__ , __file__ )
class MyTestClass ( BaseCase ):
def test_find_army_of_robots_on_xkcd_desert_island ( self ):
self . open ( "https://xkcd.com/731/" )
self . assert_element ( "div#ARMY_OF_ROBOTS" , timeout = 1 ) # This should fail
您可以從examples/
資料夾運行它,如下所示:
pytest test_fail.py
?您會注意到建立了一個日誌資料夾「latest_logs」來保存有關失敗測試和螢幕截圖的資訊。在測試運行期間,如果您在 settings.py 中將 ARCHIVE_EXISTING_LOGS 設為 True,或者如果您使用--archive-logs
執行測試,則過去的結果將移至 archived_logs 資料夾。如果您選擇不歸檔現有日誌,它們將被刪除並替換為最新測試運行的日誌。
? pytest 的--dashboard
選項會產生一個位於dashboard.html
的 SeleniumBase 儀表板,該儀表板會在測試運行並產生結果時自動更新。例子:
pytest --dashboard --rs --headless
?此外,您可以在您選擇的連接埠上託管自己的 SeleniumBase 儀表板伺服器。以下是使用 Python 的http.server
的範例:
python -m http.server 1948
?現在您可以導航至http://localhost:1948/dashboard.html
以將儀表板作為 Web 應用程式檢視。這需要兩個不同的終端視窗:一個用於運行伺服器,另一個用於運行測試,它們應該從同一目錄運行。 (使用Ctrl+C停止 http 伺服器。)
?以下是 SeleniumBase 儀表板的完整範例:
pytest test_suite.py test_image_saving.py --dashboard --rs --headless
pytest
HTML 報表: ✅ 使用--html=report.html
為您提供測試套件完成後指定名稱的精美報告。
pytest test_suite.py --html=report.html
✅ 將 pytest html 報表與 SeleniumBase 儀表板使用情況結合時,儀表板中的圓餅圖將會加入 html 報表中。此外,如果您在使用儀表板時將 html 報告 URL 設定為與儀表板 URL 相同(例如: --dashboard --html=dashboard.html
),那麼當所有測試完成時。
✅ 這是升級後的 html 報告的範例:
pytest test_suite.py --dashboard --html=report.html
如果在 Jenkins 中查看 pytest html 報告,您可能需要設定 Jenkins 設定以使 html 正確呈現。這是由於 Jenkins CSP 變更所致。
您也可以使用--junit-xml=report.xml
來取得 xml 報告。 Jenkins 可以使用此文件來顯示更好的測試報告。
pytest test_suite.py --junit-xml=report.xml
pynose
報告: --report
選項在測試套件完成後為您提供一份精美的報告。
pynose test_suite.py --report
(注意:您可以新增--show-report
以在測試套件完成後立即顯示 pynose 報告。僅在本地運行測試時使用--show-report
因為它會暫停測試運行。)
behave
儀表板和報告:(behave_bdd/資料夾可以在examples/資料夾中找到。)
behave behave_bdd/features/ -D dashboard -D headless
您也可以使用--junit
來取得每個behave
功能的.xml
報告。 Jenkins 可以使用這些檔案來顯示更好的測試報告。
behave behave_bdd/features/ --junit -D rs -D headless
請參閱:https://allurereport.org/docs/pytest/
SeleniumBase 不再包含allure-pytest
作為已安裝依賴項的一部分。如果你想使用它,請先安裝它:
pip install allure-pytest
現在您的測試可以建立 Allure 結果文件,該文件可以由 Allure 報告進行處理。
pytest test_suite.py --alluredir=allure_results
如果您希望使用代理伺服器進行瀏覽器測試(Chromium 或 Firefox),您可以在命令列上新增--proxy=IP_ADDRESS:PORT
作為參數。
pytest proxy_test.py --proxy=IP_ADDRESS:PORT
如果您希望使用的代理伺服器需要身份驗證,您可以執行以下操作(僅限 Chromium):
pytest proxy_test.py --proxy=USERNAME:PASSWORD@IP_ADDRESS:PORT
SeleniumBase 也支援 SOCKS4 和 SOCKS5 代理:
pytest proxy_test.py --proxy= " socks4://IP_ADDRESS:PORT "
pytest proxy_test.py --proxy= " socks5://IP_ADDRESS:PORT "
為了讓事情變得更簡單,您可以將常用代理程式新增至 proxy_list.py 中的 PROXY_LIST 中,然後使用--proxy=KEY_FROM_PROXY_LIST
來使用該金鑰的 IP_ADDRESS:PORT。
pytest proxy_test.py --proxy=proxy1
?如果您希望變更瀏覽器測試的使用者代理程式(僅限 Chromium 和 Firefox),您可以新增--agent="USER AGENT STRING"
作為命令列上的參數。
pytest user_agent_test.py --agent= " Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7412.EU "
? self.accept_alert()
自動等待並接受警報彈出視窗。 self.dismiss_alert()
自動等待並消除警報彈出視窗。有時,某些方法(例如self.click(SELECTOR)
可能會自行關閉彈出窗口,因為它們會呼叫 JavaScript 以確保頁面的readyState
在前進之前已complete
。如果您嘗試接受以這種方式關閉的彈出窗口,請使用以下解決方法:改為呼叫self.find_element(SELECTOR).click()
(這將使彈出視窗保留在螢幕上),然後使用self.accept_alert()
接受彈出視窗(更多資訊請參閱此處)。如果彈出視窗是間歇性的,請將程式碼包裝在 try/ except 區塊中。
?了解 SeleniumBase 互動式演練(在examples/tour_examples/
資料夾中)。它非常適合製作網站入門體驗原型。
--with-s3-logging
。以下是在啟用一些附加功能的情況下執行測試的範例:
pytest [YOUR_TEST_FILE.py] --with-db-reporting --with-s3-logging
?導航至網頁:(以及相關指令)
self . open ( "https://xkcd.com/378/" ) # This method opens the specified page.
self . go_back () # This method navigates the browser to the previous page.
self . go_forward () # This method navigates the browser forward in history.
self . refresh_page () # This method reloads the current page.
self . get_current_url () # This method returns the current page URL.
self . get_page_source () # This method returns the current page source.
ProTip™:您可以將self.get_page_source()
方法與 Python 的find()
命令結合使用來解析 HTML 以尋找特定內容。 (有關更高級的解析,請參閱 BeautifulSoup 範例。)
source = self . get_page_source ()
head_open_tag = source . find ( '<head>' )
head_close_tag = source . find ( '</head>' , head_open_tag )
everything_inside_head = source [ head_open_tag + len ( '<head>' ): head_close_tag ]
?點擊:
點擊頁面上的元素:
self . click ( "div#my_id" )
ProTip™:在大多數 Web 瀏覽器中,您可以右鍵單擊頁面並選擇Inspect Element
以查看建立自己的腳本所需的 CSS 選擇器詳細資訊。
?鍵入文字:
self.type(selector, text)
# 使用指定值更新指定元素中的文字。如果元素遺失或文字欄位不可編輯,則會引發異常。例子:
self . type ( "input#id_value" , "2012" )
您也可以使用self.add_text()
或 WebDriver .send_keys()
命令,但如果內部已有文本,這些命令不會先清除文字方塊。
?從頁面上的元素取得文字:
text = self . get_text ( "header h2" )
?從頁面上的元素取得屬性值:
attribute = self . get_attribute ( "#comic img" , "title" )
?在幾秒鐘內斷言頁面上某個元素的存在:
self . wait_for_element_present ( "div.my_class" , timeout = 10 )
(注意:您也可以使用: self.assert_element_present(ELEMENT)
)
?在幾秒內斷言頁面上元素的可見性:
self . wait_for_element_visible ( "a.my_class" , timeout = 5 )
(注意:其簡短版本是self.find_element(ELEMENT)
和self.assert_element(ELEMENT)
find_element()
版本傳回元素。)
由於上面的行返回元素,因此您可以將其與.click()
結合使用,如下所示:
self . find_element ( "a.my_class" , timeout = 5 ). click ()
# But you're better off using the following statement, which does the same thing:
self . click ( "a.my_class" ) # DO IT THIS WAY!
ProTip™:您可以在 CSS 選擇器中使用點來表示類別名稱(例如: div.class_name
)作為div[class="class_name"]
的簡化版本。
您也可以使用*=
在 CSS 選擇器中搜尋任何部分值,如下所示:
self . click ( 'a[name*="partial_name"]' )
?在幾秒內斷言頁面元素內文本的可見性:
self . assert_text ( "Make it so!" , "div#trek div.picard div.quotes" )
self . assert_text ( "Tea. Earl Grey. Hot." , "div#trek div.picard div.quotes" , timeout = 3 )
(注意: self.find_text(TEXT, ELEMENT)
和self.wait_for_text(TEXT, ELEMENT)
也執行此操作。為了向後相容,保留了舊的方法名稱,但預設逾時可能不同。)
?斷言任何事情:
self . assert_true ( var1 == var2 )
self . assert_false ( var1 == var2 )
self . assert_equal ( var1 , var2 )
?有用的條件語句:(有創意範例)
❓ is_element_visible(selector):
頁面可見)
if self . is_element_visible ( 'div#warning' ):
print ( "Red Alert: Something bad might be happening!" )
❓ is_element_present(selector):
存在於 HTML 中)
if self . is_element_present ( 'div#top_secret img.tracking_cookie' ):
self . contact_cookie_monster () # Not a real SeleniumBase method
else :
current_url = self . get_current_url ()
self . contact_the_nsa ( url = current_url , message = "Dark Zone Found" ) # Not a real SeleniumBase method
def is_there_a_cloaked_klingon_ship_on_this_page ():
if self . is_element_present ( "div.ships div.klingon" ):
return not self . is_element_visible ( "div.ships div.klingon" )
return False
❓ is_text_visible(text, selector):
(元素上可見的文字)
if self . is_text_visible ( "You Shall Not Pass!" , "h1" ):
self . open ( "https://www.youtube.com/watch?v=3xYXUeSmb-Y" )
is_text_visible():
def get_mirror_universe_captain_picard_superbowl_ad ( superbowl_year ):
selector = "div.superbowl_%s div.commercials div.transcript div.picard" % superbowl_year
if self . is_text_visible ( "Yes, it was I who summoned you all here." , selector ):
return "Picard Paramount+ Superbowl Ad 2020"
elif self . is_text_visible ( "Commander, signal the following: Our Network is Secure!" ):
return "Picard Mirror Universe iboss Superbowl Ad 2018"
elif self . is_text_visible ( "For the Love of Marketing and Earl Grey Tea!" , selector ):
return "Picard Mirror Universe HubSpot Superbowl Ad 2015"
elif self . is_text_visible ( "Delivery Drones... Engage" , selector ):
return "Picard Mirror Universe Amazon Superbowl Ad 2015"
elif self . is_text_visible ( "Bing it on Screen!" , selector ):
return "Picard Mirror Universe Microsoft Superbowl Ad 2015"
elif self . is_text_visible ( "OK Glass, Make it So!" , selector ):
return "Picard Mirror Universe Google Superbowl Ad 2015"
elif self . is_text_visible ( "Number One, I've Never Seen Anything Like It." , selector ):
return "Picard Mirror Universe Tesla Superbowl Ad 2015"
elif self . is_text_visible ( "Let us make sure history never forgets the name ... Facebook" , selector ):
return "Picard Mirror Universe Facebook Superbowl Ad 2015"
elif self . is_text_visible ( """With the first link, the chain is forged.
The first speech censored, the first thought forbidden,
the first freedom denied, chains us all irrevocably.""" , selector ):
return "Picard Mirror Universe Wikimedia Superbowl Ad 2015"
else :
raise Exception ( "Reports of my assimilation are greatly exaggerated." )
❓ is_link_text_visible(link_text):
if self . is_link_text_visible ( "Stop! Hammer time!" ):
self . click_link ( "Stop! Hammer time!" )
如果您的測試打開一個新選項卡/窗口,您可以切換到它。 (SeleniumBase 會自動切換到不會開啟about:blank
URL 的新分頁。)
self . switch_to_window ( 1 ) # This switches to the new tab (0 is the first one)
? iframe遵循與新視窗相同的原則:如果要在 iframe 中執行操作,則必須先切換到 iframe:
self . switch_to_frame ( "iframe" )
# ... Now perform actions inside the iframe
self . switch_to_parent_frame () # Exit the current iframe
若要退出多個 iframe,請使用self.switch_to_default_content()
。 (如果在單一 iframe 內,這與self.switch_to_parent_frame()
具有相同的效果。)
self . switch_to_frame ( 'iframe[name="frame1"]' )
self . switch_to_frame ( 'iframe[name="frame2"]' )
# ... Now perform actions inside the inner iframe
self . switch_to_default_content () # Back to the main page
?您也可以使用上下文管理器在 iframe 內進行操作:
with self . frame_switch ( "iframe" ):
# ... Now perform actions while inside the code block
# You have left the iframe
這也適用於嵌套 iframe:
with self . frame_switch ( 'iframe[name="frame1"]' ):
with self . frame_switch ( 'iframe[name="frame2"]' ):
# ... Now perform actions while inside the code block
# You are now back inside the first iframe
# You have left all the iframes
jQuery 是一個功能強大的 JavaScript 函式庫,可讓您在 Web 瀏覽器中執行進階操作。如果您所在的網頁已經載入了 jQuery,您可以立即開始執行 jQuery 腳本。您將知道這一點,因為網頁將在 HTML 中包含類似以下內容的內容:
< script src =" https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js " > </ script >
?如果您想在尚未載入 jQuery 的頁面上使用 jQuery,這是可以的。為此,請先執行以下命令:
self . activate_jquery ()
self . execute_script ( "jQuery, window.scrollTo(0, 600)" ) # Scrolling the page
self . execute_script ( "jQuery('#annoying-widget').hide()" ) # Hiding elements on a page
self . execute_script ( "jQuery('#hidden-widget').show(0)" ) # Showing hidden elements on a page
self . execute_script ( "jQuery('#annoying-button a').remove()" ) # Removing elements on a page
self . execute_script ( "jQuery('%s').mouseover()" % ( mouse_over_item )) # Mouse-over elements on a page
self . execute_script ( "jQuery('input#the_id').val('my_text')" ) # Fast text input on a page
self . execute_script ( "jQuery('div#dropdown a.link').click()" ) # Click elements on a page
self . execute_script ( "return jQuery('div#amazing')[0].text" ) # Returns the css "text" of the element given
self . execute_script ( "return jQuery('textarea')[2].value" ) # Returns the css "value" of the 3rd textarea element on the page
(上面的大部分指令都可以直接使用內建的 SeleniumBase 方法來完成。)
❗ 有些網站具有限制性的內容安全策略,以防止使用者將 jQuery 和其他外部庫載入到其網站上。如果您需要在這些網站上使用 jQuery 或其他 JS 函式庫,請新增--disable-csp
作為pytest
命令列選項來載入繞過 CSP 的 Chromium 擴充功能。
start_page = "https://xkcd.com/465/"
destination_page = "https://github.com/seleniumbase/SeleniumBase"
self . open ( start_page )
referral_link = '''<a class='analytics test' href='%s'>Free-Referral Button!</a>''' % destination_page
self . execute_script ( '''document.body.innerHTML = " %s " ''' % referral_link )
self . click ( "a.analytics" ) # Clicks the generated button
(由於大眾的需求,這個流量產生範例已透過self.generate_referral(start_page, end_page)
和self.generate_traffic(start_page, end_page, loops)
方法包含在 SeleniumBase 中。)
假設您想在一次測試中驗證網頁上的多個不同元素,但您不希望測試失敗,直到您一次驗證了多個元素,這樣您就不必重新運行測試來發現更多缺失的元素同一頁面上的元素。這就是延遲斷言的用武之地。
from seleniumbase import BaseCase
BaseCase . main ( __name__ , __file__ )
class DeferredAssertTests ( BaseCase ):
def test_deferred_asserts ( self ):
self . open ( "https://xkcd.com/993/" )
self . wait_for_element ( "#comic" )
self . deferred_assert_element ( 'img[alt="Brand Identity"]' )
self . deferred_assert_element ( 'img[alt="Rocket Ship"]' ) # Will Fail
self . deferred_assert_element ( "#comicmap" )
self . deferred_assert_text ( "Fake Item" , "ul.comicNav" ) # Will Fail
self . deferred_assert_text ( "Random" , "ul.comicNav" )
self . deferred_assert_element ( 'a[name="Super Fake !!!"]' ) # Will Fail
self . deferred_assert_exact_text ( "Brand Identity" , "#ctitle" )
self . deferred_assert_exact_text ( "Fake Food" , "#comic" ) # Will Fail
self . process_deferred_asserts ()
deferred_assert_element()
和deferred_assert_text()
將保存將引發的任何異常。若要將所有失敗的延遲斷言清除為單一異常,請確保在測試方法末端呼叫self.process_deferred_asserts()
。如果您的測試命中多個頁面,您可以在導航到新頁面之前調用self.process_deferred_asserts()
以便日誌檔案中的螢幕截圖與進行延遲斷言的 URL 相符。
如果您需要存取標準 WebDriver 附帶的任何命令,您可以像這樣直接呼叫它們:
self . driver . delete_all_cookies ()
capabilities = self . driver . capabilities
self . driver . find_elements ( "partial link text" , "GitHub" )
(一般來說,您需要使用可用的 SeleniumBase 版本的方法。)
您可以使用pytest --reruns=NUM
多次重試失敗的測試。添加--reruns-delay=SECONDS
以在重試之間等待那麼多秒。例子:
pytest --reruns=1 --reruns-delay=1
您可以使用@retry_on_exception()
裝飾器重試失敗的方法。 (第一次導入: from seleniumbase import decorators
)。要了解有關 SeleniumBase 裝飾器的更多信息,請按此處。
“在將程式碼部署到生產環境之前捕獲 QA 中的錯誤!”