1. 项目概述:当Postman遇上DeepSeek,接口测试的“降维打击”

如果你和我一样,常年泡在接口测试的“苦海”里,一定对这样的场景不陌生:面对一个新项目,几十上百个接口文档摆在你面前,你需要手动在Postman里一个个创建请求,然后绞尽脑汁地设计测试用例,特别是那些复杂的断言逻辑——验证响应状态码、检查关键字段是否存在、判断数据类型、甚至验证嵌套JSON对象里的某个值是否符合预期。这个过程枯燥、重复,还容易出错。更头疼的是,当接口文档更新时,你的测试集合可能又要推倒重来。

这就是为什么当我开始尝试将DeepSeek这类大语言模型(LLM)与Postman结合时,感觉像是给手里的“瑞士军刀”装上了“智能导航”。这不仅仅是效率的提升,更像是一种工作范式的转变。简单来说,这个组合的核心价值在于: 让AI理解你的接口文档(无论是Swagger/OpenAPI、Markdown还是简单的文字描述),然后自动为你生成结构化的Postman集合,包括完整的请求参数、认证信息,以及最关键、最耗时的部分——智能、健壮的断言脚本。

它解决的痛点非常明确: 将测试工程师从大量重复、机械的配置工作中解放出来,让他们能更专注于测试策略设计、边界条件探索和业务逻辑验证这些更具创造性和挑战性的工作。 无论是前端、后端还是测试工程师,只要你的工作涉及API调试与验证,这套组合都能让你事半功倍。接下来,我就结合自己近期的实践,拆解一下如何实现这场“效率革命”。

2. 核心思路与工具选型背后的考量

2.1 为什么是Postman + DeepSeek?

在接口测试领域,工具选择很多,比如JMeter、Apifox、SoapUI等。我选择Postman作为落地点,主要基于几个现实考量:

Postman的普适性与生态成熟度: 它几乎是API开发者的“标配”。其直观的图形界面降低了使用门槛,强大的集合(Collection)、环境变量(Environment)、预请求脚本(Pre-request Script)和测试脚本(Tests)功能,构成了一个完整的测试工作流。更重要的是,Postman支持导出/导入集合(JSON格式),这为程序化生成和修改测试用例提供了可能。

DeepSeek的代码与逻辑理解能力: 在众多LLM中,我选择DeepSeek进行探索,是因为它在代码生成、逻辑推理和长文本理解方面表现突出。生成Postman测试脚本(本质上是JavaScript)正是其擅长领域。它不仅能根据接口描述生成基础断言,还能理解“业务逻辑”。例如,你告诉它“登录成功后返回的token需要用于后续请求的鉴权”,它能帮你生成在Tests脚本中提取token并存入环境变量的代码。

组合的化学反应: Postman提供了标准化的“容器”和运行环境,DeepSeek则扮演了“超级助手”,负责填充这个容器里最耗费脑力的内容(用例与断言)。两者的结合,实现了“标准化流程”与“智能化内容生成”的完美互补。

2.2 整体工作流设计

我设计的自动化流程,核心是构建一个“AI中间件”。这个中间件的工作流可以概括为以下几步:

  1. 输入处理: 接收各种格式的接口文档(Swagger JSON/YAML、Markdown、甚至自然语言描述)。
  2. AI解析与增强: 利用DeepSeek的API,将文档内容、你的测试意图(如“需要测试成功和失败场景”、“重点验证数据一致性”)作为提示词(Prompt)输入,请求AI进行分析。
  3. 用例与脚本生成: AI根据分析结果,生成对应的Postman集合结构(包含文件夹、请求),并为每个请求编写预请求脚本和测试脚本(断言)。
  4. 输出与集成: 将AI生成的输出转换为标准的Postman Collection v2.1格式的JSON文件,直接导入Postman即可使用。

这个流程的关键在于 提示词工程 。你需要教会AI如何像一个经验丰富的测试工程师那样去思考。例如,不能仅仅让它“生成登录接口的测试”,而应该指令它:“请为登录接口生成三个测试用例:1. 使用正确用户名密码,断言状态码为200,响应体包含 token 字段且不为空,并将 token 值存入环境变量 auth_token ;2. 使用错误密码,断言状态码为401,错误信息字段匹配;3. 请求体缺失用户名,断言状态码为400。”

3. 实操搭建:从零构建你的AI测试助手

