✅ 可靠的测试自动化

SeleniumBase

测试框架 SeleniumBase on GitHub

中文文件 <=> English Docs

Latest Release on GitHub Latest Release on PyPI SeleniumBase.io Docs SeleniumBase.io Docs SeleniumBase GitHub Actions SeleniumBase

UI自动化测试需要的一切这里都有.

🚀 立即开始 | 🧙‍♂️ 命令行选项 | 🏰 功能列表 | 👨‍🏫 学习示例 | 📱 移动测试 | 📊 测试报告
📖 API语法 | 🗺️ 创建旅游 | 🌎 语言翻译 | 🛂 MasterQA | 🤖 持续集成

Selenium 和 pytest 组合使用.

SeleniumBase

立即开始:

* 需要 **[Python](https://www.python.org/downloads/)** 和 **[Git](https://git-scm.com/)** * [Python:2.7|3.5|3.6|3.7|3.8](https://www.python.org/downloads/) * 建议配合 [Python virtual env](https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/) . See shortcut. * 更新 **[pip](https://pypi.org/project/pip/)** 以防出现警告: ```bash python -m pip install -U pip ```

安装 SeleniumBase:

```bash git clone https://github.com/seleniumbase/SeleniumBase.git cd SeleniumBase/ pip install -r requirements.txt python setup.py install ``` 如果存在多个安装的python版本, 需要显示具体版本 (E.g. 使用 ``python3`` 代替 ``python``). * 你也可以通过[pypi](https://pypi.python.org/pypi/seleniumbase)安装 ``seleniumbase`` : ```bash pip install seleniumbase ``` * 添加 ``--upgrade`` 或 ``-U`` 来更新安装程序. * 添加 ``--force-reinstall`` 更新依赖包.

下载 webdriver:

SeleniumBase 下载 webdriver 驱动到 [seleniumbase/drivers](https://github.com/seleniumbase/SeleniumBase/tree/master/seleniumbase/drivers) 文件夹下, 使用 ``install`` 命令: ```bash seleniumbase install chromedriver ``` * 你可能需要不同的 webdriver 来对应各种网页浏览器来完成自动化测试,例如: ``chromedriver`` 对应 Chrome, ``edgedriver`` 对应 Edge, ``geckodriver`` 对应 Firefox, ``operadriver`` 对应 Opera, ``iedriver`` 对应 Internet Explorer. * 如果你需要安装最新版本的浏览器驱动, 以以下命令获取最新版本浏览器驱动 (因兼容性原因,默认下载的版本为 chromedriver 2.44 ): ```bash seleniumbase install chromedriver latest ```

使用 Chrome 运行用例:

```bash cd examples/ pytest my_first_test.py ``` * 如果没指定版本则默认运行的浏览器驱动为 chromedriver, 使用指定版本的命令为: ``--browser=BROWSER``. * Linux 中 ``--headless`` 为默认值 (无界面运行).你也可以在任何系统中运行无界面模式. 如果你的 Linux服务器有 GUI 界面,你也需要在界面中查看浏览器运行用例的过程,你可以添加 ``--headed`` 或 ``--gui``. 运行 [my_first_test.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py) Demo Mode: ```bash pytest my_first_test.py --demo ``` 此处为相关代码 [my_first_test.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py): ```python 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") ``` * 默认情况下, **[CSS Selectors](https://www.w3schools.com/cssref/css_selectors.asp)** 用来查找页面元素. * 如果你是CSS Selectors新手, 可以通过 [Flukeout](http://flukeout.github.io/) 游戏来帮助学习掌握. * 在上述代码中可以看到以下相关的 ``SeleniumBase`` 方法: ``from seleniumbase import BaseCase``: ```python self.open(URL) # 打开页面 self.click(SELECTOR) # 点击页面元素 self.type(SELECTOR, TEXT) # 输入文字 (添加 "\n" 在"TEXT"的末尾来进行换行.) self.assert_element(SELECTOR) # 断言元素是否存在并可见 self.assert_text(TEXT) # 断言文本是否存在并可见 (可以选择某个元素选择器) self.assert_title(PAGE_TITLE) # 断言标题是否存在并可见 self.assert_no_404_errors() # 断言不存在404错误,若存在则断言失败 self.assert_no_js_errors() # 断言不存在js错误 (Chrome-ONLY) self.execute_script(JAVASCRIPT) # 在页面中执行js脚本 self.go_back() # 返回到上一个url链接页面 self.get_text(SELECTOR) # 获取元素的文本 self.get_attribute(SELECTOR, ATTRIBUTE) # 获取某个定位元素的指定元素属性的属性值 self.is_element_visible(SELECTOR) # 判断元素是否在页面上可见 self.is_text_visible(TEXT) # 判断文本是否在页面上可见(可提供 SELECTOR) self.hover_and_click(HOVER_SELECTOR, CLICK_SELECTOR) # 鼠标移动在指定元素上后点击另一个元素 self.select_option_by_text(DROPDOWN_SELECTOR, OPTION_TEXT) # 选择下拉框中内容 self.switch_to_frame(FRAME_NAME) # 切换 webdriver control 到页面上指定 iframe self.switch_to_default_content() # 切换 webdriver control out 到当前的 iframe self.switch_to_window(WINDOW_NUMBER) # 切换不同的 window/tab self.save_screenshot(FILE_NAME) # 保存当前页面的截图 ``` [chinese_test_1.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/translations/chinese_test_1.py): ```python from seleniumbase.translate.chinese import 硒测试用例 硒测试用例.main(__name__, __file__) class 我的测试类(硒测试用例): def test_例子1(self): self.开启("https://zh.wikipedia.org/wiki/") self.断言标题("维基百科,自由的百科全书") self.断言元素('a[title="Wikipedia:关于"]') self.如果可见请单击('button[aria-label="关闭"]') self.如果可见请单击('button[aria-label="關閉"]') self.断言元素('span:contains("创建账号")') self.断言元素('span:contains("登录")') self.输入文本('input[name="search"]', "舞龍") self.单击('button:contains("搜索")') self.断言文本("舞龍", "#firstHeading") self.断言元素('img[src*="Chinese_draak.jpg"]') self.回去() self.输入文本('input[name="search"]', "麻婆豆腐") self.单击('button:contains("搜索")') self.断言文本("麻婆豆腐", "#firstHeading") self.断言元素('figure:contains("一家中餐館的麻婆豆腐")') self.回去() self.输入文本('input[name="search"]', "精武英雄") self.单击('button:contains("搜索")') self.断言元素('img[src*="Fist_of_legend.jpg"]') self.断言文本("李连杰", 'li a[title="李连杰"]') ``` ``from seleniumbase.translate.chinese import 硒测试用例``: ```python self.开启(URL) # 打开页面 self.单击(SELECTOR) # 点击页面元素 self.输入文本(SELECTOR, TEXT) # 输入文字 (添加 "\n" 在"TEXT"的末尾来进行换行.) self.断言元素(SELECTOR) # 断言元素是否存在并可见 self.断言文本(TEXT) # 断言文本是否存在并可见 (可以选择某个元素选择器) self.断言标题(PAGE_TITLE) # 断言标题是否存在并可见 self.检查断开的链接() # 断言不存在404错误,若存在则断言失败 self.检查JS错误() # 断言不存在js错误 (Chrome-ONLY) self.执行脚本(JAVASCRIPT) # 在页面中执行js脚本 self.回去() # 返回到上一个url链接页面 self.获取文本(SELECTOR) # 获取元素的文本 self.获取属性(SELECTOR, ATTRIBUTE) # 获取某个定位元素的指定元素属性的属性值 self.元素是否可见(SELECTOR) # 判断元素是否在页面上可见 self.文本是否显示(TEXT) # 判断文本是否在页面上可见(可提供 SELECTOR) self.悬停并单击(HOVER_SELECTOR, CLICK_SELECTOR) # 鼠标移动在指定元素上后点击另一个元素 self.按文本选择选项(DROPDOWN_SELECTOR, OPTION_TEXT) # 选择下拉框中内容 self.切换到帧(FRAME_NAME) # 切换 webdriver control 到页面上指定 iframe self.切换到默认内容() # 切换 webdriver control out 到当前的 iframe self.切换到窗口(WINDOW_NUMBER) # 切换不同的 window/tab self.保存截图(FILE_NAME) # 保存当前页面的截图 ``` 完整的 SeleniumBase methods, 可见: Method Summary

了解更多信息:

自动化 WebDriver 技能:

SeleniumBase 自动化控制 WebDriver 操作 web browsers(浏览器),在运行失败后进行截图保存. (了解更多关于定制的启动测试用例.)

简易的代码:

SeleniumBase 使用简单简约的语法, 例如: ```python self.type("input", "dogs\n") ``` 上述相似的代码在 Webdriver中变现的不是特别好: (而且下面的代码不包含 SeleniumBase 的智能等待.) ```python from selenium.webdriver.common.by import By element = self.driver.find_element(by=By.CSS_SELECTOR, value="input") element.clear() element.send_keys("dogs") element.submit() ``` 如你所见,在 WebDriver 中同样的事情并不如 SeleniumBase! 使用 SeleniumBase 让你的用例变得更加简单! (你可以在你的代码中一直使用 ``self.driver`` .)

适用 ``pytest`` 或者 ``nosetests`` 在所有的浏览器中运行你的测试用例:

(推荐使用 **pytest** . **Chrome** 是默认的浏览器.) ```bash pytest my_first_test.py --browser=chrome nosetests test_suite.py --browser=firefox ``` Python 文件中所有以 ``test_`` 开头的python方法将自动运行当你使用 ``pytest`` 或 ``nosetests``, (或包含Python文件的文件夹). 还可以使用以下命令更具体地说明在文件中运行什么: (注意,pytest和nosetests的语法是不同的.) ```bash pytest [FILE_NAME].py::[CLASS_NAME]::[METHOD_NAME] nosetests [FILE_NAME].py:[CLASS_NAME].[METHOD_NAME] ```

不再有不可靠的测试:

在与页面元素进行交互之前,SeleniumBase方法会自动等待页面元素完成加载(*直到超时限制*)。这意味着您不再需要脚本中随机的' time.sleep() '语句.

自动/手动混合模式:

SeleniumBase包括一个名为 MasterQA的解决方案, 通过让自动化执行所有浏览器操作,同时由手动测试人员处理验证,从而加快了手动测试的速度。.

丰富的特性:

获取SeleniumBase特性的完整列表, 点击这里.

详细说明书:

下面介绍如何在各种web浏览器上运行示例脚本:

首先,为您打算使用的每个浏览器安装一个webdriver: ```bash seleniumbase install chromedriver seleniumbase install geckodriver seleniumbase install edgedriver seleniumbase install iedriver seleniumbase install operadriver ``` 接着, 在 **pytest** 和 **nosetests** 中选择一个为您的测试启动器. (可以互换.) ```bash cd examples/ pytest my_first_test.py --browser=chrome nosetests my_first_test.py --browser=firefox ``` (如果没有指定浏览器,则默认使用Chrome.) 对于Pytest,绿色的点表示测试通过。“F”表示测试失败。 **使用演示模式来帮助您查看所断言的测试.** 如果示例测试运行得太快,您可以在**Demo模式**下运行它,方法是在命令行上添加``--Demo ``,它会在操作之间短暂地暂停浏览器,突出显示正在操作的页面元素,并让您实时了解测试断言的内容:: ```bash pytest my_first_test.py --demo ``` **Pytest** 包括测试发现。如果您没有指定要运行的特定文件或文件夹,`` pytest ``将根据以下匹配条件自动搜索要运行的测试的所有子目录: Python 文件名应是开头为 ``test_`` 或者以 ``_test.py``结尾. Python 方法应以 ``test_``开头. Python类名可以是任何东西,因为SeleniumBase的`` BaseCase ``类继承自`` unittest ``的TestCase的类。 你可以看到哪些测试是由`` pytest ``发现使用:: ```bash pytest --collect-only -q ``` 您可以在脚本中使用以下内容来帮助您调试问题: (如果使用pdb,请确保将“-s”添加到命令行选项中,除非已经在pytest.ini中) ```python import time; time.sleep(5) # Makes the test wait and do nothing for 5 seconds. import pdb; pdb.set_trace() # Enter debugging mode. n = next, c = continue, s = step. import pytest; pytest.set_trace() # Enter debugging mode. n = next, c = continue, s = step. ``` 要暂停抛出异常或错误的活动测试,请添加``--pdb -s ``: ```bash pytest my_first_test.py --pdb -s ``` 上面的代码将在出现故障时打开浏览器窗口。(pdb命令:'n', 'c', 's' => next, continue, step)。 下面是Pytest附带的一些有用的命令行选项: ```bash -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命令行选项: ```bash --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.) --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.) --pls=PLS # (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".) --headless # (Run tests in headless mode. The default arg on Linux OS.) --headless2 # (Use the 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.) --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.) --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.) --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-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.) --remote-debug # (Sync to Chrome Remote Debugger chrome://inspect/#devices) --final-debug # (Enter Debug Mode after each test ends. 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 # (Use Chrome's "--use-gl=swiftshader" feature.) --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-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.) ``` (有关详细信息,请参见命令行选项的完整列表 **[点击这里](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/plugins/pytest_plugin.py)**.) 在测试失败期间,最近一次测试运行的日志和屏幕截图将被保存到``latest_logs/``文件夹中。如果在命令行选项中添加——archive_logs,或者在 [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py)中将``ARCHIVE_EXISTING_LOGS``设置为``True``,那么这些日志将被移动到``archived_logs/``。否则,将在下一次测试运行开始时清理日志文件。``test_suite.py``集合包含故意失败的测试,以便您可以看到日志记录是如何工作的。 ```bash cd examples/ pytest test_suite.py --browser=chrome pytest test_suite.py --browser=firefox ``` 覆盖seleniumbase/config/settings.py的一个简单方法是使用自定义设置文件。下面是要添加到测试中的命令行选项: (See [examples/custom_settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/custom_settings.py)) ``--settings_file=custom_settings.py`` (设置包括默认超时值、双因素auth密钥、DB凭据、S3凭据和测试使用的其他重要设置.) 要将额外的数据从命令行传递给测试,添加 ``--data="ANY STRING"``. 现在在您的测试中,您可以使用 ``self.data`` 来访问。

测试目录定制:

用于在SeleniumBase repo之外运行测试 Pytest, 你需要一份 [pytest.ini](https://github.com/seleniumbase/SeleniumBase/blob/master/pytest.ini) 在根目录上。用于在SeleniumBase repo之外运行测试 Nosetests, 你需要拷贝 [setup.cfg](https://github.com/seleniumbase/SeleniumBase/blob/master/setup.cfg) 在根目录上. (子文件夹应该包括一个空白的 "__init__.py" 文件。)这些文件指定测试的默认配置细节。(对于运行nosetest,还可以使用``--config ``指定.cfg文件。示例`` nosetests [MY_TEST].py--config=[MY_CONFIG].cfg `` ') 作为一个快捷方式,您可以运行`` seleniumbase mkdir [DIRECTORY_NAME] ``来创建一个新的文件夹,其中已经包含了必要的文件和一些可以运行的示例测试。例子: ```bash seleniumbase mkdir ui_tests cd ui_tests/ pytest my_first_test.py ```

日志记录/失败测试的结果:

让我们尝试一个失败的测试示例: ```python """ test_fail.py """ from seleniumbase import BaseCase 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 ``` 你可以运行在``example``文件夹运行: ```bash pytest test_fail.py ``` 您会注意到,创建了一个名为“latest_logs”的日志文件夹来保存有关失败测试的信息和屏幕截图。在测试运行期间,如果您在 [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py)中将ARCHIVE_EXISTING_LOGS设置为True, 或者如果您使用``--archive-logs ``运行测试,那么过去的结果就会移动到archived_logs文件夹中。如果您选择不归档现有的日志,它们将被删除,并被最新测试运行的日志所取代。

创建可视化测试套件报告:

(注意:Pytest和nosetest的一些命令行参数是不同的)

Pytest 报告:

使用 ``--html=report.html`` 在您的测试套件完成后,为您提供指定名称的漂亮报告。 ```bash pytest test_suite.py --html=report.html ``` Example Pytest Report 还可以使用``--junit-xml=report``。获取一个xml报告。Jenkins可以使用这个文件为您的测试显示更好的报告。 ```bash pytest test_suite.py --junit-xml=report.xml ```

Nosetest 报告:

``--report`` 选项将在测试套件完成后为您提供一个漂亮的报告。 ```bash nosetests test_suite.py --report ``` Example Nosetest Report (注意:您可以添加``--show-report ``来在测试套件完成后立即显示Nosetest报告。只在本地运行测试时使用``--show-report ``,因为它会暂停测试运行.)

使用代理服务器:

如果您希望为您的浏览器测试使用代理服务器(仅适用于Chrome和Firefox),您可以在命令行上添加``--proxy=IP_ADDRESS:PORT ``作为参数。 ```bash pytest proxy_test.py --proxy=IP_ADDRESS:PORT ``` 如果您希望使用的代理服务器需要身份验证,您可以执行以下操作 (Chrome only): ```bash pytest proxy_test.py --proxy=USERNAME:PASSWORD@IP_ADDRESS:PORT ``` 为了使事情更简单,您可以将您经常使用的代理添加到PROXY_LIST中 [proxy_list.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/proxy_list.py), 然后使用``--proxy=KEY_FROM_PROXY_LIST ``来使用该键的IP_ADDRESS:PORT。 ```bash pytest proxy_test.py --proxy=proxy1 ```

变更 User-Agent:

如果您希望为您的浏览器测试更改用户代理(仅限Chrome和Firefox),您可以在命令行上添加``--agent="USER agent STRING" ``作为参数。 ```bash pytest user_agent_test.py --agent="Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7412.EU" ```

为网站建设导游服务:

学习更多内容 SeleniumBase Interactive Walkthroughs (在 ``examples/tour_examples`` 文件). 这对于构建一个在线体验网站的原型非常有用。

Production Environments & Integrations:

下面是为测试设置生产环境时可以做的一些事情: * 您可以启动 [Jenkins](https://jenkins.io/) 为定期运行测试构建服务器. 这是一个真实的Jenkins的headless浏览器自动化的例子, check out the SeleniumBase Jenkins在Azure上的例子 或者 在谷歌云上的SeleniumBase Jenkins例子. * 您可以使用 [the Selenium Grid](https://selenium.dev/documentation/en/grid/) 通过在多台机器上并行执行测试来扩展测试. 要做到这一点,请查看 [SeleniumBase selenium_grid folder](https://github.com/seleniumbase/SeleniumBase/tree/master/seleniumbase/utilities/selenium_grid), 这应该有你需要的一切,包括 Selenium Grid ReadMe, 这会帮助你开始. * 如果你用 SeleniumBase MySQL 特性 保存在服务器机器上运行的测试结果,你需要安装 [MySQL Workbench](https://dev.mysql.com/downloads/tools/workbench/) 帮助你从你的数据库更容易地读和写. * 如果你用 [Slack](https://slack.com), 您可以使用 [Jenkins Slack Plugin](https://github.com/jenkinsci/slack-plugin)很容易地让Jenkins jobs在那里显示结果. 另一种将消息从测试发送到Slack的方法是通过 [Slack's Incoming Webhooks API](https://api.slack.com/incoming-webhooks). * 如果您正在使用AWS,您可以设置一个 [Amazon S3](https://aws.amazon.com/s3/) 保存来自测试的日志文件和屏幕截图的帐户. 激活此功能, 修改 [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py) 连接细节见S3部分, 添加 "``--with-s3-logging``" 在运行测试时使用命令行. 下面是一个启用了附加功能的测试运行示例: ```bash pytest [YOUR_TEST_FILE].py --with-db-reporting --with-s3-logging ```

详细的方法说明和实例:

导航到web页面 (使用相关commands)

```python 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™: 您可能需要使用get_page_source()方法和Python的find()命令来解析源代码,以找到Selenium无法找到的东西。(你可能需要温习一下你的Python编程技能。) ```python source = self.get_page_source() head_open_tag = source.find('') head_close_tag = source.find('', head_open_tag) everything_inside_head = source[head_open_tag+len(''):head_close_tag] ```

点击

单击页面上的元素: ```python self.click("div#my_id") ``` **ProTip™:** 在大多数web浏览器中,您可以右键单击页面并选择`` Inspect Element ``来查看创建您自己的脚本所需的CSS选择器详细信息.

输入文本

self.type(selector, text) # 用指定的值更新来自指定元素的文本。如果元素丢失或文本字段不可编辑,则引发异常。例如: ```python self.type("input#id_value", "2012") ``` 您也可以使用self.add_text()或WebDriver .send_keys()命令,但是如果文本框中已经有文本,这些命令不会首先清除文本框 如果您想键入特殊的键,这也很容易。这里有一个例子: ```python from selenium.webdriver.common.keys import Keys self.find_element("textarea").send_keys(Keys.SPACE + Keys.BACK_SPACE + '\n') # The backspace should cancel out the space, leaving you with the newline ```

从页面上的元素获取文本

```python text = self.get_text("header h2") ```

从页面上的元素获取属性值

```python attribute = self.get_attribute("#comic img", "title") ```

断言页面上某个元素在几秒钟内存在:

```python self.wait_for_element_present("div.my_class", timeout=10) ``` (注意: 您也可以使用: ``self.assert_element_present(ELEMENT)``)

在数秒内断言页面上元素的可见性:

```python self.wait_for_element_visible("a.my_class", timeout=5) ``` (注意: 这个的简单版本是 ``self.find_element(ELEMENT)`` 和 ``self.assert_element(ELEMENT)``. find_element() version 返回元素) 由于上面的行返回元素,您可以将其与.click()组合起来,如下所示: ```python 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™:** 可以使用点来表示类名(例如:`` div.class_name ``),这是CSS选择器中`` div[class="class_name"] ``的简化版本。 你也可以使用 ``*=`` 在CSS选择器中搜索任何部分值,如下所示: ```python self.click('a[name*="partial_name"]') ```

在数秒内断言页面上元素内的文本的可见性:

```python 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)`` 干了同一件事. 为了向后字兼容性,保留了较旧的方法名,但默认超时可能不同.)

断言 anything

```python self.assert_true(myvar1 == something) self.assert_equal(var1, var2) ```

有用的条件语句 (with creative examples in action)

is_element_visible(selector) # is an element visible on a page ```python if self.is_element_visible('div#warning'): print("Red Alert: Something bad might be happening!") ``` is_element_present(selector) # is an element present on a page ```python 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 ``` Another example: ```python 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) # is text visible on a page ```python 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("For the Love of Marketing and Earl Grey Tea!", selector): return "Picard HubSpot Superbowl Ad 2015" elif self.is_text_visible("Delivery Drones... Engage", selector): return "Picard Amazon Superbowl Ad 2015" elif self.is_text_visible("Bing it on Screen!", selector): return "Picard Microsoft Superbowl Ad 2015" elif self.is_text_visible("OK Glass, Make it So!", selector): return "Picard Google Superbowl Ad 2015" elif self.is_text_visible("Number One, I've Never Seen Anything Like It.", selector): return "Picard Tesla 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 Wikimedia Superbowl Ad 2015" elif self.is_text_visible("Let us make sure history never forgets the name ... Facebook", selector): return "Picard Facebook Superbowl Ad 2015" else: raise Exception("Reports of my assimilation are greatly exaggerated.") ```

切换 tabs

如果您的测试打开了一个新选项卡/窗口,而现在您有多个页面,该怎么办?没有问题。您需要指定当前想要使用哪个Selenium。在选项卡/窗口之间切换很容易: ```python self.switch_to_window(1) # This switches to the new tab (0 is the first one) ``` **ProTip™:** iFrame遵循与新窗口相同的原则—如果要对其中的某些内容采取操作,需要指定iFrame ```python self.switch_to_frame('ContentManagerTextBody_ifr') # Now you can act inside the iFrame # .... Do something cool (here) self.switch_to_default_content() # Exit the iFrame when you're done ```

处理 Pop-Up 警告

如果您的测试在浏览器中弹出了一个警告,该怎么办?没有问题。你需要切换到它,要么接受它,要么拒绝它: ```python self.wait_for_and_accept_alert() self.wait_for_and_dismiss_alert() ``` 如果您不确定在尝试接受或取消警报之前是否有警报,一种处理方法是将警报处理代码包装在try/except块中。其他方法(如.text和.send_keys())也可以使用警报.

执行定制jQuery脚本:

Query是一个强大的JavaScript库,允许您在web浏览器中执行高级操作。 如果您所在的web页面已经加载了jQuery,您可以立即开始执行jQuery脚本。 您应该知道这一点,因为web页面在HTML中会包含如下内容: ```html ``` 如果您想在尚未加载jQuery的页面上使用它,这是可以的。为此,首先运行以下命令: ```python self.activate_jquery() ``` 许多 websites 存在限制 [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) 防止用户将jQuery和其他外部库加载到自己的网站上。如果您需要在这样的网站上使用jQuery或其他JS库,请在命令行上添加``--disable_csp ``。 下面是一些在脚本中使用jQuery的例子: ```python 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 ``` 在下面的示例中,JavaScript用于在页面上植入代码,然后Selenium可以在此之后访问该页面: ```python start_page = "https://xkcd.com/465/" destination_page = "https://github.com/seleniumbase/SeleniumBase" self.open(start_page) referral_link = '''Free-Referral Button!''' % destination_page self.execute_script('''document.body.innerHTML = \"%s\"''' % referral_link) self.click("a.analytics") # Clicks the generated button ``` (由于大众需求,这个流量生成示例已经被嵌入到SeleniumBase中 ``self.generate_referral(start_page, end_page)`` 和 ``self.generate_traffic(start_page, end_page, loops)`` 方法中.)

使用延迟的断言:

假设您想在单个测试中验证web页面上的多个不同元素,但是您不希望在一次验证多个元素之前测试失败,这样您就不必重新运行测试来查找同一页面上的更多缺失元素。这就是延迟断言的用武之地。这里的例子: ```python from seleniumbase import BaseCase class MyTestClass(BaseCase): def test_delayed_asserts(self): self.open('https://xkcd.com/993/') self.wait_for_element('#comic') self.delayed_assert_element('img[alt="Brand Identity"]') self.delayed_assert_element('img[alt="Rocket Ship"]') # Will Fail self.delayed_assert_element('#comicmap') self.delayed_assert_text('Fake Item', '#middleContainer') # Will Fail self.delayed_assert_text('Random', '#middleContainer') self.delayed_assert_element('a[name="Super Fake !!!"]') # Will Fail self.process_delayed_asserts() ``` ``delayed_assert_element()`` 和 ``delayed_assert_text()`` 将保存将引发的任何异常。 要将所有失败的延迟断言清除到单个异常中, 确保在测试方法的末尾调用 ``self.process_delayed_asserts()`` . 如果测试涉及多个页面, 可以在单个页面的所有延迟断言的末尾调用 ``self.process_delayed_asserts()``. 这样,日志文件的屏幕截图就会显示延迟断言的生成位置。

访问原始WebDriver

如果您需要访问标准WebDriver附带的任何命令,您可以像这样直接调用它们: ```python self.driver.delete_all_cookies() capabilities = self.driver.capabilities self.driver.find_elements_by_partial_link_text("GitHub") ``` (通常,您会希望在可用时使用带方法的SeleniumBase版本.)

自动重试失败的测试

你可以使用 ``--reruns NUM`` 来重试失败的用例,次数为 NUM 值. 使用 ``--reruns-delay SECONDS`` 在重试之间等待那么多秒。例子: ``` pytest --reruns 5 --reruns-delay 1 ``` 此外,可以使用`` @retry_on_exception() ``装饰器来特别重试失败的方法. (需要 import: ``from seleniumbase import decorators``) 了解更多关于SeleniumBase装饰器的信息, [click here](https://github.com/seleniumbase/SeleniumBase/tree/master/seleniumbase/common).

简讯

祝贺您开始使用SeleniumBase!

如果你有任何问题,说出来! 并联系我们

如果你喜欢这个项目,请给个❤(stars)吧!

https://github.com/mdmintz

Repo Size Join the chat!
Tested with SeleniumBase SeleniumBase.io Docs

SeleniumBase on GitHub SeleniumBase on Gitter SeleniumBase on Twitter SeleniumBase on Instagram SeleniumBase on Facebook