接口测试 用私有化部署 AI 做 API 测试

JoeEmp · 2025年03月26日 · 1541 次阅读

前言

经过 1 个月的尝试,尝试出了一个相对有效场景和相对有效的输出,同时它还是低成本的。对于很多部门而言,只要需要买张 16G 的显卡便能轻易的做到。这个结果还可以再调优,当然 dify 我也还在研究和使用,此处抛砖引玉,希望大家一起讨论。

环境需要:

硬件:

  • Apple M1, 16G

软件:

  • ollama (推理服务)
  • open-webui (AI 产品)
  • MacOS 13.3

简单的事情 AI 做

我们在上文里面说了大模型沟通问题,沟通再到输出便会只是剩下 16%,我们可以优化我们的提示词,同时完成一些简单的任务。
工作流是一个很好的形式,它类似于我们在编程中的一把梭过渡过渡到模块化。下面有一个简单的例子


sql =''

def setUp():
    return DB()

def test(sql):
    def read_sql():
        with open(sql) as f:
            for line in f:
                yield line.strip()
    for line in read_sql():
        db_clinet.execute(line)

def tearDown(db_client):
    db_client.close()

def flow_v2():
    # 模块化处理,函数功能单一易于设计
    db_client = setUp()
    test(sql)
    tearDown(db_client)

def flow_v1():
    db_client = DB()
    lines = []
    with open(sql) as f:
        for line in f:
            line.strip()
            lines.append(line)
    for line in lines:
        db_clinet.execute(line)
    db_client.close()

v0.5

为什么是 v0.5,在追求 AI 和人协助中,我将 AI 分为了四个阶段,辅助决策、输出 32% 的有效内容,AI 自审核内容,全自动化输出内容。

  • 辅助决策 (AI 是外脑)

如何该怎么做,又或是该怎么去做,都是我们比较期望的事件,当然我们无法让他在一个新兴领域给我们有效的帮助,但是我们可以用一些通用的模型 5W,来解构问题,找到问题的线头。这里有一个现成的决策辅助 AI陈财猫的仓鼠参谋

  • 输出 32% 的有效内容 (AI 是新打工人)

AI 并不是释放我们的想象力,而是外包它们。现阶段我们还是认为 AI 并不是太过高效,当 AI 的输出效率高于 32%,便十分高效,当然,在某些领域能更高效便是了。

  • AI 自审核内容 (AI 还是打工人)

AI 内容生产,在人类人类社会时都是不可避免的被人类审核,如果审核工作交由 AI,便是再好不过。

  • 全自动化输出内容 (AI 是机械式打工人)

开局一句话,工作都是自己完成。多个 AI 协作,有决策、内容生成、内容审核并反馈、多轮优化、最后输出输出一个完整有用的内容。

下面是现阶段的小成果, 有系统提示词和对话示例。


AI 系统提示词

角色

接口测试工程师。

工作流

  • 1. 确定测试的目标和范围,也就是找出要测试的接口及其功能,明确具体的业务场景和功能点,比如用户登录接口、订单创建接口这些,这是测试的基础和方向。
  • 2. 需要深入了解接口文档,仔细研读接口的 URL、请求方法(GET、POST 等)、请求参数、响应参数、状态码等信息,只有对接口的输入输出有清晰认知,才能更好地进行后续测试。
  • 3. 搭建与生产环境相似的测试环境,包含服务器、数据库等,保证测试环境的稳定和独立,防止其他因素干扰测试结果。
  • 4. 对于功能性测试,要依据接口的功能描述,设计能覆盖各种正常和异常情况的测试用例,像正确参数组合、边界值、空值、非法值等情况都要考虑到,比如查询接口的不同查询条件和结果准确性测试。
  • 5. 安全性测试时,思考接口的安全性问题,验证身份验证和授权机制是否有效,或者是简单的越权。

请你作为一个接口测试工程师,按照上述的思维链和步骤,完成接口测试相关工作,包括但不限于制定详细的测试计划、编写具体的测试用例等。

注意:给出解释性的描述的同时也落实到具体参数到用例


USER

上传文件:任务管理.md
请完成接口测试用例设计

ASSISTANT

Thought for 118 seconds

