Trae 助力测试效率提升:从 Swagger 到自动化测试的高效转化

564 阅读6分钟

Trae 助力测试人效提升:从 Swagger 到自动化测试的高效转化

我正在参加 Trae「超级体验官」创意实践征文,本文所使用的 Trae 免费下载链接:www.trae.ai/?utm_source…

作为一名测试人员,日常工作中,自动化测试的开发常常让我陷入繁琐的接口梳理与代码编写中。以往,我需要在页面上手动抓取接口,或者仔细研读开发人员提供的 Swagger 接口文档,再基于这些信息去编写测试代码。这个过程不仅耗时耗力,而且很容易因为疏忽而遗漏一些重要的接口细节,进而影响测试的全面性和准确性。

但最近,我发现 Trae 这款智能协作 AI IDE 为我的工作带来了意想不到的改变。

一、问题的起点:Swagger 文档与测试代码的“鸿沟”

Swagger 文档是开发人员精心编写的接口说明,它详细地列出了接口的请求方式、参数、返回值等关键信息。然而,对于测试人员来说,从这份文档到实际可运行的测试代码之间,存在着一道难以跨越的“鸿沟”。我们需要将文档中的信息逐一转化为具体的测试逻辑,这个过程不仅重复性高,而且容易出错。

二、Trae 的介入:脚本解析与 AI 协作

为了解决这一问题,我编写了一个脚本,用于解析 Swagger 文件。脚本的核心逻辑是分析 swagger.json 文件,通过不同的 tags,将对应 tags 的接口信息分别提取并放置在不同的文件中。这样做的好处有两个:一方面,后续将这些文件的内容传递给 Trae 时,可以减少上下文的压力,确保 AI 能够更高效地处理和生成代码;另一方面,未来还可以通过对比服务发布前后的 swagger.json 文件,快速找出哪些接口发生了变化,防止开发人员在我们不知情的情况下修改接口。

from typing import Dict, List, Optional
import json
from barbecue.polaris.api.log import Logger
import os

log = Logger().get_logger()


class SwaggerParser:
    def __init__(self, swagger_file_path: str):
        self.swagger_file_path = swagger_file_path
        self.swagger_data = self._load_swagger_file()

    def _load_swagger_file(self) -> Dict:
        """加载并解析Swagger文件"""
        try:
            with open(self.swagger_file_path, 'r') as f:
                return json.loads(f.read())
        except Exception as e:
            log.error(f"加载Swagger文件失败: {str(e)}")
            raise

    def get_tags(self) -> List[str]:
        """获取所有API标签"""
        return [tag['name'] for tag in self.swagger_data['tags']]

    def get_req_body(self, body_name: str) -> Dict:
        """获取请求体定义"""
        return self.swagger_data['definitions'][body_name]

    def _process_parameters(self, parameters: List[Dict], method: str, url: str) -> Dict:
        """处理API参数"""
        result = {}
        if not parameters:
            return result

        for param in parameters:
            param_in = param.get('in')
            if param_in == 'body':
                ref = param.get('schema', {}).get('$ref')
                if ref:
                    body_name = ref.split('/')[-1]
                    result['body'] = self.get_req_body(body_name)
                else:
                    log.warning(f"API {method} {url} 的body参数格式错误")
            elif param_in in ['query', 'path']:
                if 'params' not in result:
                    result['params'] = []
                result['params'].append(param)

        return result

    def _extract_api_info(self, url: str, method_info: Dict, method: str) -> Optional[Dict]:
        """提取API信息"""
        api_info = {
            'method': method.upper(),
            'url': url,
            'api_name': method_info.get('summary')
        }

        parameters = method_info.get('parameters', [])
        api_info.update(self._process_parameters(parameters, method.upper(), url))
        return api_info

    def get_tag_apis(self, tag: str) -> List[Dict]:
        """获取指定标签的所有API信息"""
        paths = self.swagger_data['paths']
        apis = []

        # 添加标签分隔符
        apis.append(f" 🎯 {'=' * 50} Tags:{tag} {'=' * 50} 🎯 ")

        for url, methods in paths.items():
            log.info(f"解析API: {url}")

            for method, info in methods.items():
                if info.get('tags', [None])[0] == tag:
                    api_info = self._extract_api_info(url, info, method)
                    if api_info:
                        apis.append(api_info)

        return apis