3.1 环境与依赖准备

这个方案不依赖复杂的部署,核心是编写一个脚本(Python或Node.js均可)作为桥梁。我以Python为例,因为它处理JSON和HTTP请求非常方便。

基础环境:

  • Python 3.8+
  • 一个可用的DeepSeek API密钥(从官方平台获取)。
  • Postman桌面版(用于导入和运行生成的集合)。

安装必要的Python库:

pip install requests python-dotenv
  • requests : 用于调用DeepSeek API。
  • python-dotenv : 用于管理API密钥等敏感信息,避免硬编码在脚本中。

项目结构规划:

ai_postman_generator/
├── .env                    # 存储DEEPSEEK_API_KEY
├── config.py               # 配置文件
├── prompt_templates/       # 存放不同场景的提示词模板
│   ├── basic_assertion.j2
│   ├── auth_flow.j2
│   └── data_driven.j2
├── generators/
│   ├── collection_generator.py # 核心生成器
│   └── postman_exporter.py     # 导出为Postman JSON
├── input/                  # 存放输入的接口文档
│   └── user_api.md
└── main.py                # 主执行脚本

3.2 核心脚本编写:与DeepSeek对话

首先,在 .env 文件中配置你的密钥:

DEEPSEEK_API_KEY=your_deepseek_api_key_here

然后,我们编写一个核心的对话函数。这里的关键是构建一个 系统提示词(System Prompt) ,来定义AI的角色和能力。

generators/collection_generator.py 核心片段:

import os
import requests
import json
from dotenv import load_dotenv

load_dotenv()

class DeepSeekClient:
    def __init__(self):
        self.api_key = os.getenv('DEEPSEEK_API_KEY')
        self.base_url = "https://api.deepseek.com/v1/chat/completions" # 请以DeepSeek官方最新API地址为准
        self.headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
    
    def generate_test_scripts(self, api_description, test_scenarios):
        """
        根据API描述和测试场景,生成Postman测试脚本。
        
        :param api_description: str, 接口的详细描述,包括URL、方法、请求体/参数、响应示例。
        :param test_scenarios: list, 测试场景列表,如 ['成功登录', '密码错误', '用户名缺失']
        :return: dict, 包含生成的请求和测试脚本的字典。
        """
        # 构建一个强大的系统提示词
        system_prompt = """你是一名资深的API测试开发工程师,精通Postman和JavaScript。你的任务是根据提供的接口文档和测试需求,生成可直接导入Postman使用的、完整的测试用例。
        
        输出要求:
        1. 你必须以纯JSON格式回应,且只包含这个JSON对象,不要有任何额外的解释、标记或代码块包裹。
        2. JSON结构必须严格遵循以下示例:
        {
          "collection_name": "生成的集合名称",
          "requests": [
            {
              "name": "测试用例名称,如: 登录-成功场景",
              "method": "GET/POST/PUT等",
              "url": "完整的请求URL,包含路径参数。使用{{base_url}}作为环境变量占位符。",
              "request_body": {}, // JSON格式的请求体,如果没有则为null
              "query_params": {}, // 查询参数对象
              "headers": {
                "Content-Type": "application/json"
                // 其他必要头部
              },
              "pre_request_script": "// JavaScript代码,用于请求前准备,如生成随机数据",
              "tests": "// JavaScript代码,即Postman的Tests脚本,包含pm.test断言"
            }
          ]
        }
        3. 在`tests`字段中,你必须编写全面且健壮的断言,至少包括:
           - 验证HTTP状态码 (pm.response.to.have.status)
           - 验证响应时间在合理范围内 (pm.expect(pm.response.responseTime).to.be.below(2000))
           - 验证响应体包含必要的字段 (pm.response.to.have.jsonBody, pm.expect(jsonData.field).to.eql(...))
           - 对于成功操作,如果返回了认证token或ID等,需要将其保存到环境变量中 (pm.environment.set)
           - 验证响应JSON Schema结构(如果条件允许)。
        4. 在`pre_request_script`中,如果需要动态数据(如随机邮箱、未来日期),请生成它。
        5. 所有硬编码的测试数据(如用户名、密码)应使用Postman的动态变量(如`{{username}}`)或环境变量占位,并在脚本注释中说明。
        """
        
        user_prompt = f"""
        接口文档如下:
        {api_description}
        
        请为这个接口生成以下测试场景:{', '.join(test_scenarios)}。
        请严格按照上述JSON格式输出。
        """
        
        payload = {
            "model": "deepseek-chat", # 根据实际可用模型调整
            "messages": [
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": user_prompt}
            ],
            "temperature": 0.2, # 低温度保证输出稳定、格式正确
            "max_tokens": 4000
        }
        
        try:
            response = requests.post(self.base_url, headers=self.headers, json=payload, timeout=60)
            response.raise_for_status()
            result = response.json()
            ai_output = result['choices'][0]['message']['content']
            
            # 清理输出,确保是纯JSON
            ai_output_cleaned = ai_output.strip()
            if ai_output_cleaned.startswith('```json'):
                ai_output_cleaned = ai_output_cleaned[7:-3].strip()
            elif ai_output_cleaned.startswith('```'):
                ai_output_cleaned = ai_output_cleaned[3:-3].strip()
                
            return json.loads(ai_output_cleaned)
            
        except requests.exceptions.RequestException as e:
            print(f"调用DeepSeek API失败: {e}")
            return None
        except json.JSONDecodeError as e:
            print(f"解析AI返回的JSON失败,原始内容为:\n{ai_output}")
            return None