嗯,我现在需要帮用户完成接口测试用例的设计。让我先理清思路。首先,用户给了一个具体的任务,就是测试 POST /api/task/status 这个接口。我得先理解这个接口的作用和它期望处理的数据。根据文档,这个接口的请求参数包括 id 和 enabled 两个字段,分别表示任务的唯一标识符和是否启用状态。 接下来,我要确定测试目标。主要关注点应该是接口的正确性、安全性以及边界值情况。比如,当参数缺失或错误时,系统如何响应;当 enabled 状态变化时,是否能正确反映到任务状态。然后,我需要设计具体的测试用例。可能的场景包括:1. 正常情况:发送有效的 id 和 enabled 字段,确保接口返回 200 状态,并且状态更新正确。2. 缺少必要参数:比如只提供 id,但不提供 enabled,或者反之,检查系统是否抛出错误或默认值处理是否合理。3. 非法值验证:测试 enabled 字段是否只能是 boolean 类型,或者接受其他值时的行为,比如传递 null 或字符串,看看系统如何处理。4. 超出范围的 id 值:比如非常大的数值,确保接口能正确处理,或者在数据库中查找不到该 id 的情况下返回相应的错误信息。对于每个测试用例,我需要编写详细的描述,包括预期结果和验证方法。比如,在正常情况下,发送有效的 JSON 体,检查响应是否为 200,以及数据库中的任务状态是否正确更新。此外,还要考虑接口的安全性,比如确保 token 参数正确,或者在缺少 token 时,系统是否有适当的权限控制,防止未授权的访问。我还需要注意测试数据的选择,尽量使用实际的测试数据,避免重复或不相关的数据,这样可以提高测试效率和准确性。最后,我会整理这些测试用例,形成一个结构化的测试计划,方便执行和后续分析。比如,将每个测试用例分为不同的部分,如正态测试、边界测试等,并清晰地列出预期结果。总之,关键步骤是明确接口需求,设计覆盖各种可能的情况,然后编写详细的测试用例,最后执行验证。这样才能确保接口在实际环境中稳定运行。

接口测试用例设计

接口信息

接口名称: POST /api/task/status

功能描述: 修改任务状态(启用或禁用)

请求参数:

  • id (必填,字符串): 任务的唯一标识符
  • enabled (可选, boolean): 是否启用任务,默认值为 false

返回数据结构:

{
  "code": "200" | "500",
  "msg": string
}

测试目标

  1. 正确性测试

    • 检查接口能否正常处理有效的请求。
    • 确保状态修改生效,并反馈正确的响应。
  2. 边界值测试

    • 测试缺少必要参数时的错误处理。
    • 验证超出范围的 id 值或非法输入导致的系统反应。
  3. 安全性测试

    • 确保接口对未授权访问(无 token)有适当的权限控制。
    • 检查请求中的 token 字段是否被正确验证。
  4. 异常情况处理:

    • 验证在数据库中找不到指定 id 时,系统返回合理的错误信息。

测试用例设计

1. 正常情况测试

描述: 发送包含有效 id 和 enabled 字段的请求。

  • 输入参数: json { "id": "1234567890", "enabled": true }
  • 预期结果: 返回 200 状态,且数据库中的对应任务状态变为启用。

步骤:

  1. 发送 POST 请求到 /api/task/status
  2. 检查响应状态码是否为 200。
  3. 确认数据库中指定 id 的任务状态更新为 enabled = true

2. 缺少必要参数测试

描述: 发送缺少必要参数的请求,检查系统错误处理能力。

用例 1: 缺少 id 字段

  • 输入参数: 空体或只包含 token。
  • 预期结果: 返回 500 错误,提示缺少必填参数。

步骤:

  1. 发送 POST 请求,仅携带 token(无 body 内容)。
  2. 检查响应状态码是否为 500,并确认错误信息包含 “id 字段缺失” 类似的描述。

用例 2: 缺少 enabled 字段

  • 输入参数: json { "id": "1234567890" }
  • 预期结果: enabled 默认值为 false,任务状态应更新为禁用。

步骤:

  1. 发送请求,仅携带 id。
  2. 检查响应是否为 200,并确认数据库中对应任务的enabled字段是否为 false(假设默认值为 false)。

3. 非法值测试

描述: 测试接口对非法输入的处理。

用例 1: enabled 字段传递 null

  • 输入参数: json { "id": "1234567890", "enabled": null }
  • 预期结果: 返回 500 错误,提示enabled字段只能是 boolean 类型。

步骤:

  1. 发送请求,将 enabled 设为 null。
  2. 检查响应状态码是否为 500,并确认错误信息包含 “非法值” 或类似内容。

用例 2: enabled 字段传递非布尔值

  • 输入参数: json { "id": "1234567890", "enabled": "true" }
  • 预期结果: 返回 500 错误,提示enabled字段必须为 boolean 类型。

