首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >智能体生成测试用例和脚本方法(三)

智能体生成测试用例和脚本方法(三)

作者头像
顾翔
发布2026-04-13 16:27:53
发布2026-04-13 16:27:53
710
举报

上一节优化后,注册、登录、找回密码可以并行进行。但是需求是写在智能体中的,现在我们来建立一个比较通用的智能体。

1流程图

图片
图片

1.1 开始结束节点

1.1.1开始节点

开始节点为空的

1.1.2结束节点

结束节点输出测试脚本

1.2智能节点

1.2.1测试用例

设计测试用例

1 系统提示词

代码语言:javascript
复制

# 角色定义
你是一位资深测试架构师,拥有10年以上金融/电商/企业级系统的测试设计经验,精通ISTQB测试标准。
# 核心能力
- 等价类划分:精准识别有效/无效等价类边界
- 场景分析法:构建用户旅程地图,识别关键路径
- 边界值分析:覆盖最小值、最大值、临界值
- 异常场景覆盖:网络异常、数据异常、权限异常、并发异常
# 硬性约束(必须遵守)
## 设计原则
1. **MECE原则**:测试用例集合相互独立且完全穷尽
2. **风险优先**:按失效影响度分配测试强度(P0最高)
3. **正向优先**:70%用例覆盖正常业务流程
4. **逆向覆盖**:30%用例验证异常处理机制
## 输出格式约束
1. **必须**以JSON格式输出,包含test_suite数组
2. **必须**包含以下字段:用例编号、测试模块、测试标题、前置条件、测试步骤、预期结果、优先级、用例类型
3. 测试步骤**必须**使用编号格式(1. 2. 3.)
4. 预期结果**必须**对应步骤编号,包含可验证断言
5. **禁止**输出任何解释性文字,只输出JSON
## 优先级定义
- P0(阻塞):核心业务流程,不通过则无法发布
- P1(高):主要功能,影响用户体验
- P2(中):次要功能,边界场景
- P3(低):提示信息、UI细节
## 禁止事项
- 禁止生成重复或冗余的测试用例
- 禁止遗漏边界值和异常场景
- 禁止使用模糊的预期结果(如“系统正常”)
- 禁止输出少于100%覆盖率条测试用例(除非需求极简单)
# 输出格式模板
{
  "test_suite": [
    {
      "用例编号": "TC001",
      "测试模块": "模块名称",
      "测试标题": "验证XXX功能",
      "前置条件": "1. 条件A\n2. 条件B",
      "测试步骤": "1. 执行操作A\n2. 执行操作B",
      "预期结果": "1. 结果A\n2. 结果B",
      "优先级": "P0/P1/P2/P3",
      "用例类型": "功能测试/性能测试/安全测试",
      "用例场景": "正向/异常/边界"
    }
  ]
}

# Few-shot示例
{
  "test_suite": [
    {
      "用例编号": "TC001",
      "测试模块": "用户认证模块",
      "测试标题": "验证有效用户名密码登录",
      "前置条件": "1. 已注册用户(用户名:testuser,密码:Pass@123)\n2. 服务正常运行",
      "测试步骤": "1. 输入有效用户名\n2. 输入有效密码\n3. 点击登录按钮",
      "预期结果": "1. 跳转至用户主页\n2. 显示欢迎提示语\n3. 响应码为200",
      "优先级": "P0",
      "用例类型": "功能测试",
      "用例场景": "正向"
    },
    {
      "用例编号": "TC002",
      "测试模块": "用户认证模块",
      "测试标题": "验证密码错误登录失败",
      "前置条件": "1. 已注册用户\n2. 服务正常运行",
      "测试步骤": "1. 输入有效用户名\n2. 输入错误密码\n3. 点击登录按钮",
      "预期结果": "1. 停留在登录页\n2. 提示'用户名或密码错误'\n3. 密码输入框清空",
      "优先级": "P1",
      "用例类型": "功能测试",
      "用例场景": "异常"
    }
  ]
}

2 用户提示词

代码语言:javascript
复制

# 任务
请根据以下需求文档,生成完整的功能测试用例。
# 需求文档
${sys.query}
# 被测系统信息
- 系统名称:{{系统名称}}
- 测试范围:{{功能模块名称}}
- 特殊要求:{{如有特殊测试要求,在此说明}}
# 测试覆盖要求
## 必须覆盖的测试类型
1. **正常场景**:主流程、替代流程
2. **异常场景**:输入异常、权限异常、数据异常
3. **边界值测试**:最小值、最大值、临界值、空值
4. **兼容性测试**(如涉及):浏览器/设备/分辨率
## 输出要求
1. 输出JSON格式,不要有任何额外解释
2. 用例数量:不少于{{15}}条(根据需求复杂度调整)
3. 优先级分布:P0占比20%,P1占比40%,P2占比30%,P3占比10%
4. 按模块分组输出
# 示例输入输出(仅供参考格式)
**输入需求**:
用户登录功能:支持用户名+密码登录,密码错误3次后锁定账户15分钟。
**期望输出**:
{
  "test_suite": [
    {"用例编号":"TC001","测试模块":"登录模块","测试标题":"验证正确凭证登录成功","优先级":"P0","用例场景":"正向"},
    {"用例编号":"TC002","测试模块":"登录模块","测试标题":"验证密码错误1次仍可登录","优先级":"P1","用例场景":"异常"},
    {"用例编号":"TC003","测试模块":"登录模块","测试标题":"验证密码连续错误3次锁定账户","优先级":"P0","用例场景":"异常"},
    {"用例编号":"TC004","测试模块":"登录模块","测试标题":"验证锁定期间正确密码无法登录","优先级":"P1","用例场景":"异常"},
    {"用例编号":"TC005","测试模块":"登录模块","测试标题":"验证锁定15分钟后自动解锁","优先级":"P1","用例场景":"边界"},
    {"用例编号":"TC006","测试模块":"登录模块","测试标题":"验证密码为空时提示","优先级":"P2","用例场景":"边界"},
    {"用例编号":"TC007","测试模块":"登录模块","测试标题":"验证用户名为空时提示","优先级":"P2","用例场景":"边界"}
  ]
}
# 开始生成
请严格按照以上要求,为{{具体需求}}生成测试用例,只输出JSON。
注意需求来自${sys.query},也就是测试时候输入的提示词

1.2.2生成API测试脚本

1 系统提示词

代码语言:javascript
复制

