本文目录导读:

我来为您提供几个常见的Selenium自动化测试案例,涵盖不同场景:
基础Web自动化测试案例
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
class BasicTest:
def __init__(self):
self.driver = webdriver.Chrome() # 或者使用其他浏览器
self.driver.maximize_window()
self.driver.implicitly_wait(10)
def test_login(self):
"""登录测试"""
try:
# 1. 打开登录页面
self.driver.get("https://example.com/login")
# 2. 输入用户名和密码
username = self.driver.find_element(By.ID, "username")
password = self.driver.find_element(By.ID, "password")
username.send_keys("testuser")
password.send_keys("test123")
# 3. 点击登录按钮
login_btn = self.driver.find_element(By.XPATH, "//button[@type='submit']")
login_btn.click()
# 4. 等待登录成功后的页面加载
WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "welcome"))
)
# 5. 验证登录成功
welcome_text = self.driver.find_element(By.CLASS_NAME, "welcome").text
assert "欢迎" in welcome_text
print("登录测试通过!")
except Exception as e:
print(f"登录测试失败:{e}")
self.take_screenshot("login_failure")
finally:
self.cleanup()
def take_screenshot(self, name):
"""截图"""
timestamp = time.strftime("%Y%m%d_%H%M%S")
self.driver.save_screenshot(f"{name}_{timestamp}.png")
def cleanup(self):
"""清理资源"""
self.driver.quit()
# 运行测试
if __name__ == "__main__":
test = BasicTest()
test.test_login()
数据驱动测试案例
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 pandas as pd
import pytest
from datetime import datetime
class DataDrivenTest:
"""数据驱动测试"""
def __init__(self):
self.driver = None
@pytest.fixture
def setup(self):
"""初始化浏览器"""
self.driver = webdriver.Chrome()
self.driver.maximize_window()
yield
self.driver.quit()
@pytest.mark.parametrize("test_data", [
{"username": "user1", "password": "pass1", "expected": "登录成功"},
{"username": "user2", "password": "wrong", "expected": "密码错误"},
{"username": "", "password": "", "expected": "请输入用户名"}
])
def test_login_scenarios(self, setup, test_data):
"""多场景登录测试"""
self.driver.get("https://example.com/login")
# 输入测试数据
username = self.driver.find_element(By.ID, "username")
password = self.driver.find_element(By.ID, "password")
username.clear()
username.send_keys(test_data["username"])
password.clear()
password.send_keys(test_data["password"])
# 点击登录
login_btn = self.driver.find_element(By.XPATH, "//button[@type='submit']")
login_btn.click()
# 验证结果
if test_data["expected"]:
result = self.driver.find_element(By.CLASS_NAME, "message").text
assert test_data["expected"] in result
def test_from_csv(self, setup):
"""从CSV文件读取测试数据"""
df = pd.read_csv('test_data.csv')
for index, row in df.iterrows():
self.driver.get("https://example.com/search")
search_box = self.driver.find_element(By.NAME, "search")
search_box.clear()
search_box.send_keys(row['keyword'])
search_btn = self.driver.find_element(By.CLASS_NAME, "search-btn")
search_btn.click()
# 验证搜索结果
result_count = self.driver.find_element(By.CLASS_NAME, "result-count").text
assert int(result_count) >= row['min_results']
print(f"测试用例 {index+1}: {row['keyword']} - 通过")
页面对象模式(POM)案例
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
from abc import ABC, abstractmethod
# 基础页面类
class BasePage(ABC):
def __init__(self, driver):
self.driver = driver
self.wait = WebDriverWait(driver, 10)
@abstractmethod
def is_loaded(self):
"""检查页面是否加载完成"""
pass
def find_element(self, *locator):
"""查找元素"""
return self.driver.find_element(*locator)
def find_elements(self, *locator):
"""查找多个元素"""
return self.driver.find_elements(*locator)
# 登录页面
class LoginPage(BasePage):
# 页面元素定位器
USERNAME_INPUT = (By.ID, "username")
PASSWORD_INPUT = (By.ID, "password")
LOGIN_BUTTON = (By.XPATH, "//button[@type='submit']")
ERROR_MESSAGE = (By.CLASS_NAME, "error-message")
def __init__(self, driver):
super().__init__(driver)
self.url = "https://example.com/login"
def is_loaded(self):
"""检查登录页面是否加载"""
return self.driver.current_url == self.url
def login(self, username, password):
"""登录操作"""
self.find_element(*self.USERNAME_INPUT).send_keys(username)
self.find_element(*self.PASSWORD_INPUT).send_keys(password)
self.find_element(*self.LOGIN_BUTTON).click()
# 等待页面跳转
self.wait.until(EC.url_changes(self.url))
def get_error_message(self):
"""获取错误信息"""
return self.find_element(*self.ERROR_MESSAGE).text
# 搜索页面
class SearchPage(BasePage):
SEARCH_INPUT = (By.NAME, "search")
SEARCH_BUTTON = (By.CLASS_NAME, "search-btn")
RESULTS = (By.CLASS_NAME, "search-result")
NO_RESULTS = (By.CLASS_NAME, "no-results")
def __init__(self, driver):
super().__init__(driver)
self.url = "https://example.com/search"
def is_loaded(self):
"""检查搜索页面是否加载"""
return self.driver.current_url.startswith(self.url)
def search(self, keyword):
"""执行搜索"""
search_input = self.find_element(*self.SEARCH_INPUT)
search_input.clear()
search_input.send_keys(keyword)
self.find_element(*self.SEARCH_BUTTON).click()
def get_results_count(self):
"""获取搜索结果数量"""
results = self.find_elements(*self.RESULTS)
return len(results)
def has_no_results(self):
"""是否无结果"""
try:
return self.find_element(*self.NO_RESULTS).is_displayed()
except:
return False
# 测试执行类
class TestWithPOM:
def __init__(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
def test_login_and_search(self):
"""测试登录和搜索功能"""
try:
# 1. 加载登录页面
login_page = LoginPage(self.driver)
self.driver.get(login_page.url)
assert login_page.is_loaded()
# 2. 执行登录
login_page.login("user1", "password123")
# 3. 进入搜索页面
search_page = SearchPage(self.driver)
self.driver.get(search_page.url)
assert search_page.is_loaded()
# 4. 执行搜索
search_page.search("Python自动化")
# 5. 验证结果
count = search_page.get_results_count()
assert count > 0, f"搜索结果应为正数,实际为{count}"
print(f"搜索成功,共有{count}条结果")
except Exception as e:
print(f"测试失败:{e}")
raise
finally:
self.driver.quit()
等待策略案例
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
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import time
class WaitStrategyTest:
def __init__(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
def test_different_waits(self):
"""测试不同的等待方式"""
try:
# 1. 隐式等待 - 对所有find_element有效
self.driver.implicitly_wait(5)
# 2. 显式等待 - 特定条件
element = WebDriverWait(self.driver, 10).until(
EC.element_to_be_clickable((By.ID, "dynamic-button"))
)
# 3. 等待特定文本
WebDriverWait(self.driver, 15).until(
EC.text_to_be_present_in_element(
(By.CLASS_NAME, "status"),
"处理完成"
)
)
# 4. 等待元素消失
WebDriverWait(self.driver, 10).until(
EC.invisibility_of_element_located((By.ID, "loading"))
)
# 5. 组合条件
WebDriverWait(self.driver, 10).until(
EC.all_of(
EC.presence_of_element_located((By.CLASS_NAME, "content")),
EC.visibility_of_element_located((By.CLASS_NAME, "content")),
EC.element_to_be_clickable((By.ID, "submit"))
)
)
except TimeoutException as e:
print(f"等待超时:{e}")
except NoSuchElementException as e:
print(f"元素未找到:{e}")
finally:
self.cleanup()
def test_custom_wait(self):
"""自定义等待条件"""
def element_text_not_empty(driver):
element = driver.find_element(By.ID, "dynamic-text")
return element.text if element.text.strip() else None
try:
# 自定义等待函数
text = WebDriverWait(self.driver, 10).until(
element_text_not_empty
)
print(f"获取到文本:{text}")
except TimeoutException:
print("等待超时,文本始终为空")
finally:
self.cleanup()
def cleanup(self):
"""清理资源"""
self.driver.quit()
文件上传下载案例
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
import os
import time
class FileHandlingTest:
def __init__(self):
options = webdriver.ChromeOptions()
# 设置下载目录
download_dir = os.path.join(os.getcwd(), "downloads")
os.makedirs(download_dir, exist_ok=True)
prefs = {
"download.default_directory": download_dir,
"download.prompt_for_download": False,
"download.directory_upgrade": True,
"safebrowsing.enabled": True
}
options.add_experimental_option("prefs", prefs)
self.driver = webdriver.Chrome(options=options)
self.driver.maximize_window()
def test_file_upload(self, file_path):
"""文件上传测试"""
try:
self.driver.get("https://example.com/upload")
# 使用send_keys直接上传文件
file_input = self.driver.find_element(By.ID, "file-upload")
file_input.send_keys(file_path) # 直接传入文件路径
# 或使用文件上传组件
upload_area = self.driver.find_element(By.CLASS_NAME, "upload-area")
# 模拟拖拽文件
actions = ActionChains(self.driver)
actions.click_and_hold(file_input)
actions.move_to_element(upload_area)
actions.release()
actions.perform()
# 点击上传按钮
upload_btn = self.driver.find_element(By.ID, "upload-btn")
upload_btn.click()
# 等待上传完成
time.sleep(3)
status = self.driver.find_element(By.CLASS_NAME, "status").text
assert "上传成功" in status
print("文件上传成功!")
except Exception as e:
print(f"文件上传失败:{e}")
def test_file_download(self):
"""文件下载测试"""
try:
self.driver.get("https://example.com/download")
download_btn = self.driver.find_element(By.ID, "download-file")
download_btn.click()
# 等待下载完成
time.sleep(5)
# 检查文件是否下载成功
download_dir = os.path.join(os.getcwd(), "downloads")
files = os.listdir(download_dir)
assert len(files) > 0, "没有文件被下载"
recent_file = max(
[os.path.join(download_dir, f) for f in files],
key=os.path.getmtime
)
file_size = os.path.getsize(recent_file)
assert file_size > 0, "下载的文件为空"
print(f"文件下载成功:{os.path.basename(recent_file)},大小:{file_size} 字节")
except Exception as e:
print(f"文件下载失败:{e}")
finally:
self.cleanup()
def cleanup(self):
self.driver.quit()
截图和报告案例
from selenium import webdriver
from selenium.webdriver.common.by import By
from datetime import datetime
import os
import logging
import json
class ScreenshotReporter:
def __init__(self, driver):
self.driver = driver
self.results = []
self.setup_logging()
def setup_logging(self):
"""配置日志"""
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('test_report.log'),
logging.StreamHandler()
]
)
self.logger = logging.getLogger(__name__)
def take_screenshot(self, name):
"""截图并保存"""
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"screenshots/{name}_{timestamp}.png"
os.makedirs("screenshots", exist_ok=True)
self.driver.save_screenshot(filename)
self.logger.info(f"截图保存: {filename}")
return filename
def take_element_screenshot(self, locator, name):
"""元素截图"""
try:
element = self.driver.find_element(*locator)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"screenshots/{name}_{timestamp}.png"
os.makedirs("screenshots", exist_ok=True)
element.screenshot(filename)
self.logger.info(f"元素截图保存: {filename}")
return filename
except Exception as e:
self.logger.error(f"元素截图失败: {e}")
return None
def record_result(self, test_name, status, message="", screenshot=None):
"""记录测试结果"""
result = {
"timestamp": datetime.now().isoformat(),
"test_name": test_name,
"status": status,
"message": message,
"screenshot": screenshot
}
self.results.append(result)
self.logger.info(f"测试{item['test_name']}: {item['status']} - {item['message']}")
def generate_report(self):
"""生成HTML报告"""
report_name = f"report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html"
html = """
<html>
<head>
<title>测试报告</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.pass { color: green; }
.fail { color: red; }
.skip { color: yellow; }
.test-result { margin: 10px 0; padding: 10px; border: 1px solid #ccc; }
.header { background-color: #f0f0f0; padding: 10px; }
table { border-collapse: collapse; width: 100%%; }
td, th { border: 1px solid #ddd; padding: 8px; text-align: left; }
</style>
</head>
<body>
<div class="header">
<h1>自动化测试报告</h1>
<p>报告生成时间: %s</p>
<p>总测试数: %d, 通过: %d, 失败: %d</p>
</div>
<table>
<tr><th>时间</th><th>测试名称</th><th>状态</th><th>消息</th><th>截图</th></tr>
""" % (
datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
len(self.results),
sum(1 for r in self.results if r["status"] == "PASS"),
sum(1 for r in self.results if r["status"] == "FAIL")
)
for result in self.results:
status_class = result["status"].lower()
screenshot_tag = ""
if result["screenshot"]:
screenshot_tag = f'<a href="{result["screenshot"]}" target="_blank">查看</a>'
html += f"""
<tr>
<td>{result["timestamp"]}</td>
<td>{result["test_name"]}</td>
<td class="{status_class}">{result["status"]}</td>
<td>{result["message"]}</td>
<td>{screenshot_tag}</td>
</tr>
"""
html += """
</table>
</body>
</html>
"""
with open(report_name, "w", encoding="utf-8") as f:
f.write(html)
self.logger.info(f"测试报告生成: {report_name}")
return report_name
# 使用示例
def test_with_reporter():
driver = webdriver.Chrome()
reporter = ScreenshotReporter(driver)
try:
# 测试场景1
driver.get("https://example.com")
if "Example" in driver.title:
reporter.record_result("页面标题检查", "PASS", "标题正确")
else:
screenshot = reporter.take_screenshot("title_check")
reporter.record_result("页面标题检查", "FAIL", "标题不正确", screenshot)
# 测试场景2
try:
element = driver.find_element(By.ID, "non-existent")
reporter.record_result("元素查找", "PASS", "元素存在")
except Exception as e:
screenshot = reporter.take_screenshot("element_not_found")
reporter.record_result("元素查找", "FAIL", f"元素不存在: {e}", screenshot)
# 生成报告
report_file = reporter.generate_report()
print(f"测试完成,报告已生成: {report_file}")
finally:
driver.quit()
这些案例覆盖了Selenium最常见的应用场景,根据您的实际需求,可以选择合适的案例进行学习和使用,每个案例都包含了详细的注释,便于理解和扩展。