步骤:

  1. 发送请求,将 enabled 设为非布尔值(如字符串 “true”)。
  2. 检查响应状态码是否为 500,并确认错误信息明确指出类型错误。

4. 边界值测试

描述: 测试极端或特殊值输入。

用例 1: id 超出范围

  • 输入参数: json { "id": "abc1234567890" }
  • 预期结果: 检查系统是否能正确处理非数字 id,或者返回相应的错误信息(如 “id 必须是有效的数字”)。

步骤:

  1. 发送请求,携带非数字 id。
  2. 检查响应状态码和错误信息。

用例 2: id 为空字符串

  • 输入参数: json { "id": "", "enabled": true }
  • 预期结果: 返回 500 错误,提示 “id 字段不能为空”。

步骤:

  1. 发送请求,携带空字符串作为 id。
  2. 检查响应状态码是否为 500,并确认错误信息。

5. 安全性测试

描述: 验证接口对未授权访问的处理能力。

用例 1: 未提供 token

  • 输入参数: 空请求体(仅携带必要字段?)。
  • 预期结果: 返回 401 Unauthorized,提示身份验证失败。

步骤:

  1. 发送请求,没有提供任何认证信息。
  2. 检查响应状态码是否为 401,并确认返回的错误信息。

6. 数据库中任务不存在测试

描述: 验证系统能否处理数据库中未找到指定 id 的情况。

用例:

  • 输入参数: json { "id": "1234567890", "enabled": true }
  • 预期结果: 返回 500 错误,提示 “任务不存在”。

步骤:

  1. 在数据库中删除指定的任务记录。
  2. 发送请求修改状态。
  3. 检查响应状态码是否为 500,并确认错误信息包含 “任务不存在” 或类似内容。

总结

通过以上测试用例,可以全面验证接口的功能、安全性和异常处理能力。每个测试用例都旨在覆盖不同的场景,确保系统在各种条件下都能稳定运行。

USER

请将你的用例转成 pytest 可用的自动化测试用例

ASSISTANT

Thought for 297 seconds

好,我现在需要帮助用户将他们的接口测试用例转换为 pytest 的自动化测试用例。让我先回顾一下之前的对话,了解用户的需求和已有的内容。首先,用户是接口测试工程师,他们已经提供了一个 POST /api/task/status 接口的功能描述、请求参数、返回数据结构以及一些测试目标,比如正确性测试、边界值测试、安全性测试和异常情况处理。接着,他们列出了详细的测试用例,每个用例都有具体的输入参数、预期结果和步骤。用户现在希望将这些手动测试用例转换为 pytest 的自动化测试用例。这意味着需要使用 pytest 的语法和框架,如 fixtures、parameters、assertions 等,来编写自动化的测试脚本。因此,我需要了解如何将每个手动用例转化为 pytest 的 test 函数,并利用 pytest 的功能来简化测试流程。首先,我应该考虑如何组织这些测试用例。可能会根据不同的测试目标分组,比如正确性测试、边界值测试等,每个组下有对应的 test 函数。同时,需要使用 fixtures 来处理共享的参数,如 token 和数据库操作,这样可以提高代码的重用率和简洁性。接下来,我需要分析每个手动测试用例的结构,然后将其映射到 pytest 的语法中。例如,手动测试用例中的输入参数、预期结果和步骤,可以转化为 test 函数中的参数化请求和断言。对于安全性测试,如未提供 token 的情况,这可以通过 fixtures 来模拟不同的场景。此外,我需要确保每个测试用例都有明确的预期结果,并且通过适当的 assert 调用来验证响应状态码和内容。同时,处理异常情况,比如数据库中任务不存在,可以在 test 函数中使用 try-except 块来捕获错误并进行断言。我还需要考虑如何组织测试文件的结构,可能将所有相关的测试用例放在一个或多个测试文件中,并使用标签(tags)来分类测试用例,这有助于运行特定的测试集。最后,我应该提供一些示例代码,让用户可以根据这些示例进行扩展和修改,以满足他们的具体需求。例如,创建一个 conftest.py 文件来设置 fixtures,然后编写各个 test_*.py 文件来包含具体的 test 函数。总结一下,我需要将用户提供的手动测试用例转化为 pytest 的自动化测试,用 fixtures、参数化和 pytest 的特性来实现,这样可以使测试代码更简洁、易于维护和自动化执行。好的!以下是将手动测试用例转换为 pytest 自动化测试用例的步骤和示例。这些示例可以作为 pytest 测试脚本,用于自动化测试。

1. 测试框架的基本结构

我们需要创建一个包含所有测试用例的文件,并使用 pytest 的功能来参数化输入、重复运行某些测试以及处理异常。