注意: 上面的 system_prompt 是灵魂所在。它详细规定了AI的角色、输出格式和内容要求。 temperature 参数设置为较低值(0.2),是为了让AI的输出更确定、更符合格式要求,减少随机性。在实际使用中,你可能需要根据DeepSeek API的最新文档调整模型名称和端点URL。

3.3 将AI输出转换为Postman集合

DeepSeek生成的是我们自定义的中间JSON格式,需要将其转换为Postman官方集合格式(v2.1)。这是一个结构化的转换过程。

generators/postman_exporter.py 关键转换函数:

def convert_to_postman_collection(ai_output, base_env_vars=None):
    """
    将AI生成的中间格式转换为Postman Collection v2.1格式。
    """
    if base_env_vars is None:
        base_env_vars = {}
    
    collection = {
        "info": {
            "name": ai_output.get("collection_name", "AI-Generated Collection"),
            "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
        },
        "item": [] # 这里存放所有请求
    }
    
    for req in ai_output.get("requests", []):
        postman_item = {
            "name": req["name"],
            "request": {
                "method": req["method"],
                "header": [],
                "url": {
                    "raw": req["url"],
                    "host": ["{{base_url}}"], # 简化处理,实际应解析URL
                    "path": req["url"].split('?')[0].split('/')[3:] # 示例性解析
                }
            },
            "response": []
        }
        
        # 添加Headers
        for key, value in req.get("headers", {}).items():
            postman_item["request"]["header"].append({"key": key, "value": value})
        
        # 处理请求体
        if req.get("request_body"):
            postman_item["request"]["body"] = {
                "mode": "raw",
                "raw": json.dumps(req["request_body"], indent=2),
                "options": {"raw": {"language": "json"}}
            }
        
        # 处理查询参数
        if req.get("query_params"):
            # 这里需要将字典转换为Postman的query数组格式,代码略
            pass
        
        # **核心:添加预请求脚本和测试脚本**
        event_list = []
        if req.get("pre_request_script"):
            event_list.append({
                "listen": "prerequest",
                "script": {
                    "type": "text/javascript",
                    "exec": req["pre_request_script"].splitlines()
                }
            })
        if req.get("tests"):
            event_list.append({
                "listen": "test",
                "script": {
                    "type": "text/javascript",
                    "exec": req["tests"].splitlines()
                }
            })
        
        if event_list:
            postman_item["event"] = event_list
        
        collection["item"].append(postman_item)
    
    # 可以在这里添加一个全局的变量定义(如base_url的占位说明)
    # collection["variable"] = [ ... ]
    
    return collection

转换完成后,使用 json.dump 将collection字典写入一个 .postman_collection.json 文件,就可以直接拖入Postman导入了。

4. 高级技巧与场景化应用

4.1 设计高效的提示词模板

直接让AI从零生成一切,有时效果不稳定。我的经验是准备一些“模板”,让AI在模板基础上填充。这能极大提高生成结果的质量和一致性。

示例:针对RESTful CRUD接口的提示词模板 ( prompt_templates/crud_api.j2 )

你正在为标准的RESTful {{resource_name}} 资源接口生成Postman测试集合。
基础URL是: {{base_url}}/api/{{resource_name}}

