资讯动态

Python+Selenium自动化测试实战与优化技巧

发布时间:2026/10/27 22:53:16 来源:尧图企业网站定制
1. 为什么选择PythonSelenium做自动化测试十年前我刚入行测试时手工点击页面按钮到凌晨三点的经历让我至今难忘。现在PythonSelenium的组合已经成为Web自动化测试的事实标准这背后有几个关键原因首先Python的语法就像说人话一样简单。我带的实习生经常开玩笑说这代码读起来像英语小作文。比如定位元素只需要driver.find_element(By.ID, username)比Java的WebDriver driver new FirefoxDriver();清爽多了。对于测试脚本这种需要频繁修改的场景Python的动态类型和简洁语法能节省大量时间。其次Selenium的跨浏览器支持实在太香。记得2016年某个紧急项目需要兼容IE11我用Selenium Grid只花了半天就搭建好了测试环境。现在最新版的Selenium 4更是原生支持CDP协议连Chrome DevTools的功能都能直接调用。2. 环境搭建避坑指南2.1 Python安装的玄学问题新手最容易栽在Python环境上。最近帮同事排查一个诡异问题同样的脚本在他电脑上报No module named selenium但pip list明明显示已安装。最终发现他同时安装了Python 3.8和3.9而PATH指向的是3.8pip却装到了3.9的site-packages里。建议用以下命令检查环境一致性which python # 查看Python解释器路径 which pip # 查看pip路径 pip list # 查看当前环境安装的包2.2 Selenium的版本矩阵Selenium 4有个大坑它要求浏览器驱动必须严格匹配浏览器版本。上周我用webdriver_manager自动下载驱动时就遇到了Chrome 115版本找不到对应驱动的尴尬情况。这是目前验证过的稳定组合组件版本备注Python3.83.7已停止维护Selenium4.10旧版API不同ChromeDriver114-116新版可能不兼容Firefox(geckodriver)最新ESR版企业版更稳定3. 元素定位的实战技巧3.1 比XPath更香的CSS选择器早期我特别依赖XPath直到遇到一个动态ID的商城页面XPath路径长得能绕显示器三圈。后来发现CSS选择器才是真神器# 找包含购物车文字的span driver.find_element(By.CSS_SELECTOR, span:contains(购物车)) # 找class为price且父元素是div的span driver.find_element(By.CSS_SELECTOR, div span.price)警告:contains()不是标准CSS仅在Selenium中可用。正式环境建议用text()xxx的XPath3.2 等待的艺术元素加载不同步是最常见的报错原因。我总结出三级等待策略硬等待time.sleep(3)最后手段隐式等待driver.implicitly_wait(10)全局设置显式等待推荐方案from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC element WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, dynamicElement)) )4. 框架设计进阶4.1 Page Object模式改造看过太多面条代码式的测试脚本维护起来简直噩梦。这是我团队现在用的PO模式结构project/ ├── pages/ │ ├── login_page.py │ └── dashboard_page.py ├── tests/ │ └── test_login.py └── utilities/ ├── config_reader.py └── custom_waits.py其中login_page.py的典型写法class LoginPage: def __init__(self, driver): self.driver driver self.username_field (By.ID, username) self.password_field (By.XPATH, //input[typepassword]) def enter_credentials(self, username, password): self.driver.find_element(*self.username_field).send_keys(username) self.driver.find_element(*self.password_field).send_keys(password) def click_login(self): self.driver.find_element(By.CSS_SELECTOR, button.login-btn).click()4.2 异常处理模板这个try-catch模板帮我定位过无数诡异问题try: element.click() except Exception as e: screenshot_path fscreenshots/failure_{datetime.now().strftime(%Y%m%d_%H%M%S)}.png driver.save_screenshot(screenshot_path) page_source_path fpage_source/failure_{datetime.now().strftime(%Y%m%d_%H%M%S)}.html with open(page_source_path, w, encodingutf-8) as f: f.write(driver.page_source) raise AssertionError(f元素点击失败截图已保存到{screenshot_path}) from e5. 真实案例电商下单流程测试最近用这套方法测试某跨境电商平台发现三个关键问题货币切换BUG# 测试步骤 home_page.select_currency(EUR) product_page.add_to_cart() assert € in cart_page.get_total_price() # 这里报错最终发现是CDN缓存导致货币符号没更新地址自动填充失效 通过分析发现是Google Places API的key过期了移动端支付跳转超时 用driver.context切换到WebView后才成功定位到元素6. 持续集成实战在Jenkins中这样配置能节省大量时间pipeline { agent any environment { PYTHON_PATH C:\\Python38 CHROME_DRIVER drivers/chromedriver.exe } stages { stage(Test) { steps { bat set PATH%PYTHON_PATH%;%PYTHON_PATH%\\Scripts;%PATH% python -m pytest tests/ --alluredir./allure-results } } } post { always { allure includeProperties: false, jdk: , results: [[path: allure-results]] } } }7. 性能优化技巧复用浏览器会话options webdriver.ChromeOptions() options.add_experimental_option(debuggerAddress, 127.0.0.1:9222) driver webdriver.Chrome(optionsoptions) # 连接已打开的浏览器并行测试方案from concurrent.futures import ThreadPoolExecutor def run_test(browser): # 测试代码... with ThreadPoolExecutor(max_workers3) as executor: executor.map(run_test, [chrome, firefox, edge])智能等待改进def wait_for_animation(driver, timeout30): WebDriverWait(driver, timeout).until( lambda d: d.execute_script(return jQuery.active 0) )8. 移动端测试特别处理Hybrid应用测试需要特别注意这个流程先获取当前上下文contexts driver.contexts # [NATIVE_APP, WEBVIEW_com.example]切换到WebViewdriver.switch_to.context(contexts[1])现在可以用常规CSS选择器定位元素了关键点必须开启App的WebView调试模式在代码中需要指定appPackage和appActivity9. 常见报错解决方案这是我整理的排错清单错误信息可能原因解决方案NoSuchElementException元素未加载/定位器错误1. 增加等待时间 2. 检查iframe 3. 更新定位器ElementClickInterceptedException元素被遮挡1. 滚动到元素 2. 使用JavaScript点击StaleElementReferenceExceptionDOM已更新重新获取元素引用InvalidSelectorExceptionXPath/CSS语法错误使用浏览器开发者工具验证10. 最新趋势Selenium 4的相对定位Selenium 4新增的相对定位API简直不要太方便from selenium.webdriver.support.relative_locator import with_tag_name password_field driver.find_element(By.ID, password) submit_button driver.find_element( with_tag_name(button).below(password_field) )支持的方向包括above()below()to_left_of()to_right_of()near()50像素范围内11. 可视化报告生成用Allure生成这样的报告只需三步安装依赖pip install allure-pytest添加装饰器allure.title(测试登录功能) allure.feature(认证模块) def test_login(): ...运行测试pytest --alluredir./allure-results allure serve ./allure-results生成的报告包含自动录制的操作步骤截图和DOM快照12. 无头模式优化Chrome无头模式的新参数能提升20%执行速度options webdriver.ChromeOptions() options.add_argument(--headlessnew) # 新版无头模式 options.add_argument(--disable-gpu) options.add_argument(--window-size1920,1080) # 避免响应式布局问题13. 元素状态检查大全这些判断方法能避免很多Flaky测试def is_clickable(element): return element.is_displayed() and element.is_enabled() def is_disappeared(driver, locator, timeout5): try: WebDriverWait(driver, timeout).until_not( EC.presence_of_element_located(locator) ) return True except TimeoutException: return False14. 跨域处理技巧遇到跨域iframe时可以这样操作# 先切换到iframe driver.switch_to.frame(iframe_id) # 操作iframe内的元素 driver.find_element(...).click() # 切回主文档 driver.switch_to.default_content()注意如果iframe是动态加载的需要先等待其加载完成15. 文件上传终极方案各种文件上传场景的处理方法普通input上传driver.find_element(By.CSS_SELECTOR, input[typefile]).send_keys(/path/to/file)Flash/ActiveX控件考虑用AutoIT或PyWinAuto拖拽上传用ActionChains模拟file_input driver.find_element(...) drop_area driver.find_element(...) actions ActionChains(driver) actions.drag_and_drop(file_input, drop_area).perform()16. 验证码处理策略测试环境禁用验证码推荐设置万能验证码如0000使用OCR服务准确率约70%人工干预接口通过API获取验证码17. 测试数据管理我用Faker库生成逼真的测试数据from faker import Faker fake Faker(zh_CN) test_user { name: fake.name(), email: fake.email(), address: fake.address(), phone: fake.phone_number() }18. 性能对比测试用time模块简单测算操作耗时start_time time.time() driver.find_element(...).click() end_time time.time() print(f点击操作耗时{(end_time - start_time)*1000:.2f}毫秒)更专业的可以用BrowserMob Proxy做网络性能分析19. 浏览器日志分析获取控制台日志排查JS错误logs driver.get_log(browser) for log in logs: if log[level] SEVERE: print(f[JS错误] {log[message]})20. 自动化测试的未来最近在试验SeleniumBase框架它内置了很多实用功能from seleniumbase import BaseCase class MyTest(BaseCase): def test_example(self): self.open(https://example.com) self.assert_title(Example Domain) self.assert_element(div h1)这种扩展框架可能会成为新趋势特别是它自带的自动重试机制和智能等待能显著降低Flaky测试的出现概率

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