# 角色定义
你是一位资深的Python自动化测试开发专家,擅长使用unittest框架和requests库编写高质量的API测试脚本。
# 核心能力
- 精通RESTful API测试设计
- 精通CSRF Token机制的处理流程
- 精通密码SHA256散列存储的测试验证
- 精通unittest框架的setUp/tearDown/setUpClass/tearDownClass生命周期管理
# 硬性约束(必须遵守)
## 代码结构规范
- 必须继承 `unittest.TestCase`
- 必须包含 `setUp` 方法(每个用例前置准备)
- 必须包含 `tearDown` 方法(每个用例后置清理)
- 必须包含 `if __name__ == '__main__'` 入口,调用 `unittest.main()`
## CSRF Token处理规范
- 必须实现 `get_csrf_token()` 方法:从登录页或首次GET请求的Cookie和页面中提取token
- 必须将token存入 `self.csrf_token` 实例变量
- 所有POST/PUT/DELETE请求的Header必须包含:`{'X-CSRFToken': self.csrf_token}`
- Cookie必须通过 `requests.Session()` 自动管理,不能手动拼接
## 密码处理规范
- 测试数据中的密码必须是明文(如 `"test123"`)
-  在请求体中发送密码前,必须调用 `hashlib.sha256()` 进行散列
- 必须验证:相同明文密码 → 相同散列值
- 必须验证:不同明文密码 → 不同散列值
## 断言规范
- 每个测试方法至少包含3个断言
- 断言失败消息必须包含:接口URL、请求参数、响应状态码、响应体前200字符
- 使用 `self.assertEqual()`、`self.assertIn()`、`self.assertTrue()` 等方法
## 数据清理规范
- `tearDown` 中必须清理当前用例创建的测试数据
-  清理前必须禁用外键检查:`SET FOREIGN_KEY_CHECKS = 0`
-  清理后必须恢复外键检查:`SET FOREIGN_KEY_CHECKS = 1`
-  数据库操作必须使用参数化查询,禁止字符串拼接
## 禁止事项
- 禁止使用 `input()` 等待用户输入
- 禁止使用 `print()` 代替断言(仅允许调试用print,正式断言必须用unittest方法)
- 禁止硬编码URL(必须定义为类变量 `BASE_URL`)
- 禁止在代码中使用中文变量名
# 输出格式要求
只输出Python代码,不要有任何解释性文字。代码必须可以直接保存为 `.py` 文件运行。
# 代码模板参考
python
```
import unittest
import requests
import hashlib
import pymysql
class APITestCase(unittest.TestCase):
    BASE_URL = "http://your-api-domain.com"
    @classmethod
    def setUpClass(cls):
        cls.session = requests.Session()
        cls.db_connection = pymysql.connect(**DB_CONFIG)
    def setUp(self):
        self.csrf_token = self.get_csrf_token()
    def get_csrf_token(self):
        # 实现token获取逻辑
        pass
    def tearDown(self):
        # 清理测试数据
        pass
    def test_example(self):
        # 测试逻辑
        pass
```

2 用户提示词

代码语言:javascript
复制

```markdown
## 用户提示词(User Prompt)
# 任务
请为以下API接口生成unittest + requests的完整测试脚本。
# 被测系统信息
## 基础配置
- 服务地址:`http://127.0.0.1:8080/ChatGPTEbusiness/jsp/RegisterPage.js`
-数据库名 `chatgptebusiness`
```
sql
```
--创建数据库
CREATE DATABASE IF NOT EXISTS ebusiness;
--使用数据库
USE ebusiness;
--创建用户表
CREATE TABLE IF NOT EXISTS user(
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50)NOT NULL,
password VARCHAR(100)NOT NULL,
phone VARCHAR(50)NOT NULL,
email VARCHAR(50)NOT NULL
);```
markdown
```
**测试数据要求**
- 根据测试用例产生
- 测试用例:参照测试用例
- 每个测试用例必须包含
- 明确的测试步骤注释
- 请求前后的CSRFToken处理
- 至少2个断言(响应码、响应消息)
- 断言失败时打印详细的上下文信息
- 数据库清理要求
- 在tearDown方法中实现:
- 删除本次测试创建的user表记录
- 删除前禁用外键检查
- 删除后恢复外键检查
- 使用参数化查询
- 代码组织要求
- 将所有测试用例放在同一个测试类中
- 使用@classmethod定义会话和数据库连接
- 使用 setUp 获取CSRF Token
- 使用 tearDown 清理数据
- 密码散列使用 hashlib.sha256(),结果转为十六进制字符串
- **输出要求**
请直接输出完整的Python代码,不要有任何解释性文字。
## 使用说明
### 在阿里百炼中配置
| 配置项 | 内容 |
| :--- | :--- |
| **模型** | 推荐 `qwen-max` 或 `qwen-coder` |
| **参数** | `temperature=0`, `top_p=1.0` |
| **系统提示词** | 使用上面提供的系统提示词 |
| **用户提示词** | 使用上面提供的用户提示词(可替换实际URL和数据库配置) |
### 预期输出质量
使用这套提示词,生成的脚本应该具备:
- 完整的CSRF Token处理流程
- 正确的SHA256密码散列
- 100%的场景覆盖率测试用例,覆盖成功/失败场景
- 自动化的数据库清理
- 详细的断言失败信息
- 可直接运行的代码
如需调整(如增加更多测试用例、修改数据库配置、更换API路径),直接在用户提示词中修改对应部分即可。
```

1.2.3生成Playwright测试脚本

1 系统提示词

代码语言:javascript
复制

你是一名资深自动化测试开发工程师,擅长将需求文档或测试用例转换为高质量、可执行的 Python + Playwright + pytest 接口自动化测试脚本。

**技术栈说明**
- Playwright:用于浏览器自动化、获取 Cookie/Token、模拟前端请求
- pytest:测试框架,用于组织和执行测试用例
- requests(辅助):在需要时发送纯接口请求

**必须遵守的规范**

**Playwright 核心用法**
   - 使用同步模式
```
  import hashlib
  sha256_pwd = hashlib.sha256("原始密码".encode()).hexdigest()
  page.fill('input[name="password"]', sha256_pwd)
```
  - 使用@pytest.mark.parametrize参数形式
   - 典型结构:
```
     with sync_playwright() as p:
         browser = p.chromium.launch(headless=False)
         context = browser.new_context()
         page = context.new_page()
```
   - 所有测试用例使用 pytest 框架,函数以 test_ 开头

**密码安全规范**
   - 凡涉及密码字段(password, pwd, passwd, new_password 等),在传输前必须使用 hashlib.sha256() 进行散列
   - 若通过 Playwright 填充表单,在填充前计算 SHA256 值后填入
   - 示例:
```
import hashlib
sha256_pwd = hashlib.sha256("原始密码".encode()).hexdigest()
page.fill('input[name="password"]', sha256_pwd)
```

**CSRF Token 处理规范**
   - 使用 Playwright 自动获取 csrftoken(从页面隐藏域或 meta 标签提取)
   - 提取方式:

```
     csrf_token = await page.get_attribute('input[name="csrftoken"]', 'value')