已知接口规范:
- 创建(POST): 路径 `/`, 请求体: {{create_request_sample}}
- 查询列表(GET): 路径 `/`, 支持分页参数 ?page=1&size=10
- 查询详情(GET): 路径 `/{id}`
- 更新(PUT/PATCH): 路径 `/{id}`, 请求体: {{update_request_sample}}
- 删除(DELETE): 路径 `/{id}`

请生成一个完整的Postman集合,满足以下要求:
1. 为每个端点生成成功场景的测试请求。
2. 为创建(CREATE)和更新(UPDATE)请求,在`pre_request_script`中动态生成测试数据(如随机的`name`和`email`)。
3. 为创建(CREATE)请求的`tests`脚本中,必须将响应返回的`id`保存到环境变量`{{resource_name}}_id`中,以供后续的详情、更新、删除请求使用。
4. 为删除(DELETE)请求执行后,添加一个验证该资源是否已删除的后续GET请求断言(预期404)。
5. 所有断言需包含状态码、响应结构、关键字段值验证。

在脚本中,你可以使用Jinja2等模板引擎来渲染这些提示词,将 {{resource_name}} 等变量替换为实际值,再发送给DeepSeek。这样生成的集合,天然就具备了测试数据的连贯性和依赖性。

4.2 处理复杂断言:JSON Schema与数据关联

简单的状态码和字段存在性断言AI很容易生成。但复杂的业务逻辑断言需要更精细的指导。

场景:验证订单创建后,订单总价等于各商品单价*数量之和。

你可以在给AI的指令中明确写出断言逻辑:

在“创建订单”请求的Tests脚本中,你需要计算请求体中`items`数组里每个商品的`price` * `quantity`之和,并与响应体中`total_amount`字段的值进行比较断言。使用Postman的`pm.response.json()`和数组的`reduce`方法。

AI基于此生成的脚本可能会是:

// 在Tests脚本中
pm.test("订单总价计算正确", function () {
    var jsonData = pm.response.json();
    var requestData = JSON.parse(pm.request.body.raw);
    
    var calculatedTotal = requestData.items.reduce((sum, item) => {
        return sum + (item.price * item.quantity);
    }, 0);
    
    pm.expect(jsonData.total_amount).to.eql(calculatedTotal);
});

对于JSON Schema验证 ,你可以要求AI生成类似下面的断言,这比逐个字段检查更健壮:

pm.test("响应符合预定Schema", function () {
    var schema = {
        "type": "object",
        "required": ["id", "status", "created_at"],
        "properties": {
            "id": {"type": "number"},
            "status": {"type": "string", "enum": ["pending", "processing", "shipped"]},
            "created_at": {"type": "string", "format": "date-time"}
        }
    };
    pm.response.to.have.jsonSchema(schema);
});

4.3 集成到CI/CD流水线

生成的Postman集合最终要发挥作用,往往需要集成到自动化流水线中。你可以使用Postman的命令行工具 Newman 来运行集合。

我们的AI生成脚本可以扩展,在生成Postman集合JSON的同时,生成一个对应的 newman 运行脚本或 dockerfile

扩展 postman_exporter.py ,生成一个简单的运行脚本:

def generate_newman_run_script(collection_filename, environment_filename=None):
    script_content = f"""#!/bin/bash
# 使用Newman运行Postman集合
# 安装Newman: npm install -g newman newman-reporter-html

echo "正在运行API测试集合..."
COMMAND="newman run {collection_filename}"
if [ -f "{environment_filename}" ]; then
    COMMAND="$COMMAND -e {environment_filename}"
fi
COMMAND="$COMMAND -r cli,html --reporter-html-export ./test-report.html"

eval $COMMAND

# 检查退出码
if [ $? -eq 0 ]; then
    echo "所有测试通过!"
    exit 0
else
    echo "测试失败,请查看报告。"
    exit 1
fi
"""
    with open('run_tests.sh', 'w') as f:
        f.write(script_content)
    print("已生成自动化测试运行脚本: run_tests.sh")

这样,在CI/CD流水线(如Jenkins、GitLab CI)中,步骤就简化为:1. 调用你的Python脚本生成最新的Postman集合;2. 执行 bash run_tests.sh 。测试结果和HTML报告会自动生成。

5. 常见问题、避坑指南与效果评估

5.1 AI生成内容的常见问题与调试

