林子雨编著《AI编程》(访问教材官网)
6.2 开发阶段质量保证
6.2.1 代码格式化
Black是Python社区最流行的代码格式化工具,它的安装非常简单,具体命令如下:
pip install black
安装完成后,不带任何参数执行即可:
# 格式化当前目录下的所有文件
black .
# 格式化单个文件(直接覆盖原文件)
black my_script.py
# 格式化整个目录(递归处理所有 .py)
black src/
# 同时格式化多个目标
black src/ tests/ main.py
也可以在执行之前,先检查一下Black将会执行哪些格式化操作:
# 只检查是否有文件需要格式化,不改写
black --check .
# 查看上一条命令的返回码,0=没问题,1=需要格式化
echo $?
# 打印出差分diff,但不改写
black --diff src/my_file.py
# 两个一起用
black --check --diff .
不带任何参数执行Black,将会对该文件自动进行格式化:
black port_check.py
安装isort的命令如下:
pip install isort
isort的使用方式和Black非常类似,如下所示:
# 格式化当前目录
isort .
# 格式化单个文件(直接覆盖)
isort my_script.py
# 格式化整个目录(递归)
isort src/
# 多个目标
isort src/ tests/ main.py
# 只检查,不写回
isort --check-only .
# 查看上一条命令的返回码,0=OK,1=需要整理
echo $?
# 打印 diff
isort --diff src/main.py
# 组合使用
isort --check-only --diff .
6.2.2 静态分析
安装Ruff的命令如下:
pip install ruff
Ruff的使用方式如下:
# 只检查(不改文件)——最安全
ruff check app/ # 检查app目录,这里只是举例,本章并不存在该目录
# 自动修复可修项(例如删掉未使用import、排序import)
ruff check --fix app/
# 只看某类问题(例如只看import排序相关)
ruff check --select I app/
6.2.3 类型检查
安装mypy的命令如下:
pip install mypy
6.2.4 辅助检查
安装Vulture的命令如下:
pip install vulture
6.3 校验反馈闭环机制
6.3.1 钩子框架的安装与初始化
安装pre-commit的命令如下(只要安装一次,不需要为每个项目安装):
pip install pre-commit
安装完成后,在项目根目录执行如下命令(需要为每个项目单独安装,以后开发其他项目,需要为其他项目也执行一次安装命令):
pre-commit install
如果在安装pre-commit时遇到下面这样的错误,则需要先取消全局设置,再重新安装。如下所示:
# 遇到错误
pre-commit install
[ERROR] Cowardly refusing to install hooks with `core.hooksPath` set.
hint: `git config --unset-all core.hooksPath`
# 取消全局设置
git config --global --unset-all core.hooksPath
# 重新安装
% pre-commit install
# 看到这个提示,则说明安装成功
pre-commit installed at .git/hooks/pre-commit
6.3.2 检查规则配置
以下是一个整合了6.2节所有检查的完整配置,可以保存在项目根目录下的“.pre-commit-config.yaml”文件中直接使用:
repos:
- repo: https://github.com/psf/black
rev: 24.8.0
hooks:
- id: black
language_version: python3.11
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
args: ["--profile", "black"]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.4
hooks:
- id: ruff
args: ["--fix"]
- repo: https://github.com/jendrikseipp/vulture
rev: v2.11
hooks:
- id: vulture
args: [
"--min-confidence=80",
"--sort-by-size",
"."
]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.11.2
hooks:
- id: mypy
name: mypy type checking
args: [
"--ignore-missing-imports",
"--show-error-codes",
"--cache-dir=.mypy_cache"
]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-json
6.4 AI辅助测试
6.4.2 AI辅助用例生成
下面以一个密码强度检测脚本为例,演示如何通过TRAE使用因果图方法生成测试用例。密码检测脚本的业务逻辑如下:
# password_checker.py
password = input("请输入密码: ")
has_digit = any(c.isdigit() for c in password)
has_alpha = any(c.isalpha() for c in password)
has_special = any(c in "!@" for c in password)
length_ok = 8 <= len(password) <= 16
if has_digit and has_alpha and has_special and length_ok:
print("Strong")
else:
print("Weak")
在TRAE中,使用“Agent”模式,在智能体交互界面的对话框中输入以下提示词并提交,请求TRAE使用因果图方法生成测试用例:
你是一个资深的测试专家,精通测试领域的各种方法论。
请用「因果图法」设计测试用例,规则如下:
1. 输入(因)与输出(果)的关系:恒等、非、或、与;
2. 输入之间的约束:互斥、包含、唯一、要求、屏蔽;
3. 执行步骤:
第一步:从需求提取输入/输出,画因果图,标注关系与约束;
第二步:由因果图生成判定表;
第三步:判定表每行转成 1 条测试用例。
输出要求:
- 先按 第一步/第二步/第三步 给出简要推理;
- 最后只输出一张 Markdown 表格形式的测试用例,其余内容全部省略。
请为password_checker.py生成测试用例。
6.4.3 AI辅助接口测试
安装命令如下:
pip install pytest httpx pytest-asyncio pytest-cov
安装完依赖后,可以运行接口测试。假设测试文件名为test_api.py,常用命令如下:
# 运行所有测试,-v表示详细输出
pytest test_api.py -v
# 运行指定测试函数
pytest test_api.py::test_create_user_success -v
# 显示更详细的输出(包括打印内容)
pytest test_api.py -v -s
# 生成覆盖率报告
pytest test_api.py --cov=src --cov-report=html
测试覆盖率是衡量测试质量的重要指标,它表示测试用例覆盖了多少源代码。pytest-cov插件可以生成详细的覆盖率报告:
# 运行测试并生成覆盖率报告
pytest test_api.py --cov=src --cov-report=term-missing
# 生成HTML格式的覆盖率报告(可浏览器查看)
pytest test_api.py --cov=src --cov-report=html
下面以4.5小节的待办事项应用为例,演示如何通过TRAE生成接口测试。在TRAE中选择“Agent”模式,在智能体交互界面的对话框中输入如下提示词并提交:
你是资深测试开发专家 (Python/FastAPI/pytest 方向)
请你根据用户提供的FastAPI代码,生成可直接运行的pytest接口功能测试脚本。
执行步骤:
1. 识别所有路由和HTTP方法
2. 解析Pydantic模型构造请求体
3. 为每个接口生成正常和异常场景测试
4. 使用httpx.AsyncClient测试
代码规范:使用pytest+httpx+pytest-asyncio,断言覆盖status_code和response body关键字段
输出要求:最后只输出pytest测试代码,其余内容全部省略。
通过下面的命令执行接口测试:
pytest test_api.py -v
6.4.4 AI辅助端到端测试
Playwright的安装非常简单,在项目目录下执行以下命令:
npm init -y
npm install -D @playwright/test @types/node
然后,在package.json中添加如下测试脚本(package.json是Node.js的配置文件,是由AI自动生成的):
{
"scripts": {
"test": "playwright test",
"test:headed": "playwright test --headed",
"report": "playwright show-report"
}
}
下面是在TRAE中对第4章的待办事项应用进行端到端测试生成时使用的提示词:
你是资深测试开发(TS+Playwright Test),根据FastAPI源码生成可直接运行端到端测试:
1. 识别全部路由、请求方式、参数;
2. 解析Pydantic模型,组装正常/异常请求体;
3. 采用Playwright内置request发起请求。
规范:基于Playwright Test,断言状态码+返回关键字段,代码放tests目录。
输出:在当前目录下创建一个e2e目录,生成端到端测试代码,并给出执行方式。
执行端到端测试的步骤如下:
# 1. 进入e2e目录并安装依赖
cd e2e
npm install
# 2. 安装Playwright浏览器(首次运行需要)
npx playwright install chromium
# 3. 在另一个终端启动FastAPI服务
cd ..
uvicorn main:app --reload
# 4. 运行测试
npm test
# 5. 查看测试报告
npm run report
6.4.5 AI辅助性能测试
Locust的安装非常简单,通过pip一行命令即可完成:
pip install locust
接下来为4.5小节的待办事项应用增加性能测试。由于目前的待办事项应用只提供了获取所有待办事项、新增待办事项和更新待办事项3个接口,为了模拟标准的增、删、改、查,可以在TRAE对话框中,通过提示词编程为应用增加两个新的接口,用以获取某一个待办事项和删除某一个待办事项,这里假设两个新的接口的代码如下:
@app.get("/todos/{todo_id}")
async def get_todo(todo_id: int) -> dict:
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute("SELECT * FROM todos WHERE id = ?", (todo_id,))
todo = cursor.fetchone()
conn.close()
if todo is None:
raise HTTPException(status_code=404, detail="Todo not found")
return {
"id": todo["id"],
"title": todo["title"],
"is_completed": bool(todo["is_completed"]),
"created_at": todo["created_at"]
}
@app.delete("/todos/{todo_id}", status_code=204)
async def delete_todo(todo_id: int):
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute("DELETE FROM todos WHERE id = ?", (todo_id,))
conn.commit()
if cursor.rowcount == 0:
conn.close()
raise HTTPException(status_code=404, detail="Todo not found")
conn.close()
return None
接下来,让TRAE根据这五个API端点自动生成Locust压测脚本,只需要通过提示词让TRAE生成压测脚本即可:
为当前项目增加locust的压测脚本,要求覆盖到当前项目的所有API,并且读写API的比例为3:1。
启动待办事项应用后,在终端执行以下命令,以Headless模式运行压测:
locust -f locustfile.py --host=http://localhost:8000 --headless -u 100 -t 60s --csv=results/report --loglevel=WARNING
