一体化浏览器自动化框架:
网络爬行/测试/抓取/隐形
开始| ?特点| ?️ 选项 |示例 | ?脚本 |移动的
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 中的错误!”