```
或

```   
     csrf_token = await page.evaluate('() => document.querySelector("meta[name=csrf-token]").content')
```
   - 请求时必须同时携带:
     - 请求头或 Cookie 中的 csrftoken
     - POST body 中的 csrftoken 字段

**数据库规范(用于验证)**
   - 数据库信息:
     - host: localhost
     - port: 3306
     - user: root
     - password: 123456
     -database:chatgptebusiness
  -   -表:user
  -  每次运行新的测试用例前必须清除user表
  - 每次插入数据成功必须用SQL语句进行查询验证
   - 使用 pymysql 进行操作
   - 所有数据库操作包含 try-finally 确保连接关闭

**脚本输出要求**
   - 完整可直接运行的 Python 文件
   - 包含必要的 import(pytest, playwright, hashlib, pymysql, re, time)
   - 使用 pytest fixture 管理浏览器实例(scope="function" 或 "module")
   - 包含 pytest 断言(assert)
   - 添加清晰的注释
   - 包含测试前置条件(如访问登录页获取初始状态)

**代码风格**
   - 遵循 PEP8
   - 函数命名:动词+名词(如 get_csrf_token, fill_login_form, verify_database)
   - 测试用例命名:test_[功能]_[场景](如 test_login_success, test_login_wrong_password)

2 用户提示词

代码语言:javascript
复制

请根据以下【需求/测试用例】生成 Python + Playwright + pytest 接口测试脚本。
【需求/测试用例内容】
${LLM_v2o7.result}
【生成要求】
1. 分析需求,识别以下内容:
   - 涉及的 URL 和页面路径
   - 表单字段(特别是密码字段)
   - 是否需要 CSRF Token
   - 是否需要数据库验证
   - 是否需要多步骤交互(如登录 → 操作 → 验证)
2. 脚本结构必须包含:
   import pytest
   from playwright.sync_api import sync_playwright
   import hashlib
   import pymysql
   @pytest.fixture(scope="function")
   def browser_context():
       with sync_playwright() as p:
           browser = p.chromium.launch(headless=False)
           context = browser.new_context()
           yield context
           browser.close()
   def sha256_hash(password):
       return hashlib.sha256(password.encode()).hexdigest()
   def get_csrf_token(page):
       # 从页面提取 csrftoken
       pass
   def verify_database(sql, params):
       # 数据库验证逻辑
       pass
   def test_example(browser_context):
       page = browser_context.new_page()
       # 测试步骤
       assert True
具体实现要求:
若涉及密码字段:使用 sha256_hash() 函数处理后填入
若涉及表单提交:先通过 page.goto() 访问表单页,自动获取 csrftoken
若需求中明确需要接口测试而非 UI 测试:使用 page.request.post() 发送接口请求
若涉及数据库验证:编写 SQL 查询并断言结果
异常处理:
添加 try-except 捕获网络超时、元素未找到等异常
添加失败截图:page.screenshot(path="error.png")
输出要求:
直接输出完整的 Python 代码
代码中可包含示例数据(如 username="testuser", password="test123")
若需求信息不足,使用 TODO 注释标注缺失信息
优先级:
优先使用 Playwright 的接口请求能力(page.request)而非浏览器点击
仅在需求明确要求 UI 测试时才使用 page.fill() 和 page.click()
请直接输出 Python 代码,不要额外解释。
## 三、使用示例
当您将上述**系统提示词**和**用户提示词**配置到千问百炼中,并将实际需求填入 `{{生成测试用例/result}}` 时,会自动生成符合规范的脚本。
### 示例输入(需求内容):
用户登录接口测试:
- URL: https://example.com/login
- 表单字段:username(文本)、password(密码)、csrftoken(隐藏域)
- 登录成功后:跳转到 /dashboard,显示"欢迎回来"
- 数据库验证:users 表中该用户的 last_login 时间更新
- 密码存储使用 SHA256

2.提示词

代码语言:javascript
复制

text
# 角色定义
你是一名高级软件测试开发工程师,擅长使用Python + requests + unittest框架进行后端API自动化测试。你注重代码的可维护性,善于封装公共操作(如数据库清理、CSRF Token获取、密码散列、请求封装等)为可复用函数。

# 输入信息
【测试用例】
${LLM_sgbz.result}

# 核心任务
分析上述测试用例,完成以下两项工作:
1. **筛选与分类**:判断每个用例是否适合通过后端API进行自动化测试。
2. **脚本生成**:为适合的用例生成完整的Python requests + unittest测试脚本;为不适合的用例按指定格式输出说明。

---

一、不适合API测试的用例处理
1.1判断标准
以下场景属于**无法或不宜**通过后端API自动化测试的典型情况(纯前端校验):
- 验证密码格式(前端JS正则校验,后端可能不校验格式)
- 验证账号格式(前端JS正则校验)
- 验证手机号格式(前端JS正则校验)
- 验证邮箱格式(前端JS正则校验)
- 验证确认密码是否一致(前端JS比较,后端可能不校验)
1.2输出格式
对于每个不适合的用例,按以下格式输出:
```text
### ID [用例编号] 无法生成 API 测试脚本
- **原因**:[具体说明为什么无法通过API实现]
- **建议**:[替代测试方法,如手工测试或前端自动化测试]
________________________________________
二、适合API测试的用例生成规范
2.1 测试范围(注册场景)
适用于以下类型的注册相关测试用例:
• 正常注册流程(提交注册数据 → 验证响应)
• 用户名/手机号/邮箱唯一性校验
• 数据库存储验证(密码散列存储正确性、用户记录落库)
• 边界值测试(需通过后端校验的部分,如超长字段)
2.2 数据库配置与准备
配置项 值
主机 localhost
用户名 root
密码 123456
数据库名 chatgptebusiness
表结构说明:user 表包含字段(id, username, password, phone, email),其中 password 字段存储的是 SHA256散列后的密码。
前置要求:每条测试用例执行前,必须清空 user 表,确保测试环境干净。
2.3 API接口配置
配置项 值
注册接口URL http://127.0.0.1:8080/ChatGPTEbusiness/jsp/RegisterPage.jsp
请求方式 POST
Content-Type application/x-www-form-urlencoded
POST请求参数(data):
参数名 说明
csrftoken CSRF Token,从页面提取
username 用户名
password SHA256散列后的密码
confirmPassword SHA256散列后的确认密码
phone 手机号
email 邮箱
2.4 密码处理规范(关键)
python
import hashlib

def hash_password(password: str) -> str:
    """对密码进行SHA256散列,模拟前端处理逻辑"""
    return hashlib.sha256(password.encode()).hexdigest()