在实际使用中,AI生成的内容不会总是完美的。以下是几个我踩过的坑和解决方案:

问题1:AI生成的JSON格式不正确或包含多余文本。

  • 原因: 即使有严格的系统提示,AI有时仍会在JSON前后添加解释性文字或标记错误的代码块。
  • 解决: 在解析AI响应时,像前面代码所示,加入更健壮的清理逻辑(检查并去除 ```json ``` )。同时,在提示词中反复强调“只输出JSON,不要任何其他文本”。如果问题持续,可以尝试在用户提示词末尾加上“记住,你的响应必须是且仅是一个有效的JSON对象。”

问题2:生成的JavaScript断言脚本有语法错误或使用了Postman不支持的API。

  • 原因: DeepSeek的训练数据可能包含不同版本的Postman或通用JavaScript语法。
  • 解决: 在系统提示词中明确指定Postman的沙盒环境支持哪些库(如 pm.* API, lodash , cheerio 等)。例如,可以加上:“你编写的JavaScript代码必须在Postman的测试沙盒环境中运行,主要使用 pm.expect (基于Chai)和 pm.response 进行断言。” 生成后,第一件事是在Postman中运行一下语法检查。

问题3:生成的测试数据过于单一或不符合业务规则。

  • 原因: AI可能只是简单复制示例中的数据。
  • 解决: 在提示词中明确要求动态生成数据。例如:“对于需要邮箱的字段,请在预请求脚本中使用 Math.random() 动态生成一个唯一的测试邮箱,如 testuser_<随机数>@example.com 。” 或者提供更具体的业务规则:“ status 字段只能从‘active’, ‘inactive’, ‘pending’中取值。”

5.2 效果评估与迭代

引入AI辅助后,如何评估其效果?我主要看几个指标:

  1. 用例生成速度: 过去手动编写一个包含5个复杂断言用例的请求可能需要15-30分钟。现在,从输入文档到生成可导入的集合,整个过程在2-5分钟内完成。
  2. 用例覆盖率(广度): AI能快速生成大量正向、反向用例(如参数缺失、类型错误、边界值),覆盖了那些容易被手动测试忽略的“显而易见”的无效场景,提升了测试集的完整性。
  3. 断言健壮性(深度): 通过精心设计的提示词,AI生成的断言往往比手动编写的更全面,会主动加入响应时间检查、JSON Schema验证等工程师可能因匆忙而遗漏的检查点。
  4. 维护成本: 当接口变更时,只需更新输入给AI的接口描述文档,重新运行生成脚本即可获得更新的测试集合,维护效率提升显著。

一个真实的对比: 我曾负责一个用户管理模块的测试,包含约12个接口。手动创建完整的Postman集合并编写所有断言,花了近一个工作日。使用初步版本的AI助手后,我将Swagger文档和测试场景描述输入,生成基础集合只用了10分钟。我随后花了1个小时左右检查和微调AI生成的脚本(主要是调整一些业务逻辑断言和动态变量)。整体效率提升了70%以上,而且生成的断言脚本风格一致,可作为团队内的代码规范参考。

5.3 安全与数据脱敏提醒

这是一个至关重要的实践点。在使用AI生成测试脚本时, 绝对不要 将真实的敏感信息(如生产数据库连接串、真实的用户凭证、内部密钥)放入提示词或生成的脚本中。

  • 在提示词中使用占位符: 始终使用 {{base_url}} , {{api_key}} , {{test_user}} 这样的占位符。
  • 生成后审查: 在将生成的集合导入Postman或提交到代码仓库前,务必人工审查一遍脚本,确保没有意外泄露的硬编码敏感信息。
  • 使用Postman环境: 在最终生成的集合中,将所有敏感或可变的配置都指向Postman的环境变量。你的AI生成脚本应该输出一个“干净”的集合,而将具体的变量值留给用户在Postman环境中配置。

将DeepSeek与Postman结合,不是要完全取代测试工程师,而是将工程师从重复劳动中解放出来,去做更有价值的事情——设计更巧妙的测试场景、探索更隐蔽的缺陷、理解更复杂的业务交互。这个过程本身,也是一个不断“训练”和优化你的“AI测试助手”的过程,你给它的提示词越精准,它反馈给你的内容就越实用。从这个角度看,我们每个人都在成为自己工作流的“提示词工程师”,而这,可能就是未来效率提升的常态。

更多推荐