登录页面自动化测试综合案例
期末考试高频题型:登录页面自动化测试是编程题的经典考点,必须掌握完整的测试流程、异常处理和页面截图技术。
考试题型分析
典型题目要求
- 基础要求:实现用户登录功能的自动化测试
- 元素定位:正确定位用户名输入框(id="user")、密码输入框(id="pwd")、登录按钮(id="login")
- 测试场景:正确登录、错误凭据、空字段等多种场景
- 异常处理:捕获并处理各种异常情况
- 结果验证:验证登录成功或失败的提示信息
- 页面截图:失败时自动保存错误截图
标准解题模板
基础登录测试类
Python
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 logging
import time
from datetime import datetime
class LoginAutomationTest:
"""登录页面自动化测试标准实现"""
def __init__(self, base_url="https://example.com/login"):
"""初始化测试环境"""
self.base_url = base_url
self.driver = None
self.wait = None
self._setup_logging()
self._init_driver()
def _setup_logging(self):
"""配置日志系统"""
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(),
logging.FileHandler(f'login_test_{datetime.now().strftime("%Y%m%d_%H%M%S")}.log', encoding='utf-8')
]
)
self.logger = logging.getLogger(self.__class__.__name__)
def _init_driver(self):
"""初始化WebDriver"""
try:
self.driver = webdriver.Chrome()
self.wait = WebDriverWait(self.driver, 10)
self.logger.info("WebDriver初始化成功")
except Exception as e:
self.logger.critical(f"WebDriver初始化失败:{e}")
raise
def open_login_page(self):
"""打开登录页面"""
try:
self.logger.info(f"导航到登录页面:{self.base_url}")
self.driver.get(self.base_url)
# 验证页面加载
self.wait.until(EC.presence_of_element_located((By.ID, "user")))
self.logger.info("登录页面加载成功")
except Exception as e:
self.logger.error(f"登录页面加载失败:{e}")
self._save_screenshot("page_load_error")
raise
def perform_login(self, username, password):
"""执行登录操作"""
try:
self.logger.info(f"开始登录操作,用户名:{username}")
# 1. 定位并输入用户名
username_field = self.wait.until(
EC.element_to_be_clickable((By.ID, "user"))
)
username_field.clear()
username_field.send_keys(username)
self.logger.debug("用户名输入完成")
# 2. 定位并输入密码
password_field = self.driver.find_element(By.ID, "pwd")
password_field.clear()
password_field.send_keys(password)
self.logger.debug("密码输入完成")
# 3. 点击登录按钮
login_button = self.driver.find_element(By.ID, "login")
login_button.click()
self.logger.info("登录按钮点击完成")
# 4. 等待页面响应
time.sleep(2)
except Exception as e:
self.logger.error(f"登录操作执行失败:{e}")
self._save_screenshot("login_operation_error")
raise
def verify_login_success(self):
"""验证登录成功"""
try:
# 方法1:检查成功元素
success_element = self.wait.until(
EC.presence_of_element_located((By.CLASS_NAME, "welcome"))
)
success_message = success_element.text
if "欢迎" in success_message:
self.logger.info("登录成功验证通过")
return True
else:
self.logger.warning(f"成功页面文本异常:{success_message}")
return False
except Exception:
# 方法2:检查URL变化
current_url = self.driver.current_url
if "dashboard" in current_url or "home" in current_url:
self.logger.info("通过URL变化验证登录成功")
return True
self.logger.error("登录成功验证失败")
return False
def verify_login_failure(self, expected_error_text="用户名或密码错误"):
"""验证登录失败"""
try:
error_element = self.wait.until(
EC.presence_of_element_located((By.CLASS_NAME, "error"))
)
error_message = error_element.text
if expected_error_text in error_message:
self.logger.info(f"登录失败验证通过:{error_message}")
return True
else:
self.logger.warning(f"错误信息不符合预期:{error_message}")
return False
except Exception as e:
self.logger.error(f"登录失败验证异常:{e}")
self._save_screenshot("login_failure_verify_error")
return False
def _save_screenshot(self, scenario):
"""保存错误截图"""
try:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
screenshot_path = f"screenshot_{scenario}_{timestamp}.png"
self.driver.save_screenshot(screenshot_path)
self.logger.info(f"截图已保存:{screenshot_path}")
except Exception as e:
self.logger.error(f"截图保存失败:{e}")
def cleanup(self):
"""清理资源"""
if self.driver:
self.driver.quit()
self.logger.info("WebDriver已关闭")
# 使用示例
def main():
"""主测试函数"""
test = LoginAutomationTest()
try:
# 测试场景1:正确登录
test.open_login_page()
test.perform_login("testuser", "testpass")
if test.verify_login_success():
print("✅ 正确登录测试通过")
else:
print("❌ 正确登录测试失败")
except Exception as e:
print(f"❌ 测试执行异常:{e}")
finally:
test.cleanup()
if __name__ == "__main__":
main()
多场景测试实现
完整测试套件
Python
import unittest
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 logging
from datetime import datetime
class LoginTestSuite(unittest.TestCase):
"""登录功能完整测试套件"""
@classmethod
def setUpClass(cls):
"""测试类初始化"""
cls._setup_logging()
cls.base_url = "https://example.com/login"
cls.driver = webdriver.Chrome()
cls.wait = WebDriverWait(cls.driver, 10)
cls.logger.info("="*60)
cls.logger.info("开始执行登录功能测试套件")
@classmethod
def _setup_logging(cls):
"""配置日志"""
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(),
logging.FileHandler(f'login_suite_{datetime.now().strftime("%Y%m%d_%H%M%S")}.log', encoding='utf-8')
]
)
cls.logger = logging.getLogger(cls.__name__)
def setUp(self):
"""每个测试用例前的准备"""
self.logger.info(f"开始执行测试用例:{self._testMethodName}")
self.driver.get(self.base_url)
# 等待页面加载
try:
self.wait.until(EC.presence_of_element_located((By.ID, "user")))
except Exception as e:
self.logger.error(f"页面加载失败:{e}")
self._save_screenshot("page_load_failed")
raise
def tearDown(self):
"""每个测试用例后的清理"""
if hasattr(self, '_outcome'):
if self._outcome.errors or self._outcome.failures:
self.logger.error(f"测试用例失败:{self._testMethodName}")
self._save_screenshot(f"test_failed_{self._testMethodName}")
else:
self.logger.info(f"测试用例通过:{self._testMethodName}")
@classmethod
def tearDownClass(cls):
"""测试类清理"""
cls.driver.quit()
cls.logger.info("登录功能测试套件执行完成")
cls.logger.info("="*60)
def _perform_login(self, username, password):
"""登录操作的公共方法"""
try:
# 输入用户名
username_field = self.wait.until(
EC.element_to_be_clickable((By.ID, "user"))
)
username_field.clear()
username_field.send_keys(username)
# 输入密码
password_field = self.driver.find_element(By.ID, "pwd")
password_field.clear()
password_field.send_keys(password)
# 点击登录按钮
login_button = self.driver.find_element(By.ID, "login")
login_button.click()
self.logger.debug(f"登录操作完成 - 用户名:{username}")
except Exception as e:
self.logger.error(f"登录操作失败:{e}")
raise
def _save_screenshot(self, scenario):
"""保存截图"""
try:
timestamp = datetime.now().strftime("%H%M%S")
screenshot_path = f"screenshot_{scenario}_{timestamp}.png"
self.driver.save_screenshot(screenshot_path)
self.logger.info(f"截图已保存:{screenshot_path}")
except Exception as e:
self.logger.error(f"截图保存失败:{e}")
def test_01_valid_login(self):
"""测试用例1:有效用户名和密码登录"""
self._perform_login("testuser", "testpass")
# 验证登录成功
try:
success_element = self.wait.until(
EC.presence_of_element_located((By.CLASS_NAME, "welcome"))
)
self.assertIn("欢迎", success_element.text, "登录成功页面验证失败")
self.logger.info("有效登录测试通过")
except Exception as e:
self.logger.error(f"登录成功验证失败:{e}")
self.fail("登录成功验证失败")
def test_02_invalid_username(self):
"""测试用例2:无效用户名登录"""
self._perform_login("invaliduser", "testpass")
# 验证错误提示
try:
error_element = self.wait.until(
EC.presence_of_element_located((By.CLASS_NAME, "error"))
)
self.assertIn("用户名或密码错误", error_element.text, "错误提示信息验证失败")
self.logger.info("无效用户名测试通过")
except Exception as e:
self.logger.error(f"错误提示验证失败:{e}")
self.fail("错误提示验证失败")
def test_03_invalid_password(self):
"""测试用例3:无效密码登录"""
self._perform_login("testuser", "wrongpass")
# 验证错误提示
try:
error_element = self.wait.until(
EC.presence_of_element_located((By.CLASS_NAME, "error"))
)
self.assertIn("用户名或密码错误", error_element.text, "错误提示信息验证失败")
self.logger.info("无效密码测试通过")
except Exception as e:
self.logger.error(f"错误提示验证失败:{e}")
self.fail("错误提示验证失败")
def test_04_empty_username(self):
"""测试用例4:空用户名登录"""
self._perform_login("", "testpass")
# 验证提示信息
try:
error_element = self.wait.until(
EC.presence_of_element_located((By.CLASS_NAME, "error"))
)
error_text = error_element.text
self.assertTrue(
"请输入用户名" in error_text or "用户名不能为空" in error_text,
f"空用户名提示信息不正确:{error_text}"
)
self.logger.info("空用户名测试通过")
except Exception as e:
self.logger.error(f"空用户名验证失败:{e}")
self.fail("空用户名验证失败")
def test_05_empty_password(self):
"""测试用例5:空密码登录"""
self._perform_login("testuser", "")
# 验证提示信息
try:
error_element = self.wait.until(
EC.presence_of_element_located((By.CLASS_NAME, "error"))
)
error_text = error_element.text
self.assertTrue(
"请输入密码" in error_text or "密码不能为空" in error_text,
f"空密码提示信息不正确:{error_text}"
)
self.logger.info("空密码测试通过")
except Exception as e:
self.logger.error(f"空密码验证失败:{e}")
self.fail("空密码验证失败")
def test_06_empty_both_fields(self):
"""测试用例6:用户名和密码都为空"""
self._perform_login("", "")
# 验证提示信息
try:
error_element = self.wait.until(
EC.presence_of_element_located((By.CLASS_NAME, "error"))
)
error_text = error_element.text
self.assertTrue(
"请输入用户名和密码" in error_text or "用户名和密码不能为空" in error_text,
f"空字段提示信息不正确:{error_text}"
)
self.logger.info("空字段测试通过")
except Exception as e:
self.logger.error(f"空字段验证失败:{e}")
self.fail("空字段验证失败")
# 执行测试套件
if __name__ == "__main__":
# 创建测试套件
suite = unittest.TestLoader().loadTestsFromTestCase(LoginTestSuite)
# 执行测试
runner = unittest.TextTestRunner(verbosity=2)
result = runner.run(suite)
# 输出测试结果摘要
print("\n" + "="*60)
print("测试结果摘要")
print("="*60)
print(f"执行测试用例数:{result.testsRun}")
print(f"成功:{result.testsRun - len(result.failures) - len(result.errors)}")
print(f"失败:{len(result.failures)}")
print(f"错误:{len(result.errors)}")
print("="*60)
高级特性实现
带有浏览器导航验证的登录测试
Python
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 logging
import time
class AdvancedLoginTest:
"""高级登录测试 - 包含浏览器导航和状态验证"""
def __init__(self):
self.driver = webdriver.Chrome()
self.wait = WebDriverWait(self.driver, 10)
self.logger = logging.getLogger(self.__class__.__name__)
logging.basicConfig(level=logging.INFO)
def test_login_with_navigation_verification(self):
"""登录测试 - 包含完整的导航和状态验证"""
try:
self.logger.info("开始执行高级登录测试")
# 1. 记录初始状态
initial_url = None
self.logger.info("记录浏览器初始状态")
# 2. 导航到登录页面
login_url = "https://example.com/login"
self.logger.info(f"导航到登录页面:{login_url}")
self.driver.get(login_url)
# 验证页面标题
expected_title = "用户登录"
actual_title = self.driver.title
assert expected_title in actual_title, f"页面标题验证失败,期望包含:{expected_title},实际:{actual_title}"
self.logger.info(f"页面标题验证通过:{actual_title}")
# 3. 验证页面元素存在
self._verify_login_page_elements()
# 4. 执行登录操作
self._perform_login_operation("testuser", "testpass")
# 5. 验证登录后的页面状态
self._verify_post_login_state()
# 6. 验证浏览器导航功能
self._verify_browser_navigation()
self.logger.info("高级登录测试执行成功")
except Exception as e:
self.logger.error(f"高级登录测试失败:{e}")
self._save_error_screenshot("advanced_login_test_failed")
raise
finally:
self.driver.quit()
def _verify_login_page_elements(self):
"""验证登录页面元素"""
self.logger.info("验证登录页面元素")
elements_to_check = [
("user", "用户名输入框"),
("pwd", "密码输入框"),
("login", "登录按钮")
]
for element_id, description in elements_to_check:
try:
element = self.wait.until(
EC.presence_of_element_located((By.ID, element_id))
)
assert element.is_displayed(), f"{description}不可见"
self.logger.debug(f"{description}验证通过")
except Exception as e:
self.logger.error(f"{description}验证失败:{e}")
raise
def _perform_login_operation(self, username, password):
"""执行登录操作"""
self.logger.info(f"执行登录操作 - 用户名:{username}")
# 记录登录前的URL
pre_login_url = self.driver.current_url
self.logger.debug(f"登录前URL:{pre_login_url}")
# 输入凭据
username_field = self.driver.find_element(By.ID, "user")
password_field = self.driver.find_element(By.ID, "pwd")
login_button = self.driver.find_element(By.ID, "login")
username_field.clear()
username_field.send_keys(username)
self.logger.debug("用户名输入完成")
password_field.clear()
password_field.send_keys(password)
self.logger.debug("密码输入完成")
# 点击登录按钮前记录时间
start_time = time.time()
login_button.click()
self.logger.debug("登录按钮已点击")
# 等待页面响应
self.wait.until(EC.url_changes(pre_login_url))
end_time = time.time()
response_time = end_time - start_time
self.logger.info(f"登录响应时间:{response_time:.2f}秒")
if response_time > 3:
self.logger.warning("登录响应时间较长")
def _verify_post_login_state(self):
"""验证登录后的状态"""
self.logger.info("验证登录后状态")
# 验证URL变化
current_url = self.driver.current_url
self.logger.debug(f"登录后URL:{current_url}")
expected_urls = ["dashboard", "home", "main", "index"]
url_valid = any(expected in current_url for expected in expected_urls)
assert url_valid, f"登录后URL异常:{current_url}"
# 验证页面标题变化
new_title = self.driver.title
self.logger.debug(f"登录后页面标题:{new_title}")
# 验证成功提示或欢迎信息
try:
welcome_elements = self.driver.find_elements(By.CLASS_NAME, "welcome")
if welcome_elements:
welcome_text = welcome_elements[0].text
self.logger.info(f"欢迎信息:{welcome_text}")
assert "欢迎" in welcome_text or "Welcome" in welcome_text
except Exception:
# 如果没有欢迎信息,验证用户信息显示
user_info = self.driver.find_elements(By.CLASS_NAME, "user-info")
assert len(user_info) > 0, "登录后未找到用户信息显示"
self.logger.info("登录后状态验证通过")
def _verify_browser_navigation(self):
"""验证浏览器导航功能"""
self.logger.info("验证浏览器导航功能")
# 记录当前页面
current_url = self.driver.current_url
current_title = self.driver.title
# 测试后退功能
self.logger.debug("测试浏览器后退功能")
self.driver.back()
time.sleep(1)
back_url = self.driver.current_url
self.logger.debug(f"后退后URL:{back_url}")
# 测试前进功能
self.logger.debug("测试浏览器前进功能")
self.driver.forward()
time.sleep(1)
forward_url = self.driver.current_url
forward_title = self.driver.title
# 验证前进后回到原页面
assert forward_url == current_url, f"前进功能异常,期望:{current_url},实际:{forward_url}"
assert forward_title == current_title, f"前进后标题异常,期望:{current_title},实际:{forward_title}"
# 测试刷新功能
self.logger.debug("测试页面刷新功能")
self.driver.refresh()
time.sleep(2)
refresh_url = self.driver.current_url
assert refresh_url == current_url, f"刷新后URL异常,期望:{current_url},实际:{refresh_url}"
self.logger.info("浏览器导航功能验证通过")
def _save_error_screenshot(self, scenario):
"""保存错误截图"""
try:
timestamp = time.strftime("%Y%m%d_%H%M%S")
screenshot_path = f"error_{scenario}_{timestamp}.png"
self.driver.save_screenshot(screenshot_path)
self.logger.error(f"错误截图已保存:{screenshot_path}")
except Exception as e:
self.logger.error(f"截图保存失败:{e}")
# 执行高级测试
if __name__ == "__main__":
test = AdvancedLoginTest()
test.test_login_with_navigation_verification()
考试答题要点
关键技术点总结
- WebDriver初始化:正确配置Chrome驱动
- 元素定位:使用准确的定位策略(ID优先)
- 显式等待:使用WebDriverWait确保元素可用
- 异常处理:全面的try-catch异常捕获
- 日志记录:完整的操作日志和错误记录
- 截图功能:失败时自动保存页面截图
- 结果验证:多种验证方法确保测试准确性
- 资源清理:确保WebDriver正确关闭
常见考试陷阱
- 忘记等待页面加载:直接操作元素导致失败
- 异常处理不完善:没有捕获所有可能的异常
- 验证逻辑不全面:只验证成功情况,忽略失败场景
- 资源泄露:没有正确关闭WebDriver
- 日志信息不足:缺少关键操作的日志记录
通过掌握这个综合案例,您可以应对各种登录页面自动化测试的编程题要求。