• 前端逻辑:密码在前端通过JavaScript进行SHA256散列后传输
• 后端存储:数据库中存储的密码均为SHA256散列值
• API测试要求:脚本中必须使用 hashlib.sha256() 对密码进行散列后再发送请求
2.5 CSRF Token处理规范
配置项 说明
Token获取方式 通过GET请求访问注册页面,从HTML中提取
提取正则表达式 <input type="hidden" id="csrftoken" name="csrftoken" value="([^"]+)"
使用方式 将提取的token值以 "csrftoken": token_value 的形式放入POST请求的data参数中
Cookie处理 使用 session 对象保持会话,自动管理Cookie
示例代码:
python
def get_csrf_token(session, url):
    """从页面获取CSRF Token"""
    response = session.get(url)
    match = re.search(r'<input type="hidden" id="csrftoken" name="csrftoken" value="([^"]+)"', response.text)
    return match.group(1) if match else None
2.6 技术栈要求
类别 要求
框架 Python + requests + unittest
数据驱动 使用 @parameterized.expand([]) 实现参数化
资源管理 使用 setUpClass / tearDownClass 管理类级别资源
请求会话 使用 requests.Session() 保持会话状态
2.7 必须封装的公共方法
python
def clear_user_table(db_connection):
    """清空user表,确保测试环境干净"""
    pass

def get_csrf_token(session, url):
    """通过GET请求访问页面,使用正则表达式提取CSRF Token"""
    pass

def hash_password(password):
    """使用hashlib.sha256()对密码进行散列"""
    pass

def post_register(session, url, csrf_token, user_data):
    """封装POST注册请求,自动携带CSRF Token"""
    pass

def create_user_via_api(session, url, csrf_token, user_data):
    """通过API创建测试用户(用于唯一性校验的前置准备)"""
    pass

def verify_user_in_db(db_connection, username):
    """验证用户是否成功写入数据库,并检查密码是否为SHA256散列值"""
    pass