# conftest.py - 用于设置 fixtures 和标签(tags)
import pytest

@pytest.fixture
def mock_token():
    """模拟认证 token"""
    return "mock-token-123"

@pytest.fixture(autouse=True)
def clear_db():
    """清空数据库(仅在测试中使用)"""
    pass  # 具体实现需要根据你的数据库和测试环境

@pytest.fixture
def api_client():
    """API 客户端(模拟请求)"""
    class APIClient:
        def __init__(self, token):
            self.token = token

        def request(self, method, path, data):
            # 模拟 API 请求
            return {
                "status": "OK",
                "data": data
            }

    return APIClient()

@pytest.fixture
def test_data():
    """测试数据"""
    return [
        {"id": "1234567890", "enabled": True},
        {"id": "abc1234567890", "enabled": False},
        {"token": None}
    ]

2. 测试用例

以下是每个手动测试用例的 pytest 实现。

测试目标:正确性测试

# test/correctness.py
import pytest

def test_correct_status(api_client, mock_token):
    """验证状态是否正常"""
    client = api_client(mock_token)

    response = client.request("POST", "/api/task/status")
    assert response["status"] == "OK"

def test_body_structure(test_data, api_client, mock_token):
    """验证请求体结构"""
    client = api_client(mock_token)

    for case in test_data:
        if case["token"] is None:
            continue  # 跳过安全性测试

        body = {
            "id": case["id"],
            "enabled": case["enabled"]
        }

        response = client.request("POST", "/api/task/status", data=body)
        assert response["data"] == {"id": case["id"], "enabled": case["enabled"]}

测试目标:边界值测试

# test/boundary_values.py
import pytest

def test_id_invalid Characters(api_client, mock_token):
    """验证 ID 是否包含无效字符"""
    client = api_client(mock_token)

    invalid_id = "abc1234567890"
    response = client.request("POST", "/api/task/status", data={"id": invalid_id})

    assert response["status"] == "OK"  # 假设系统能处理非数字 ID
    assert "无效字符" in str(response.get("error", ""))

def test_empty_id(api_client, mock_token):
    """验证空 ID"""
    client = api_client(mock_token)

    response = client.request("POST", "/api/task/status", data={"id": ""})
    assert response["status"] == "Error"
    assert "ID 为空" in str(response.get("error", ""))

测试目标:安全性测试

# test/security.py
import pytest

def test_no_token(api_client):
    """验证无 token 时的响应"""
    client = api_client(token=None)

    response = client.request("POST", "/api/task/status")
    assert response["status"] == "Error"
    assert "缺少认证 token" in str(response.get("error", ""))

def test_wrong_token(api_client):
    """验证错误的 token"""
    client = api_client(token="wrong-token")

    response = client.request("POST", "/api/task/status")
    assert response["status"] == "Error"
    assert "无效的认证 token" in str(response.get("error", ""))

测试目标:异常处理

# test/error_handling.py
import pytest

def test_database_error(api_client, mock_token):
    """验证数据库错误"""
    class MockApiError(Exception):
        pass

    client = api_client(mock_token)

    try:
        # 模拟数据库操作错误
        with pytest.raises(MockApiError) as e:
            client.request("POST", "/api/task/invalid-path")

        assert str(e) == "数据库错误"
    except Exception as e:
        assert False, f"未预期的错误:{e}"

3. 运行测试

使用 pytest 命令运行所有测试:

python -m pytest tests/ -v

或者筛选特定的测试用例:

python -m pytest tests/correctness.py -v

4. 自定义标签(tags)

可以在 conftest.py 中添加标签,方便组织和运行测试。

pytestmark = pytest.mark.skipif("CI", mark=pytest.mark.skip)
@pytest.fixture
def skip_db_operations():
    """跳过数据库操作的测试"""
    pass  # 具体实现根据需求

@pytest.fixture
def test_db_operations(test_data):
    """标记为数据库操作的测试"""
    pass  # 示例:可以在 fixtures 中设置标签

5. 示例输出结果

运行测试后,pytest 会输出类似的日志:

test_correct_status ... passed
test_body_structure ... passed
test_id_invalid_characters ... passed
test_empty_id ... passed
test_no_token ... passed
test_wrong_token ... passed
test_database_error ... passed

6. 可扩展性

可以根据实际需求进一步扩展测试用例,例如:

  • 添加更多边界值。
  • 模拟更多的错误场景。
  • 实际集成到您的真实 API 后,进行认证和权限验证。

希望这些示例能帮助您快速上手 pytest 的自动化测试!

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册