"""登录功能测试用例。 覆盖正常登录、异常登录、表单校验等场景。 按 ui_automation_best_practices.md §6.3 的范本结构编写。 标记: pytest -m web # 仅执行 Web 用例 pytest -m p0 # 仅执行 P0 冒烟 pytest -m smoke # 仅执行冒烟 """ import pytest from playwright.sync_api import Page from tests.web.pages.login_page import LoginPage pytestmark = [pytest.mark.web] # ═══════════════════════════════════════════════════════════════════ # P0 — 冒烟测试 # ═══════════════════════════════════════════════════════════════════ class TestLoginSuccess: """正常登录流程。""" @pytest.mark.p0 @pytest.mark.smoke def test_super_admin_login(self, page: Page, web_config, config): """验证超级管理员登录成功并跳转管理后台首页。""" account = config["accounts"]["super_admin"] login_page = LoginPage(page) page.goto(web_config["base_url"]) login_page.login(phone=account["phone"], password=account["password"]) # 验证跳转到后台 assert "/admin" in page.url, f"登录后应跳转到后台,实际 URL: {page.url}" @pytest.mark.p0 @pytest.mark.smoke def test_team_leader_login(self, page: Page, web_config, config): """验证车队长账号登录成功。""" account = config["accounts"]["team_leader"] login_page = LoginPage(page) page.goto(web_config["base_url"]) login_page.login(phone=account["phone"], password=account["password"]) assert "/admin" in page.url # ═══════════════════════════════════════════════════════════════════ # P1 — 异常与校验 # ═══════════════════════════════════════════════════════════════════ class TestLoginValidation: """登录表单校验。""" @pytest.mark.p1 @pytest.mark.parametrize("phone,password,expected_text", [ pytest.param("", "Test123456", "请输入用户名", id="empty_username"), pytest.param("super_admin", "", "请输入密码", id="empty_password"), pytest.param("super_admin", "wrong_password", "密码错误", id="wrong_password"), pytest.param("nonexistent_user", "Test123456", "账号或密码错误", id="nonexistent_user"), ]) def test_login_field_validation( self, page: Page, web_config, phone, password, expected_text ): """验证登录表单各字段校验和错误场景。""" login_page = LoginPage(page) page.goto(web_config["base_url"]) login_page.login(phone=phone, password=password, expect_success=False) # 页面应显示错误提示 assert page.getByText(expected_text).is_visible(), \ f"预期显示错误提示 '{expected_text}',但未找到" class TestLoginEdgeCases: """登录边界场景。""" @pytest.mark.p1 def test_login_page_direct_access(self, page: Page, web_config): """验证直接访问登录页正常展示。""" page.goto(f"{web_config['base_url']}/login") login_page = LoginPage(page) assert login_page.is_on_login_page() @pytest.mark.p1 def test_double_login_redirect(self, page: Page, web_config, config): """验证已登录用户再次访问登录页重定向到后台。""" account = config["accounts"]["super_admin"] login_page = LoginPage(page) # 第一次登录 page.goto(web_config["base_url"]) login_page.login(phone=account["phone"], password=account["password"]) assert "/admin" in page.url # 已登录状态再次访问登录页 page.goto(f"{web_config['base_url']}/login") # 应自动重定向到后台 assert "/admin" in page.url