def print_api_info(apis: List[Dict]) -> None:
    """打印API信息"""
    for api in apis:
        if isinstance(api, str):  # 标签分隔符
            print(api)
        else:
            # print(json.dumps(api, ensure_ascii=False, indent=4))
            print(api)
            print("-" * 90)


def export_swagger_apis(swagger_file_path: str, output_dir: str) -> None:
    """
    导出所有tag的API到单独的文件
    :param swagger_file_path: swagger文件路径
    :param output_dir: 输出目录
    """
    # 确保输出目录存在
    os.makedirs(output_dir, exist_ok=True)

    # 初始化SwaggerParser
    parser = SwaggerParser(swagger_file_path)

    # 获取所有tags
    tags = parser.get_tags()
    tags = ['组织架构管理']
    log.info(f"发现tags: {tags}")

    # 为每个tag创建文件并写入API信息
    for tag in tags:
        output_file = os.path.join(output_dir, f"{tag}.json")
        apis = parser.get_tag_apis(tag)

        # 移除第一个元素(标签分隔符)
        if apis and isinstance(apis[0], str):
            apis = apis[1:]

        log.info(f"正在导出 {tag} 的API信息到 {output_file}")

        try:
            with open(output_file, 'w', encoding='utf-8') as f:
                json.dump(apis, f, ensure_ascii=False, indent=2)
            log.info(f"{tag} 的API信息导出成功")
        except Exception as e:
            log.error(f"导出 {tags} 的API信息失败: {str(e)}")


if __name__ == '__main__':
    swagger_file = 'xxxx_api_docs.json'
    output_directory = 'xxxxx/swagger'
    export_swagger_apis(swagger_file, output_directory)

在 Trae 的帮助下,我将这些解析后的接口信息传递给它。Trae 的强大之处在于它能够理解这些数据,并根据我之前编写代码的风格和规范,自动生成对应的模块功能代码。它就像是一个熟悉我编程习惯的助手,能够精准地按照我的要求输出代码。而我只需要在测试文件中将这些生成的代码进行简单的组装和调试,就可以快速构建出完整的自动化测试脚本。

image.png

三、Trae 的优势:提升测试人效与质量

通过这种方式,我明显感受到了工作效率的提升。以往需要花费数小时甚至数天去手动编写测试代码的工作,现在只需在 Trae 的协助下,通过脚本解析和代码生成,就能在短时间内完成。这不仅节省了大量的时间,还让我能够将更多的精力投入到测试策略的优化和测试结果的分析中。

更重要的是,Trae 生成的代码质量很高。它能够严格遵循我设定的代码规范,避免了因人为疏忽导致的代码错误。同时,它还能根据接口文档的变化,快速调整生成的代码,确保测试脚本的时效性和准确性。

四、Trae 的使用展示

在实际操作中,Trae 的界面简洁直观,操作也非常方便。我只需要将解析后的API文件以及历史代码引用给chat,选择后让其根据历史代码规范编写,Trae 就会迅速输出结果。而且,它还提供了丰富的代码编辑和调试功能,让我能够在生成代码的基础上进行进一步的优化和调整。

20250210191038_rec_.gif

五、总结与展望

Trae 的出现,无疑给测试工作注入了一股新活力。它不仅显著提升了工作效率,还让测试代码的质量和稳定性有了质的飞跃。以往,测试人员常常被繁琐的代码编写所牵绊,如今有了 Trae,我们终于可以将精力聚焦于测试的核心环节,真正回归到测试工作的本质。

展望未来,我对 Trae 满怀期待。希望它能持续优化和拓展功能,提供更智能的代码优化建议。我相信,随着 Trae 的不断成长,它将为测试人员带来更多惊喜,让我们的工作变得更加轻松高效。

总的来说,Trae 是一款非常出色的工具。它改变了我的工作方式,也让我对测试工作的未来充满信心。如果你也是一名测试人员,正在为接口测试的繁琐流程而烦恼,不妨试试 Trae。说不定它会成为你工作中的得力助手,带来意想不到的惊喜。