Python+Selenium UI自动化测试入门:从零编写登录脚本实战
1. 项目概述与价值定位
最近在技术社区和招聘要求里,“UI自动化测试”这个词出现的频率越来越高。很多刚接触测试或者想从功能测试转型的同学,常常觉得这个概念听起来高大上,实际操作起来却不知从何下手。其实,UI自动化的核心,就是用代码模拟人的操作,让程序去点点按钮、填填表单。今天,我就以一个最经典、最刚需的场景——“用户登录”为例,带你手把手用Python和Selenium写一个完整的登录UI自动化脚本。这个脚本麻雀虽小,五脏俱全,涵盖了环境搭建、元素定位、数据驱动、异常处理等核心知识点。无论你是想提升测试效率,还是为学习自动化打下第一块基石,这个从零到一的实践过程都值得你花时间跟着走一遍。你会发现,所谓的“自动化”,并没有想象中那么遥不可及。
2. 环境准备与核心工具解析
2.1 Python与Selenium的安装与配置
工欲善其事,必先利其器。我们的自动化脚本运行在Python环境中,并通过Selenium库来控制浏览器。因此,第一步就是搭建好这个基础环境。
首先,确保你的电脑上安装了Python。建议使用Python 3.7及以上版本,因为社区支持和库的兼容性更好。你可以打开命令行(Windows上是CMD或PowerShell,Mac/Linux上是Terminal),输入 python --version 或 python3 --version 来检查。如果没有安装,去Python官网下载安装包,记得勾选“Add Python to PATH”这个选项,这是为了能在命令行中直接使用python命令。
接下来安装Selenium。Selenium是一个强大的浏览器自动化工具,它提供了一套WebDriver API,允许我们用代码像真实用户一样操作浏览器。安装非常简单,只需要一条pip命令:
pip install selenium
如果你在国内,觉得下载速度慢,可以使用清华的镜像源来加速:
pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple
注意:有些同学可能会遇到同时安装了Python2和Python3的情况,导致命令混淆。这时,明确使用
pip3 install selenium来为Python3安装库是更稳妥的做法。
2.2 浏览器驱动的选择与下载
Selenium本身不能直接控制浏览器,它需要一个“桥梁”,这就是浏览器驱动(WebDriver)。不同的浏览器需要不同的驱动。Chrome浏览器因其强大的开发者工具和广泛的用户基础,成为了自动化测试的首选,所以我们以ChromeDriver为例。
驱动下载的核心原则:驱动版本必须与你的Chrome浏览器版本匹配! 这是新手最容易踩坑的地方。版本不匹配会导致脚本无法启动浏览器,并报错。
查看你的Chrome浏览器版本:打开Chrome,点击右上角三个点 -> 帮助 -> 关于Google Chrome。记下版本号(例如,版本 115.0.5790.170)。
然后,去ChromeDriver的官方下载站点或国内镜像站,下载对应版本的驱动。官方地址有时访问不稳定,国内一些高校的镜像站是很好的替代选择。下载后,你会得到一个可执行文件(Windows是 chromedriver.exe ,Mac/Linux是 chromedriver )。
驱动的存放位置有三种常见方案,各有利弊:
- 放入系统PATH路径 :这是最“干净”的做法。将
chromedriver.exe文件放在系统环境变量PATH包含的任意目录下,例如Windows的C:\Windows\或专门创建的脚本工具目录。这样,你在代码中初始化时,只需写webdriver.Chrome(),Selenium会自动在PATH中查找驱动。 - 放入项目目录 :将驱动文件直接放在你的Python脚本所在的文件夹里。在代码中需要指定驱动路径:
webdriver.Chrome(executable_path='./chromedriver')。这种方式项目自包含,便于管理,但每个项目都要放一份。 - 指定绝对路径 :在代码中明确写出驱动的完整磁盘路径。例如:
webdriver.Chrome(executable_path=r'C:\Users\YourName\Tools\chromedriver.exe')。这种方式最直接,但代码移植性差,换台电脑就得改路径。
对于初学者,我推荐第二种方式,简单直观,不容易因系统环境问题出错。等熟悉后,可以过渡到第一种,更符合生产环境的部署习惯。
2.3 集成开发环境(IDE)的选择
写Python脚本,一个好用的编辑器或IDE能极大提升效率。对于自动化测试脚本开发,我首推 Visual Studio Code (VSCode) 。
VSCode轻量、免费、插件生态丰富。你需要安装两个核心插件:
- Python :由Microsoft官方提供,提供代码高亮、智能提示(IntelliSense)、代码调试、环境管理等功能。
- Pylance :作为Python插件的语言服务器,能提供更强大、更快的代码补全和类型检查。
安装好VSCode和插件后,打开你的项目文件夹,VSCode通常能自动识别Python环境。如果遇到多个Python环境,你可以通过点击编辑器底部状态栏的Python版本号进行切换。配置好这些,你的代码编写体验会非常流畅,比如输入 webdriver. 之后,它会自动弹出 Chrome 、 Firefox 等可选类和方法,大大减少拼写错误和记忆负担。
3. 登录脚本核心逻辑与代码实现
3.1 脚本骨架与浏览器启动
让我们开始编写第一个脚本。创建一个新的Python文件,比如命名为 login_automation.py 。一个好的脚本应该结构清晰,我们从一个最简单的骨架开始:
# 导入必要的库
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
# 1. 创建浏览器驱动实例
driver = webdriver.Chrome() # 如果驱动不在PATH,需指定executable_path参数
# 2. 打开目标登录页面
driver.get("https://www.example.com/login") # 请替换为实际的登录页面URL
driver.maximize_window() # 最大化窗口,确保元素可见
# 3. 后续的定位与操作代码将写在这里...
# 4. 等待一会儿以便观察,然后关闭浏览器
time.sleep(5)
driver.quit()
这段代码做了四件事:导入库、启动Chrome浏览器、访问一个登录页面、等待5秒后关闭。 driver.quit() 会关闭浏览器并结束WebDriver进程,而 driver.close() 只会关闭当前标签页。在自动化脚本中,通常用 quit() 来做清理。
实操心得一:关于等待的哲学 这里我用了 time.sleep(5) ,这是一种“强制等待”。它简单粗暴,但效率低下,并且不稳定(如果页面5秒没加载完呢?)。在实际项目中,我们几乎不会这样用。这里只是为了演示效果。真正的自动化脚本必须使用更智能的“显式等待”或“隐式等待”,我们稍后会详细讲。
3.2 元素定位:自动化测试的基石
自动化操作的前提是找到页面上的元素(输入框、按钮、链接等)。Selenium提供了8种主要的定位方式,常用的是前6种:
- ID :
driver.find_element(By.ID, “username”)。ID通常是唯一的,定位速度最快,首选。 - Name :
driver.find_element(By.NAME, “password”)。Name属性也常用于表单元素。 - Class Name :
driver.find_element(By.CLASS_NAME, “btn-submit”)。注意,一个元素可能有多个class,这里要匹配完整的class字符串。 - Tag Name :
driver.find_element(By.TAG_NAME, “input”)。通常用于定位一组同类元素,如所有输入框。 - Link Text :
driver.find_element(By.LINK_TEXT, “忘记密码?”)。专门用于定位超链接(<a>标签),且要完全匹配链接文本。 - Partial Link Text :
driver.find_element(By.PARTIAL_LINK_TEXT, “忘记”)。链接文本的部分匹配。 - CSS Selector :
driver.find_element(By.CSS_SELECTOR, “#loginForm input[type=‘text’]”)。功能强大,语法灵活,是进阶必备。 - XPath :
driver.find_element(By.XPATH, “//form[@id=‘loginForm’]//input[1]”)。最强大的定位方式,可以遍历XML/HTML文档,但写起来复杂,执行速度相对慢。
如何查看元素属性? 打开Chrome浏览器,进入目标登录页面,按F12打开开发者工具。点击左上角的箭头图标(或按Ctrl+Shift+C),然后去页面上点击你想操作的元素,比如用户名输入框。在开发者工具的“Elements”面板中,该元素的代码会被高亮。你可以查看它的 id 、 name 、 class 等属性。
假设我们的登录页面有一个典型结构:
<input type="text" id="user" name="username" placeholder="请输入用户名">
<input type="password" id="pass" name="password" placeholder="请输入密码">
<button type="submit" class="btn-login">登录</button>
那么,我们的定位代码可以这样写:
# 定位用户名输入框
username_input = driver.find_element(By.ID, “user”) # 方式1:通过ID
# 或者 username_input = driver.find_element(By.NAME, “username”) # 方式2:通过Name
# 定位密码输入框
password_input = driver.find_element(By.ID, “pass”)
# 定位登录按钮
login_button = driver.find_element(By.CLASS_NAME, “btn-login”)
# 或者如果按钮有唯一文本,也可以用:driver.find_element(By.XPATH, “//button[text()=‘登录’]”)
3.3 模拟用户操作:输入与点击
定位到元素后,我们就可以模拟用户行为了。最常用的两个操作是 send_keys() (输入文本)和 click() (点击)。
# 在用户名输入框中输入文本
username_input.send_keys(“your_username”)
# 在密码输入框中输入文本
password_input.send_keys(“your_password”)
# 点击登录按钮
login_button.click()
有时候,输入框可能有默认文字(placeholder), send_keys() 会直接追加在后面。更严谨的做法是先清空输入框:
username_input.clear() # 清空输入框
username_input.send_keys(“new_username”)
实操心得二:关于点击的替代方案 不是所有“按钮”都是 <button> 标签,也可能是 <input type=“submit”> 或 <div> 伪装成的按钮。如果 click() 不生效,可以尝试:
- 模拟键盘回车:在密码输入后,执行
password_input.send_keys(Keys.ENTER)。 - 执行JavaScript点击:
driver.execute_script(“arguments[0].click();”, login_button)。这种方式能绕过一些前端框架的事件绑定问题,作为备选方案。
3.4 引入智能等待:让脚本更稳定
回到之前提到的等待问题。 time.sleep() 是糟糕的实践。我们应该使用Selenium提供的 显式等待(Explicit Wait) 。
显式等待会针对某个条件进行等待,在设定的最大时间范围内,只要条件满足就立即继续执行,否则超时则抛出异常。这比死等固定时间高效和可靠得多。
我们需要导入相关模块:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
然后,在关键操作前后加入等待。例如,等待登录按钮可点击后再点击:
# 创建一个等待对象,最多等10秒,每0.5秒检查一次条件
wait = WebDriverWait(driver, 10)
# 等待登录按钮出现且可点击
login_button = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, “btn-login”)))
login_button.click()
# 等待登录成功后的某个元素出现,比如用户头像或“退出”链接
# 这可以作为登录成功的断言
success_element = wait.until(EC.presence_of_element_located((By.ID, “userAvatar”)))
expected_conditions 模块提供了很多预置条件,如 presence_of_element_located (元素存在DOM中), visibility_of_element_located (元素可见), element_to_be_clickable (元素可点击)等。根据场景选用合适的条件,是编写稳定自动化脚本的关键。
4. 构建健壮的登录自动化脚本
4.1 完整脚本示例与逐行解析
现在,我们将所有部分组合起来,形成一个完整、相对健壮的登录脚本。这个脚本包含了异常处理的基本框架。
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 time
def test_login():
"""
一个简单的登录UI自动化测试函数
"""
driver = None # 初始化driver变量,以便在finally块中访问
try:
# 初始化浏览器驱动,指定驱动路径(根据你的实际情况修改)
driver = webdriver.Chrome(executable_path=‘./chromedriver’)
driver.maximize_window()
wait = WebDriverWait(driver, 10) # 创建显式等待对象
# 步骤1: 导航到登录页面
login_url = “https://www.example.com/login” # 替换为你的登录页
print(f“正在访问登录页面: {login_url}”)
driver.get(login_url)
# 步骤2: 等待页面关键元素加载完成(例如登录表单)
# 这里假设页面有一个id为‘loginForm’的表单,等待它出现
wait.until(EC.presence_of_element_located((By.ID, “loginForm”)))
print(“登录页面加载完成。”)
# 步骤3: 定位并操作元素
# 定位用户名输入框并输入
username_box = wait.until(EC.visibility_of_element_located((By.ID, “user”)))
username_box.clear()
username_box.send_keys(“test_user”) # 替换为你的测试用户名
print(“已输入用户名。”)
# 定位密码输入框并输入
password_box = driver.find_element(By.ID, “pass”)
password_box.clear()
password_box.send_keys(“test_password”) # 替换为你的测试密码
print(“已输入密码。”)
# 定位登录按钮并点击
login_btn = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, “btn-login”)))
login_btn.click()
print(“已点击登录按钮。”)
# 步骤4: 验证登录是否成功
# 等待登录后才会出现的元素,如图标或欢迎语
# 这里假设登录成功后,页面会出现一个ID为‘welcome’的元素
time.sleep(2) # 给页面跳转一点缓冲时间,实际应用中最好用等待条件替代
success_indicator = wait.until(
EC.visibility_of_element_located((By.ID, “welcome”))
)
# 简单的断言:如果成功元素存在且可见,则认为登录成功
if success_indicator.is_displayed():
print(“*** 登录成功! ***”)
# 可以在这里加入更复杂的验证,比如检查欢迎文本内容
# assert “欢迎” in success_indicator.text
else:
print(“!!! 登录失败,未找到成功标识。 !!!”)
# 步骤5: 登录后操作(示例:等待3秒后截图)
time.sleep(3)
driver.save_screenshot(“login_success.png”)
print(“已保存登录成功后的截图。”)
except Exception as e:
# 捕获任何异常,并截图保存,便于排查问题
print(f“脚本执行过程中发生错误: {e}”)
if driver:
driver.save_screenshot(“error_snapshot.png”)
print(“已保存错误时的页面截图。”)
finally:
# 无论成功与否,最后都关闭浏览器
if driver:
driver.quit()
print(“浏览器已关闭。”)
# 执行测试函数
if __name__ == “__main__”:
test_login()
逐行解析与设计逻辑:
- 函数封装 :将主要逻辑放在
test_login()函数中,使结构清晰,便于管理和复用。 - 异常处理(try-except-finally) :这是生产级脚本的必备结构。
try块中是主流程。except块捕获所有异常,并打印错误信息。 关键一步是保存出错时的页面截图 ,这对于远程调试或分析不可复现的Bug至关重要。finally块确保无论是否出错,浏览器驱动都会被正确关闭,避免残留进程占用资源。
- 智能等待贯穿始终 :在打开页面后、操作关键元素前,都使用了
WebDriverWait配合expected_conditions进行等待,极大提高了脚本的稳定性和容错能力。 - 操作与日志结合 :每个关键步骤后都使用
print()输出日志,方便运行时观察脚本执行到了哪一步。 - 验证点(断言) :登录后,通过等待和检查一个特定的成功元素(如欢迎语)来验证登录功能是否正常。这是自动化测试的“测试”部分,而不仅仅是“操作”部分。
- 截图功能 :使用
driver.save_screenshot()保存成功后的页面状态,作为执行证据。
4.2 从脚本到测试用例:参数化与数据驱动
上面的脚本将测试数据(用户名、密码)硬编码在代码里。这只能测试一组数据。真正的测试需要覆盖多种情况:正确账号、错误密码、空用户名、错误格式等。这就需要 数据驱动 。
一个简单的方法是将测试数据放到一个列表或字典中,然后循环执行:
test_data = [
{“username”: “correct_user”, “password”: “correct_pwd”, “expected”: “success”},
{“username”: “wrong_user”, “password”: “correct_pwd”, “expected”: “fail”},
{“username”: “correct_user”, “password”: “”, “expected”: “fail”},
{“username”: “”, “password”: “correct_pwd”, “expected”: “fail”},
]
def login_with_data(username, password):
# … 这里是之前的登录操作逻辑,但使用传入的username和password参数 …
username_box.send_keys(username)
password_box.send_keys(password)
# … 后续操作 …
# 根据expected判断验证逻辑
# if expected == “success”: 检查成功元素
# else: 检查错误提示元素
if __name__ == “__main__”:
for data in test_data:
print(f“正在测试用例: 用户名={data[‘username’]}, 密码={data[‘password’]}”)
# 注意:每次循环需要重启浏览器,或者做好登出清理,避免状态污染
test_login_with_data(data[‘username’], data[‘password’], data[‘expected’])
更进阶的做法是将测试数据存储在外部文件中,如JSON、YAML或Excel/CSV,然后由脚本读取。 pytest 这样的测试框架也提供了强大的参数化功能( @pytest.mark.parametrize ),非常适合管理多组测试数据。
4.3 页面对象模型(POM)设计模式初探
当测试场景变多,脚本会越来越臃肿,元素定位语句散落在各个函数里,难以维护。这时就需要引入 页面对象模型(Page Object Model, POM) 。POM是一种设计模式,将每个页面抽象成一个类,页面的元素定位和基本操作封装成类的方法。测试脚本只调用这些方法,不关心具体如何定位和操作。
例如,为登录页面创建一个类:
class LoginPage:
def __init__(self, driver):
self.driver = driver
self.wait = WebDriverWait(driver, 10)
# 元素定位器(Locators)
self.username_input = (By.ID, “user”)
self.password_input = (By.ID, “pass”)
self.login_button = (By.CLASS_NAME, “btn-login”)
self.welcome_text = (By.ID, “welcome”)
def enter_username(self, username):
element = self.wait.until(EC.visibility_of_element_located(self.username_input))
element.clear()
element.send_keys(username)
def enter_password(self, password):
element = self.driver.find_element(*self.password_input) # 注意这里的解包*
element.clear()
element.send_keys(password)
def click_login(self):
element = self.wait.until(EC.element_to_be_clickable(self.login_button))
element.click()
def get_welcome_message(self):
element = self.wait.until(EC.visibility_of_element_located(self.welcome_text))
return element.text
然后在测试脚本中,使用就非常清晰了:
def test_login_with_pom():
driver = webdriver.Chrome()
driver.get(“https://www.example.com/login”)
login_page = LoginPage(driver) # 初始化登录页面对象
login_page.enter_username(“test_user”)
login_page.enter_password(“test_pwd”)
login_page.click_login()
welcome_msg = login_page.get_welcome_message()
assert “欢迎” in welcome_msg
driver.quit()
POM极大地提高了代码的可读性、可维护性和复用性。当登录页面的输入框ID发生变化时,你只需要修改 LoginPage 类中的一处定位器即可,所有测试用例都不需要改动。
5. 常见问题排查与实战技巧
5.1 高频错误与解决方案速查表
在编写和运行Selenium脚本时,你几乎一定会遇到下面这些问题。这里我整理了一个速查表,附上原因分析和解决方案。
| 问题现象 | 可能原因 | 解决方案与排查步骤 |
|---|---|---|
WebDriverException: Message: ‘chromedriver’ executable needs to be in PATH |
1. 未下载ChromeDriver。 2. ChromeDriver未放在PATH路径。 3. ChromeDriver版本与Chrome浏览器不匹配。 |
1. 检查是否已下载对应版本的ChromeDriver。 2. 将ChromeDriver所在目录添加到系统环境变量PATH,或在代码中指定 executable_path 。 3. 核对浏览器和驱动版本号,必须匹配。 |
NoSuchElementException: Unable to locate element |
1. 元素定位表达式写错了。 2. 页面尚未加载完成,元素还不存在。 3. 元素在iframe或shadow DOM内。 4. 元素是动态生成的,ID/Class等属性每次刷新会变。 |
1. 用浏览器开发者工具复查定位表达式。 2. 在操作元素前增加显式等待( WebDriverWait )。 3. 使用 driver.switch_to.frame() 切换到iframe,或使用特殊方法处理shadow DOM。 4. 尝试使用更稳定的定位方式,如XPath通过相对路径或文本定位,CSS Selector通过属性组合定位。 |
ElementNotInteractableException: element not interactable |
1. 元素不可见(被遮挡、样式为 display:none 或 visibility:hidden )。 2. 元素未被渲染到可操作状态(如禁用状态)。 3. 另一个元素覆盖在了目标元素上。 |
1. 使用 EC.visibility_of_element_located 等待元素可见。 2. 检查元素是否有 disabled 属性,等待其变为可用( EC.element_to_be_clickable )。 3. 滚动元素到可视区域: driver.execute_script(“arguments[0].scrollIntoView();”, element) 。 4. 检查是否有弹窗、蒙层遮挡。 |
| 脚本在本地运行成功,但在服务器/CI环境失败 | 1. 服务器是无图形界面的(Headless)环境。 2. 浏览器或驱动版本不一致。 3. 屏幕分辨率不同导致元素位置变化。 |
1. 配置无头浏览器选项: options = webdriver.ChromeOptions(); options.add_argument(‘--headless’) 。 2. 在服务器环境也使用固定版本的浏览器和驱动,或使用Docker容器统一环境。 3. 设置固定的窗口大小: driver.set_window_size(1920, 1080) 。避免使用基于坐标的操作。 |
InvalidSelectorException |
提供的CSS Selector或XPath语法错误。 | 将你的定位表达式粘贴到浏览器开发者工具的Console中,用 document.querySelector() (CSS) 或 $x() (XPath) 测试是否能找到元素。 |
| 页面跳转后找不到元素 | 操作(如点击登录)导致页面刷新或跳转,但脚本立即去寻找新页面的元素,此时新页面可能还未加载。 | 在引发页面跳转的操作(如 click() )之后,增加一个针对新页面某个关键元素的显式等待。 |
5.2 高级定位技巧与调试手段
当常规定位方式失效时,你需要一些“武器库”里的高级技巧。
1. 使用相对XPath或CSS Selector避免依赖易变属性: 不要过度依赖自动生成的、冗长且易变的XPath(如 //*[@id=“j_id0:j_id1:j_id2:inputText1”] )。尝试使用更有语义的定位:
- 通过文本内容 :
//button[contains(text(), ‘登录’)] - 通过属性组合 :
input[name=‘username’][type=‘text’](CSS) - 通过父子/兄弟关系 :
//form[@id=‘loginForm’]//input[@type=‘password’]
2. 处理动态ID/Class: 如果元素的ID是类似 ‘user-12345’ 这样带随机后缀的,可以使用 starts-with 、 contains 或 ends-with 函数(XPath)或属性选择器(CSS)。
- XPath:
//input[starts-with(@id, ‘user-’)] - CSS:
input[id^=‘user-’](以‘user-’开头)
3. 处理iframe: 如果元素在 <iframe> 标签内,你必须先切换到对应的iframe框架,才能定位其中的元素。
# 通过ID或Name切换
driver.switch_to.frame(“iframe_id_or_name”)
# 定位并操作iframe内的元素...
# 操作完成后,切回主页面
driver.switch_to.default_content()
4. 强大的调试工具: driver.page_source 和截图 当页面元素异常,在开发者工具里能看到但在脚本中找不到时,可以将当前页面的HTML结构保存下来分析。
with open(“page_dump.html”, “w”, encoding=“utf-8”) as f:
f.write(driver.page_source)
print(“当前页面源码已保存。”)
结合出错时的截图 ( driver.save_screenshot(‘debug.png’) ),你可以清晰地看到脚本“眼中”的页面是什么样子,这对于排查动态加载、渲染差异问题非常有效。
5.3 提升脚本稳定性的工程化思考
一个能跑起来的脚本和一个能在团队中、在CI/CD流水线上稳定运行的脚本,中间隔着工程化的距离。
1. 配置管理: 不要将URL、账号密码、等待超时时间等硬编码在脚本中。应该使用配置文件(如 config.ini 、 config.yaml )或环境变量来管理。例如:
import os
from dotenv import load_dotenv # 可以使用python-dotenv库
load_dotenv() # 从 .env 文件加载环境变量
LOGIN_URL = os.getenv(“LOGIN_URL”, “https://default.example.com/login”)
TEST_USER = os.getenv(“TEST_USER”)
TEST_PASS = os.getenv(“TEST_PASS”)
IMPLICIT_WAIT = int(os.getenv(“IMPLICIT_WAIT”, “10”))
2. 日志记录: 用 print() 只是初级阶段。应该使用Python内置的 logging 模块,可以方便地控制日志级别(DEBUG, INFO, WARNING, ERROR)、输出到文件、并格式化日志信息。
import logging
logging.basicConfig(level=logging.INFO,
format=‘%(asctime)s - %(name)s - %(levelname)s - %(message)s’)
logger = logging.getLogger(__name__)
logger.info(“正在访问登录页面…”)
3. 集成测试框架: 将你的脚本函数改造成 pytest 或 unittest 的测试用例。这样可以利用框架提供的测试发现、夹具(Fixture,如 setup / teardown )、参数化、断言和丰富的报告插件。
# 使用pytest示例
import pytest
class TestLogin:
@pytest.fixture(scope=“function”)
def driver(self):
d = webdriver.Chrome()
yield d
d.quit()
def test_valid_login(self, driver):
driver.get(LOGIN_URL)
# … 调用POM页面对象进行登录操作 …
assert “欢迎” in login_page.get_welcome_message()
4. 持续集成(CI): 将你的自动化测试脚本提交到Git仓库,并配置CI工具(如Jenkins, GitLab CI, GitHub Actions)。每次代码提交或定时任务,CI会自动拉取代码、安装依赖、执行测试并生成报告。这才是UI自动化测试价值最大化的地方——持续守护产品质量。
从一行代码开始,到一个稳定的、可维护的、可集成的自动化测试用例,这个过程本身就是一次微型的软件工程实践。它锻炼的不仅仅是Selenium API的调用,更是你的编程思维、设计模式和工程化能力。希望这个从零开始的登录UI自动化脚本,能成为你打开自动化测试大门的第一把钥匙。
更多推荐
所有评论(0)