如何使用Selenium WebDriver定位Bokeh文档中的按钮?
用Pytest + Selenium测试Bokeh交互式应用
我正在用Python和Bokeh创建带简单用户交互的图表(比如按钮点击),通过bokeh serve myapp.py运行应用,现在想借助pytest和Selenium WebDriver在浏览器中与Bokeh文档交互,验证预期的工作流程。
我的Bokeh应用代码(myapp.py)
# run this with: bokeh serve myapp.py from bokeh.models import Button from bokeh.io import curdoc # 定义按钮点击后的回调逻辑 def on_button_click(): button.label = "已点击!" # 添加按钮组件 button = Button(label="Press Me") button.on_click(on_button_click) # 将按钮添加到当前文档 curdoc().add_root(button)
测试实现步骤与代码
1. 安装依赖
先确保安装好所需的工具包:
pip install pytest selenium bokeh
另外要下载对应浏览器的WebDriver(比如Chrome的chromedriver,版本要和浏览器匹配)。
2. 编写pytest测试用例
创建test_bokeh_app.py,内容如下:
import pytest from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import subprocess import time @pytest.fixture(scope="module") def bokeh_server(): # 启动Bokeh服务 process = subprocess.Popen( ["bokeh", "serve", "myapp.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE ) # 等待服务完全启动 time.sleep(3) yield process # 测试结束后终止服务 process.terminate() process.wait() def test_button_click_flow(bokeh_server): # 初始化Chrome浏览器驱动(可替换为Firefox等) driver = webdriver.Chrome() try: # 访问Bokeh应用 driver.get("http://localhost:5006/myapp") # 显式等待按钮加载完成,比固定sleep更可靠 button = WebDriverWait(driver, 5).until( EC.presence_of_element_located((By.CSS_SELECTOR, ".bk-btn.bk-btn-default")) ) # 验证初始按钮文本 assert button.text == "Press Me" # 模拟点击按钮 button.click() # 等待回调执行后验证文本变化 WebDriverWait(driver, 3).until( EC.text_to_be_present_in_element((By.CSS_SELECTOR, ".bk-btn.bk-btn-default"), "已点击!") ) assert button.text == "已点击!" finally: # 关闭浏览器 driver.quit()
3. 运行测试
在终端执行命令启动测试:
pytest test_bokeh_app.py -v
注意事项
- WebDriver版本必须和浏览器版本匹配,否则会出现兼容性报错;
- 如果遇到端口占用问题,可以指定Bokeh服务端口:
bokeh serve --port 5007 myapp.py,同时修改测试代码中的访问URL; - 优先使用Selenium的
WebDriverWait显式等待元素,避免依赖固定的time.sleep,提升测试稳定性。
内容的提问来源于stack exchange,提问作者mdk
相关产品推荐
相关产品推荐