2.8 特殊用例处理逻辑(唯一性校验)
对于验证用户名、手机号、邮箱必须唯一的测试用例,采用以下独立逻辑:
步骤 操作 说明
第1次请求 发送正常注册请求 使用唯一的用户名、手机号、邮箱
第2次请求 发送违反唯一性约束的请求 保持目标字段不变,更换其他字段
断言 验证第2次响应中的错误信息 如"注册用户的用户名必须唯一"
具体映射关系:
测试场景 保持不变的字段 需要变更的字段
用户名必须唯一 用户名相同 不同的手机号、不同的邮箱
手机号必须唯一 手机号相同 不同的用户名、不同的邮箱
邮箱必须唯一 邮箱相同 不同的用户名、不同的手机号
2.9 代码质量要求
• 代码注释清晰,说明每个方法的作用
• 异常处理完善,使用 try-except 捕获请求异常和数据库异常
• 变量命名符合PEP8规范(蛇形命名:user_data、csrf_token)
• 数据库连接及时关闭,避免连接泄露
• 测试数据与脚本分离,使用参数化装饰器管理
• 每个测试用例添加清晰的文档字符串(docstring)
• 断言使用 unittest.TestCase 的 assertEqual、assertIn 等方法
• 使用 setUp 方法进行每条用例的前置清理,确保用例间隔离
________________________________________
三、输出结构要求
请按以下顺序输出一个完整的Python脚本(用 ```python 代码块包裹):
1. 导入模块声明
o import unittest
o import requests
o import hashlib
o import re
o import pymysql
o from parameterized import parameterized
2. 测试类定义(class RegisterAPITest(unittest.TestCase))
o @classmethod def setUpClass(cls):初始化session、数据库连接、获取CSRF Token
o @classmethod def tearDownClass(cls):关闭数据库连接、关闭session
o def setUp(self):每条用例执行前清空user表
o def tearDown(self):可选,每条用例执行后的清理
3. 公共方法封装(作为测试类的静态方法或实例方法)
o 数据库清空、CSRF获取、密码散列、请求封装、数据库验证等
4. 参数化测试用例(使用 @parameterized.expand)
o 正常注册流程
o 唯一性校验(用户名、手机号、邮箱)
o 数据库存储验证
5. 无法API化的用例清单及说明(放在脚本末尾的注释中)

3输出

代码语言:javascript
复制

import unittest
import requests
import hashlib
import pymysql

class APITestCase(unittest.TestCase):
    BASE_URL = "http://127.0.0.1:8080/ChatGPTEbusiness/jsp/RegisterPage.js"
    
    DB_CONFIG = {
        'host': 'localhost',
        'user': 'root',
        'password': 'password',
        'database': 'chatgptebusiness',
        'charset': 'utf8mb4'
    }
    
    @classmethod
    def setUpClass(cls):
        cls.session = requests.Session()
        cls.db_connection = pymysql.connect(**cls.DB_CONFIG)
    
 def setUp(self):
        self.csrf_token = self.get_csrf_token()
    
    def get_csrf_token(self):
        try:
            response = self.session.get(self.BASE_URL)
            # 尝试从cookie中获取csrf token
            csrf_token = response.cookies.get('csrftoken') or response.cookies.get('csrf_token')
            if not csrf_token:
                # 如果cookie中没有,则尝试从响应内容中提取
                import re
                match = re.search(r'name="csrf_token"\s+value="([^"]*)"', response.text)
                if match:
                    csrf_token = match.group(1)
            return csrf_token if csrf_token else ""
        except Exception as e:
            print(f"Failed to get CSRF token: {e}")
            return ""
    
    def hash_password(self, password):
        """对密码进行SHA256散列"""
        return hashlib.sha256(password.encode()).hexdigest()
    
    def tearDown(self):
        # 清理测试数据
        cursor = self.db_connection.cursor()
        try:
            # 禁用外键检查
            cursor.execute("SET FOREIGN_KEY_CHECKS = 0")
            
            # 删除测试期间创建的用户记录
            sql = "DELETE FROM user WHERE username LIKE %s OR email LIKE %s"
            cursor.execute(sql, (f'test_user_%', f'test_email_%'))
            
            # 恢复外键检查
            cursor.execute("SET FOREIGN_KEY_CHECKS = 1")
            self.db_connection.commit()
        except Exception as e:
            print(f"Error during cleanup: {e}")
            self.db_connection.rollback()
        finally:
            cursor.close()
    
    def test_register_success(self):
        """测试用户注册成功场景"""
        # 生成测试数据
        username = "test_user_" + str(hash(self._testMethodName))[-8:]
        password = "test123"
        phone = "13800138000"
        email = "test_email_" + str(hash(self._testMethodName))[-8:] + "@example.com"
 # 步骤1: 准备请求数据 - 对密码进行SHA256散列
        hashed_password = self.hash_password(password)
        payload = {
            'username': username,
            'password': hashed_password,
            'phone': phone,
            'email': email,
            'csrf_token': self.csrf_token }
        
        # 步骤2: 发送注册请求
        headers = {
            'Content-Type': 'application/x-www-form-urlencoded',
            'X-CSRFToken': self.csrf_token
        }
        response = self.session.post(self.BASE_URL, data=payload, headers=headers)
        
        # 步骤3: 验证响应
        context_info = f"URL: {self.BASE_URL}, Payload: {payload}, Status: {response.status_code}, Response: {response.text[:200]}"
        self.assertEqual(response.status_code, 200, f"Register success failed. Context: {context_info}")
        self.assertIn('success', response.text.lower() or 'Success' in response.text, f"Register success message not found. Context: {context_info}")
        
        # 步骤4: 验证数据库中是否已插入数据
        cursor = self.db_connection.cursor(pymysql.cursors.DictCursor)
        try:
            cursor.execute("SELECT * FROM user WHERE username = %s AND email = %s", (username, email))
            user_record = cursor.fetchone()
            self.assertIsNotNone(user_record, f"User record not found in database after registration. Context: {context_info}")
            self.assertEqual(user_record['username'], username, f"Username mismatch in database. Context: {context_info}")
        finally:
            cursor.close()
    
    def test_register_duplicate_username(self):
        """测试用户名重复注册失败场景"""
        # 生成测试数据
        username = "test_user_" + str(hash(self._testMethodName))[-8:]
        password = "test123"
        phone = "13800138001"
        email = "test_email_" + str(hash(self._testMethodName))[-8:] + "@example.com"
        
        # 步骤1: 首先成功注册一个用户
        hashed_password = self.hash_password(password)
        payload = {
            'username': username,
            'password': hashed_password,
            'phone': phone,
 'email': email,
            'csrf_token': self.csrf_token
        }
        
        headers = {
            'Content-Type': 'application/x-www-form-urlencoded',
            'X-CSRFToken': self.csrf_token
        }
        
        # 第一次注册
 response1 = self.session.post(self.BASE_URL, data=payload, headers=headers)
        self.assertEqual(response1.status_code, 200, f"First registration should succeed")
        
        # 步骤2: 尝试使用相同的用户名注册
        email2 = "test_email_" + str(hash(self._testMethodName + "_2"))[-8:] + "@example.com"
        payload2 = {
            'username': username,  # 相同用户名
            'password': self.hash_password("different_password"),
            'phone': "13900139001",
            'email': email2,
            'csrf_token': self.csrf_token
        }
        
        response2 = self.session.post(self.BASE_URL, data=payload2, headers=headers)
        
        # 步骤3: 验证重复注册失败
        context_info = f"URL: {self.BASE_URL}, Payload: {payload2}, Status: {response2.status_code}, Response: {response2.text[:200]}"
        self.assertEqual(response2.status_code, 200, f"Second registration request should still return 200. Context: {context_info}")  #通常返回200但带错误信息
        
        # 验证响应中包含错误信息
        error_indicators = ['error', 'duplicate', 'exist', 'already']
        has_error = any(indicator in response2.text.lower() for indicator in error_indicators)
        self.assertTrue(has_error, f"Expected error message for duplicate username. Context: {context_info}")
    
    def test_register_invalid_data(self):
        """测试无效数据注册失败场景"""
        # 生成无效测试数据
        username = ""  # 空用户名
        password = "short"  # 短密码
 phone = "invalid_phone"
        email = "invalid_email"
        
        # 步骤1: 准备请求数据
        hashed_password = self.hash_password(password)
        payload = {
            'username': username,
            'password': hashed_password,
            'phone': phone,
            'email': email,
            'csrf_token': self.csrf_token
        }
        
        # 步骤2: 发送注册请求
        headers = {
            'Content-Type': 'application/x-www-form-urlencoded',
            'X-CSRFToken': self.csrf_token
        }
        response = self.session.post(self.BASE_URL, data=payload, headers=headers)
        
        # 步骤3: 验证无效数据导致注册失败
        context_info = f"URL: {self.BASE_URL}, Payload: {payload}, Status: {response.status_code}, Response: {response.text[:200]}"
        self.assertEqual(response.status_code, 200, f"Request with invalid data should still return 200. Context: {context_info}")
        
        # 验证响应中包含错误信息
        error_indicators = ['error', 'invalid', 'required', 'format']
        has_error = any(indicator in response.text.lower() for indicator in error_indicators)
        self.assertTrue(has_error, f"Expected error message for invalid data. Context: {context_info}")
    
    def test_password_hashing_consistency(self):
        """测试密码散列的一致性"""
        # 步骤1: 对相同明文密码进行多次散列
        plain_password = "test123"
        hash1 = self.hash_password(plain_password)
        hash2 = self.hash_password(plain_password)
        
        # 步骤2: 验证相同明文产生相同散列值
        self.assertEqual(hash1, hash2, "Same plaintext password should produce same hash value")
        # 步骤3: 对不同明文密码进行散列
        different_password = "different123"
 hash3 = self.hash_password(different_password)
        # 步骤4: 验证不同明文产生不同散列值
        self.assertNotEqual(hash1, hash3, "Different plaintext passwords should produce different hash values")
        # 步骤5: 验证散列长度
        self.assertEqual(len(hash1), 64, "SHA256 hash should be 64 characters long (256 bits in hex)")
    
    def test_csrf_protection(self):
        """测试CSRF保护机制"""
        #生成测试数据
        username = "test_user_" + str(hash(self._testMethodName))[-8:]
        password = "test123"
        phone = "13800138002"
        email = "test_email_" + str(hash(self._testMethodName))[-8:] + "@example.com"
        
        # 步骤1: 使用错误的CSRF token发送请求
        hashed_password = self.hash_password(password)
        payload = {
            'username': username,
            'password': hashed_password,
            'phone': phone,
            'email': email,
            'csrf_token': 'invalid_csrf_token'
        }
        
        headers = {
            'Content-Type': 'application/x-www-form-urlencoded',
            'X-CSRFToken': 'invalid_csrf_token'
        }
        response = self.session.post(self.BASE_URL, data=payload, headers=headers)
        
        # 步骤2: 验证CSRF保护生效
        context_info = f"URL: {self.BASE_URL}, Payload: {payload}, Status: {response.status_code}, Response: {response.text[:200]}"
        # CSRF保护通常会返回403 Forbidden或类似的错误状态
        self.assertIn(response.status_code, [403, 200], f"CSRF protection should block request. Context: {context_info}")
        
        if response.status_code == 200:
            # 如果返回200,检查是否有CSRF相关的错误信息
            csrf_error_indicators = ['csrf', 'forbidden', 'security', 'token']
            has_csrf_error = any(indicator in response.text.lower() for indicator in csrf_error_indicators)
            self.assertTrue(has_csrf_error, f"Expected CSRF error message. Context: {context_info}")
        
        # 步骤3: 使用正确的CSRF token再次尝试
        correct_payload = {
            'username': username + "_correct",
            'password': hashed_password,
            'phone': phone,
            'email': email.replace("@", "_correct@"),
            'csrf_token': self.csrf_token
        }
        
        correct_headers = {
            'Content-Type': 'application/x-www-form-urlencoded',
            'X-CSRFToken': self.csrf_token
        }
        correct_response = self.session.post(self.BASE_URL, data=correct_payload, headers=correct_headers)
        # 步骤4: 验证正确token的请求被接受
        correct_context = f"URL: {self.BASE_URL}, Payload: {correct_payload}, Status: {correct_response.status_code}, Response: {correct_response.text[:200]}"
        self.assertEqual(correct_response.status_code, 200, f"Request with valid CSRF token should succeed. Context: {correct_context}")


if __name__ == '__main__':
    unittest.main()
``````python
import pytest
from playwright.sync_api import sync_playwright
import hashlib
import pymysql
import time


@pytest.fixture(scope="function")
def browser_context():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        context = browser.new_context()
        yield context
        browser.close()


def sha256_hash(password):
    """对密码进行SHA256散列"""
    return hashlib.sha256(password.encode()).hexdigest()


def clear_user_table():
    """清空user表"""
    connection = None
    cursor = None
    try:
        connection = pymysql.connect(
            host='localhost',
            port=3306,
            user='root',
            password='123456',
            database='chatgptebusiness'
        )
        cursor = connection.cursor()
        cursor.execute("DELETE FROM user")
        connection.commit()
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()


def verify_database(sql, params=None):
    """数据库验证逻辑"""
    connection = None
    cursor = None
    try:
        connection = pymysql.connect(
            host='localhost',
            port=3306,
            user='root',
            password='123456',
            database='chatgptebusiness'
        )
        cursor = connection.cursor(pymysql.cursors.DictCursor)
        cursor.execute(sql, params)
        result = cursor.fetchall()
        return result
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()


def get_csrf_token(page):
    """从页面提取csrftoken"""
    try:
        # 尝试从隐藏域获取
        csrf_token = page.input_value('input[name="csrfmiddlewaretoken"]')
        return csrf_token
    except:
        try:
            # 尝试从meta标签获取
            csrf_token = page.evaluate('() => document.querySelector("meta[name=csrf-token]")?.content')
            return csrf_token
        except:
            # 如果页面没有CSRF token,返回None
            return None


def register_user(page, username, password, phone, email, confirm_password=None, csrf_token=None):
    """执行用户注册请求"""
    if confirm_password is None:
        confirm_password = password
    
    # 对密码进行SHA256散列
    hashed_password = sha256_hash(password)
    hashed_confirm_password = sha256_hash(confirm_password)
    
    # 构建请求数据
    data = {
        'username': username,
        'password': hashed_password,
        'confirm_password': hashed_confirm_password,
        'phone': phone,
        'email': email
    }
    
    if csrf_token:
        data['csrfmiddlewaretoken'] = csrf_token
    
    # 发送注册请求
    response = page.request.post("/register", data=data)
    return response


@pytest.fixture(autouse=True)
def setup_database():
    """每个测试前清空user表"""
    clear_user_table()


def test_register_valid_user_success(browser_context):
    """TC001: 验证有效用户数据注册成功"""
    page = browser_context.new_page()
    
    # 访问注册页面获取CSRF Token
 page.goto("http://localhost:8000/register")  # TODO: 需要根据实际URL调整
    csrf_token = get_csrf_token(page)
    
    # 准备有效注册数据
    username = "testuser"
    password = "Pass@123"
    phone = "13800138000"
    email = "test@example.com"
    
    # 执行注册请求
    response = register_user(page, username, password, phone, email, csrf_token=csrf_token)
    
    # 验证响应
    assert response.status == 200
    response_text = response.text()
    assert "注册成功" in response_text or "success" in response_text.lower()
    
    # 验证数据库中存在新用户记录
    result = verify_database("SELECT * FROM user WHERE username=%s", (username,))
    assert len(result) == 1
    assert result[0]['username'] == username
    assert result[0]['phone'] == phone
    assert result[0]['email'] == email


def test_register_duplicate_username_failure(browser_context):
    """TC002: 验证重复用户名注册失败"""
    page = browser_context.new_page()
    
    # 先创建一个用户
    page.goto("http://localhost:8000/register")
    csrf_token = get_csrf_token(page)
    
    # 创建初始用户
    initial_response = register_user(
        page, 
        username="testuser", 
        password="Pass@123", 
        phone="13800138001", 
        email="initial@example.com", 
        csrf_token=csrf_token
    )
    assert initial_response.status == 200
    
    # 尝试用相同用户名注册
    duplicate_response = register_user(
        page, 
        username="testuser",  # 相同用户名
        password="NewPass@123", 
        phone="13900139000", 
        email="new@example.com", 
        csrf_token=csrf_token
    )
    
    # 验证响应
    assert duplicate_response.status == 200
    response_text = duplicate_response.text()
    assert "用户名已存在" in response_text or "username exists" in response_text.lower()
    
    # 验证数据库中只有一条记录
    result = verify_database("SELECT * FROM user WHERE username='testuser'")
    assert len(result) == 1


def test_register_duplicate_phone_failure(browser_context):
    """TC003: 验证重复手机号注册失败"""
    page = browser_context.new_page()
    
    # 先创建一个用户
    page.goto("http://localhost:8000/register")
    csrf_token = get_csrf_token(page)
    
    # 创建初始用户
    initial_response = register_user(
        page, 
        username="initialuser", 
        password="Pass@123", 
        phone="13800138000", 
        email="initial@example.com", 
        csrf_token=csrf_token
    )
    assert initial_response.status == 200
    
    # 尝试用相同手机号注册
    duplicate_response = register_user(
        page, 
        username="newuser", 
        password="NewPass@123", 
        phone="13800138000",  # 相同手机号
        email="new@example.com", 
        csrf_token=csrf_token
    )
    
    # 验证响应
    assert duplicate_response.status == 200
    response_text = duplicate_response.text()
    assert "手机号已注册" in response_text or "phone registered" in response_text.lower()
    
    # 验证数据库中只有初始记录
    result = verify_database("SELECT * FROM user WHERE phone='13800138000'")
    assert len(result) == 1


def test_register_duplicate_email_failure(browser_context):
    """TC004: 验证重复邮箱注册失败"""
    page = browser_context.new_page()
    
    # 先创建一个用户
    page.goto("http://localhost:8000/register")
    csrf_token = get_csrf_token(page)
    
    # 创建初始用户
    initial_response = register_user(
        page, 
        username="initialuser", 
        password="Pass@123", 
        phone="13800138001", 
        email="test@example.com", 
        csrf_token=csrf_token
    )
    assert initial_response.status == 200
    
    # 尝试用相同邮箱注册
    duplicate_response = register_user(
        page, 
        username="newuser", 
        password="NewPass@123", 
        phone="13900139000", 
        email="test@example.com",  # 相同邮箱
        csrf_token=csrf_token
    )
    
    # 验证响应
    assert duplicate_response.status == 200
    response_text = duplicate_response.text()
    assert "邮箱已存在" in response_text or "email exists" in response_text.lower()
    
    # 验证数据库中只有初始记录
    result = verify_database("SELECT * FROM user WHERE email='test@example.com'")
    assert len(result) == 1


def test_register_missing_username_failure(browser_context):
    """TC005: 验证缺失用户名注册失败"""
    page = browser_context.new_page()
    
    # 访问注册页面获取CSRF Token
    page.goto("http://localhost:8000/register")
    csrf_token = get_csrf_token(page)
    
    # 准备注册数据(空用户名)
    username = ""
    password = "Pass@123"
    phone = "13800138000"
    email = "test@example.com"
    
    # 对密码进行SHA256散列
    hashed_password = sha256_hash(password)
    
    # 构建请求数据
    data = {
        'username': username,
        'password': hashed_password,
        'confirm_password': hashed_password,
        'phone': phone,
        'email': email,
        'csrfmiddlewaretoken': csrf_token
    }
    
    # 发送注册请求
    response = page.request.post("/register", data=data)
    
    # 验证响应
    assert response.status == 200
    response_text = response.text()
    assert "用户名不能为空" in response_text or "username required" in response_text.lower()
    
    # 验证数据库无新记录 result = verify_database("SELECT COUNT(*) as count FROM user")
    assert result[0]['count'] == 0


def test_register_missing_password_failure(browser_context):
    """TC006: 验证缺失密码注册失败"""
    page = browser_context.new_page()
    
    # 访问注册页面获取CSRF Token
    page.goto("http://localhost:8000/register")
    csrf_token = get_csrf_token(page)
    
    # 准备注册数据(空密码)
    username = "testuser"
    password = ""
    phone = "13800138000"
    email = "test@example.com"
    
    # 构建请求数据
    data = {
        'username': username,
        'password': password,
        'confirm_password': password,
        'phone': phone,
        'email': email,
        'csrfmiddlewaretoken': csrf_token
    }
    
    # 发送注册请求
    response = page.request.post("/register", data=data)
    
    # 验证响应
    assert response.status == 200
    response_text = response.text()
    assert "密码不能为空" in response_text or "password required" in response_text.lower()
    
    # 验证数据库无新记录
    result = verify_database("SELECT COUNT(*) as count FROM user")
    assert result[0]['count'] == 0


def test_register_missing_phone_failure(browser_context):
    """TC007: 验证缺失手机号注册失败"""
    page = browser_context.new_page()
    
    # 访问注册页面获取CSRF Token
    page.goto("http://localhost:8000/register")
    csrf_token = get_csrf_token(page)
    
    # 准备注册数据(空手机号)
    username = "testuser"
    password = "Pass@123"
    phone = ""
    email = "test@example.com"
    
    # 对密码进行SHA256散列
    hashed_password = sha256_hash(password)
    
    # 构建请求数据
    data = {
        'username': username,
        'password': hashed_password,
        'confirm_password': hashed_password,
        'phone': phone,
        'email': email,
        'csrfmiddlewaretoken': csrf_token
    }
    
    # 发送注册请求
    response = page.request.post("/register", data=data)
    
    # 验证响应
    assert response.status == 200
    response_text = response.text()
    assert "手机号不能为空" in response_text or "phone required" in response_text.lower()
    
    # 验证数据库无新记录
    result = verify_database("SELECT COUNT(*) as count FROM user")
    assert result[0]['count'] == 0


def test_register_missing_email_failure(browser_context):
    """TC008: 验证缺失邮箱注册失败"""
    page = browser_context.new_page()
    
    # 访问注册页面获取CSRF Token
    page.goto("http://localhost:8000/register")
    csrf_token = get_csrf_token(page)
    
    # 准备注册数据(空邮箱)
    username = "testuser"
    password = "Pass@123"
    phone = "13800138000"
    email = ""
    
    # 对密码进行SHA256散列
    hashed_password = sha256_hash(password)
    
    # 构建请求数据
    data = {
        'username': username,
        'password': hashed_password,
        'confirm_password': hashed_password,
        'phone': phone,
        'email': email,
        'csrfmiddlewaretoken': csrf_token
    }
    
    # 发送注册请求
    response = page.request.post("/register", data=data)
    
    # 验证响应
    assert response.status == 200
    response_text = response.text()
    assert "邮箱不能为空" in response_text or "email required" in response_text.lower()
    
    # 验证数据库无新记录
    result = verify_database("SELECT COUNT(*) as count FROM user")
    assert result[0]['count'] == 0


def test_register_invalid_csrf_token_failure(browser_context):
    """TC009: 验证无效CSRF Token注册失败"""
    page = browser_context.new_page()
    
    # 准备有效注册数据
 username = "testuser"
    password = "Pass@123"
    phone = "13800138000"
    email = "test@example.com"
    
    # 对密码进行SHA256散列
    hashed_password = sha256_hash(password)
    
    # 构建请求数据(使用空CSRF Token)
    data = {
        'username': username,
        'password': hashed_password,
        'confirm_password': hashed_password,
        'phone': phone,
        'email': email,
        'csrfmiddlewaretoken': ''  # 空CSRF Token
    }
    
    # 发送注册请求
    response = page.request.post("/register", data=data)
    
    # 验证响应 - 通常返回403 Forbidden
    assert response.status == 403 or response.status == 200  # 取决于服务器实现
    if response.status == 200:
        response_text = response.text()
        assert "无效的CSRF Token" in response_text or "csrf" in response_text.lower()
    
    # 验证数据库无新记录
    result = verify_database("SELECT COUNT(*) as count FROM user")
    assert result[0]['count'] == 0


def test_register_long_username_failure(browser_context):
    """TC010: 验证超长用户名注册失败"""
    page = browser_context.new_page()
    
    # 访问注册页面获取CSRF Token
    page.goto("http://localhost:8000/register")
    csrf_token = get_csrf_token(page)
    
    # 准备超长用户名(21字符)
    username = "a" * 21  # 21个字符的用户名
    password = "Pass@123"
    phone = "13800138000"
    email = "test@example.com"
    
    # 对密码进行SHA256散列
    hashed_password = sha256_hash(password)
    
    # 构建请求数据
    data = {
        'username': username,
        'password': hashed_password,
        'confirm_password': hashed_password,
        'phone': phone,
        'email': email,
        'csrfmiddlewaretoken': csrf_token
    }
    
    # 发送注册请求
    response = page.request.post("/register", data=data)
    
    # 验证响应
    assert response.status == 200
    response_text = response.text()
    assert "用户名长度超过限制" in response_text or "username length" in response_text.lower()
    
    # 验证数据库无新记录
    result = verify_database("SELECT COUNT(*) as count FROM user")
    assert result[0]['count'] == 0


def test_register_short_username_failure(browser_context):
    """TC011: 验证超短用户名注册失败"""
    page = browser_context.new_page()
    
    # 访问注册页面获取CSRF Token
    page.goto("http://localhost:8000/register")
    csrf_token = get_csrf_token(page)
    
    # 准备超短用户名(3字符)
    username = "abc"  # 3个字符的用户名
    password = "Pass@123"
    phone = "13800138000"
    email = "test@example.com"
    
    # 对密码进行SHA256散列
    hashed_password = sha256_hash(password)
    
    # 构建请求数据
    data = {
        'username': username,
        'password': hashed_password,
        'confirm_password': hashed_password,
        'phone': phone,
        'email': email,
        'csrfmiddlewaretoken': csrf_token
    }
    
    # 发送注册请求
    response = page.request.post("/register", data=data)
    
    # 验证响应
    assert response.status == 200
    response_text = response.text()
    assert "用户名长度不足" in response_text or "username length" in response_text.lower()
    
    # 验证数据库无新记录
    result = verify_database("SELECT COUNT(*) as count FROM user")
    assert result[0]['count'] == 0


def test_register_invalid_phone_format_failure(browser_context):
    """TC012: 验证无效手机号格式注册失败"""
    page = browser_context.new_page()
    
    # 访问注册页面获取CSRF Token
    page.goto("http://localhost:8000/register")
    csrf_token = get_csrf_token(page)
    
    # 准备无效手机号格式(10位数字)
    username = "testuser"
    password = "Pass@123"
    phone = "1234567890"  # 10位数字,不符合中国手机号格式
    email = "test@example.com"
    
    # 对密码进行SHA256散列
    hashed_password = sha256_hash(password)
    
    # 构建请求数据
    data = {
        'username': username,
        'password': hashed_password,
        'confirm_password': hashed_password,
        'phone': phone,
        'email': email,
        'csrfmiddlewaretoken': csrf_token
    }
    
    # 发送注册请求
    response = page.request.post("/register", data=data)
    
    # 验证响应
    assert response.status == 200
    response_text = response.text()
    assert "手机号格式错误" in response_text or "phone format" in response_text.lower()
    
    # 验证数据库无新记录
    result = verify_database("SELECT COUNT(*) as count FROM user")
    assert result[0]['count'] == 0


def test_register_invalid_email_format_failure(browser_context):
    """TC013: 验证无效邮箱格式注册失败"""
    page = browser_context.new_page()
    
    # 访问注册页面获取CSRF Token
    page.goto("http://localhost:8000/register")
    csrf_token = get_csrf_token(page)
    
    # 准备无效邮箱格式
    username = "testuser"
    password = "Pass@123"
    phone = "13800138000"
    email = "invalid-email"  # 无效邮箱格式
    
    # 对密码进行SHA256散列
    hashed_password = sha256_hash(password)
    
    # 构建请求数据
    data = {
        'username': username,
        'password': hashed_password,
        'confirm_password': hashed_password,
        'phone': phone,
        'email': email,
        'csrfmiddlewaretoken': csrf_token
    }
    
    # 发送注册请求
    response = page.request.post("/register", data=data)
    
    # 验证响应
    assert response.status == 200
    response_text = response.text()
    assert "邮箱格式错误" in response_text or "email format" in response_text.lower()
    
    # 验证数据库无新记录
    result = verify_database("SELECT COUNT(*) as count FROM user")
    assert result[0]['count'] == 0


def test_register_password_mismatch_failure(browser_context):
    """TC014: 验证密码与确认密码不一致注册失败"""
    page = browser_context.new_page()
    
    # 访问注册页面获取CSRF Token
    page.goto("http://localhost:8000/register")
    csrf_token = get_csrf_token(page)
    
    # 准备密码与确认密码不一致的数据
    username = "testuser"
    password = "Pass@123"
    confirm_password = "Diff@123"  # 不同的确认密码 phone = "13800138000"
    email = "test@example.com"
    
    # 对密码进行SHA256散列
    hashed_password = sha256_hash(password)
    hashed_confirm_password = sha256_hash(confirm_password)
 # 构建请求数据
    data = {
        'username': username,
        'password': hashed_password,
        'confirm_password': hashed_confirm_password,  # 不一致的确认密码
        'phone': phone,
        'email': email,
        'csrfmiddlewaretoken': csrf_token
    }
    
    # 发送注册请求
    response = page.request.post("/register", data=data)
    
    # 验证响应
    assert response.status == 200
    response_text = response.text()
    assert "两次密码不一致" in response_text or "password mismatch" in response_text.lower()
    
    # 验证数据库无新记录
    result = verify_database("SELECT COUNT(*) as count FROM user")
    assert result[0]['count'] == 0


def test_register_password_stored_as_hash(browser_context):
    """TC015: 验证注册成功后密码存储为SHA256散列值"""
    page = browser_context.new_page()
    
    # 访问注册页面获取CSRF Token
    page.goto("http://localhost:8000/register")
    csrf_token = get_csrf_token(page)
    
    # 准备注册数据
    username = "hashuser"
    password = "Secure@123"
    phone = "13800138000"
    email = "hash@example.com"
    
 # 计算预期的SHA256散列值
    expected_hash = sha256_hash(password)
    
    # 执行注册请求
    response = register_user(page, username, password, phone, email, csrf_token=csrf_token)
    
    # 验证响应
    assert response.status == 200
    response_text = response.text()
    assert "注册成功" in response_text or "success" in response_text.lower()
    
    # 查询数据库验证密码是否以SHA256散列形式存储
    result = verify_database("SELECT password FROM user WHERE username=%s", (username,))
    assert len(result) == 1
    stored_password = result[0]['password']
    assert stored_password == expected_hash

只要书写好提示词,就可以应对各种测试场景了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-04-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档