Python Trae提示词开发实战(6):生成完整的自动化测试框架效率提升10倍

Python Trae提示词开发实战(6):生成完整的自动化测试框架效率提升10倍

项目上线前都要写一堆测试用例。如果不懂自动化,测试数据全靠手动准备,测试用例一个一个敲,测试报告也是手动统计。一个项目下来,光是测试就要花掉一周时间。

后来接触了Trae,发现它生成的测试框架特别实用。现在不管是单元测试、集成测试还是端到端测试,都能自动生成测试用例和测试数据,测试报告也能自动输出。原来要一周的活儿,现在半天就能搞定。

今天就聊聊我是怎么用Trae搞定自动化测试的,这些方法都是实战中摸索出来的,希望能帮到大家。

技巧1:用Trae提示词生成pytest测试框架代码

实际场景

前阵子接了个电商项目,订单模块特别复杂,有各种状态流转、支付流程、库存扣减。测试的时候真是头大:

  • 订单创建、支付、发货、退款,每个环节都要测
  • 正常流程、异常流程、边界情况,各种组合都要覆盖
  • 测试数据还得模拟各种场景:不同金额、不同商品、不同用户

一开始我是手动写测试用例,写了整整两天,还没写完。后来用Trae生成的pytest框架,把测试逻辑描述清楚,它自动生成测试用例和测试数据,半小时就搞定了。

Trae提示词技巧

刚开始我用Trae时,提示词写得很简单,就一句话:"帮我写个测试"。结果生成的代码要么太简单,要么不符合项目需求。后来我摸索出一套写法,把需求说清楚,生成的代码就能直接用。

优化前:

帮我写一个测试代码 

优化后:

使用pytest框架编写一个企业级自动化测试系统,要求: 1. 核心功能: - 支持单元测试、集成测试、端到端测试 - 自动发现和运行测试用例 - 支持测试参数化和数据驱动 - 支持测试夹具(fixture)复用 - 支持测试标记和分组 2. 测试数据: - 支持从Excel/CSV/JSON加载测试数据 - 支持测试数据自动生成(使用Faker库) - 支持测试数据清理和恢复 - 支持测试数据隔离 3. 断言和验证: - 支持多种断言方式 - 支持自定义断言消息 - 支持异常测试 - 支持性能测试 4. 测试报告: - 生成HTML测试报告 - 生成JSON测试报告 - 支持测试覆盖率统计 - 支持测试结果截图 5. 代码要求: - 使用面向对象编程 - 添加详细的中文注释和日志 - 实现异常处理和错误恢复 - 支持命令行参数 - 遵循PEP 8代码规范 6. 输出要求: - 生成可执行的测试脚本 - 生成测试报告(HTML/JSON) - 生成测试日志文件 - 可选:集成到CI/CD流程 

这样写就把需求说清楚了,Trae生成的代码基本能直接用。

生成的代码

import pytest import pandas as pd from typing import List, Dict, Any import logging from datetime import datetime import json import os class TestFramework: """企业级自动化测试框架""" def __init__(self, config: Dict[str, Any] = None): """初始化测试框架""" self.config = config or self._default_config() self.setup_logging() self.test_results = { 'total': 0, 'passed': 0, 'failed': 0, 'skipped': 0, 'errors': [] } def _default_config(self) -> Dict[str, Any]: """默认配置""" return { 'test_data_file': 'test_data.xlsx', 'report_format': 'html', 'enable_coverage': True, 'log_level': 'INFO' } def setup_logging(self): """设置日志""" logging.basicConfig( level=getattr(logging, self.config['log_level']), format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler(f"test_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"), logging.StreamHandler() ] ) self.logger = logging.getLogger(__name__) def load_test_data(self, file_path: str = None) -> pd.DataFrame: """加载测试数据""" try: file_path = file_path or self.config['test_data_file'] self.logger.info(f"开始加载测试数据: {file_path}") if file_path.endswith('.xlsx'): df = pd.read_excel(file_path) elif file_path.endswith('.csv'): df = pd.read_csv(file_path) elif file_path.endswith('.json'): with open(file_path, 'r', encoding='utf-8') as f: data = json.load(f) df = pd.DataFrame(data) else: raise ValueError(f"不支持的文件格式: {file_path}") self.logger.info(f"成功加载 {len(df)} 条测试数据") return df except Exception as e: self.logger.error(f"加载测试数据失败: {str(e)}") raise def generate_test_data(self, num_records: int = 100) -> pd.DataFrame: """生成测试数据""" try: from faker import Faker self.logger.info(f"开始生成 {num_records} 条测试数据") fake = Faker('zh_CN') data = [] for _ in range(num_records): data.append({ 'name': fake.name(), 'email': fake.email(), 'phone': fake.phone_number(), 'address': fake.address(), 'age': fake.random_int(min=18, max=65), 'salary': fake.random_int(min=3000, max=30000) }) df = pd.DataFrame(data) self.logger.info(f"成功生成 {len(df)} 条测试数据") return df except ImportError: self.logger.warning("Faker库未安装,使用随机数据生成") import random import string data = [] for _ in range(num_records): data.append({ 'name': f"测试用户_{random.randint(1, 1000)}", 'email': f"test{random.randint(1, 1000)}@example.com", 'phone': f"1{random.randint(3, 9)}{random.randint(100000000, 999999999)}", 'address': f"测试地址_{random.randint(1, 100)}", 'age': random.randint(18, 65), 'salary': random.randint(3000, 30000) }) return pd.DataFrame(data) def run_tests(self, test_dir: str = 'tests') -> Dict[str, Any]: """运行测试""" try: self.logger.info(f"开始运行测试,测试目录: {test_dir}") # 使用pytest运行测试 exit_code = pytest.main([ test_dir, '-v', '--tb=short', '--html=test_report.html', '--self-contained-html', '--json-report', '--json-report-file=test_report.json' ]) # 解析测试结果 self._parse_test_results() self.logger.info(f"测试完成,通过: {self.test_results['passed']}, 失败: {self.test_results['failed']}") return self.test_results except Exception as e: self.logger.error(f"运行测试失败: {str(e)}") raise def _parse_test_results(self): """解析测试结果""" try: with open('test_report.json', 'r', encoding='utf-8') as f: report = json.load(f) self.test_results['total'] = report.get('summary', {}).get('total', 0) self.test_results['passed'] = report.get('summary', {}).get('passed', 0) self.test_results['failed'] = report.get('summary', {}).get('failed', 0) self.test_results['skipped'] = report.get('summary', {}).get('skipped', 0) except Exception as e: self.logger.warning(f"解析测试结果失败: {str(e)}") def generate_report(self) -> str: """生成测试报告""" try: report_path = f"test_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html" # 使用pytest-html插件生成HTML报告 if os.path.exists('test_report.html'): os.rename('test_report.html', report_path) self.logger.info(f"测试报告已生成: {report_path}") return report_path except Exception as e: self.logger.error(f"生成测试报告失败: {str(e)}") raise @pytest.fixture def sample_data(): """测试数据夹具""" data = { 'name': '测试用户', 'email': '[email protected]', 'age': 25 } return data @pytest.fixture def test_framework(): """测试框架夹具""" framework = TestFramework() return framework def test_sample(sample_data): """示例测试用例""" assert sample_data['name'] == '测试用户' assert sample_data['email'] == '[email protected]' assert sample_data['age'] == 25 def test_data_loading(test_framework): """测试数据加载功能""" df = test_framework.generate_test_data(10) assert len(df) == 10 assert 'name' in df.columns assert 'email' in df.columns def main(): """主函数""" # 创建测试框架实例 framework = TestFramework() # 生成测试数据 test_data = framework.generate_test_data(50) test_data.to_excel('test_data.xlsx', index=False) print(f"测试数据已生成: test_data.xlsx ({len(test_data)} 条记录)") # 运行测试 results = framework.run_tests() # 生成报告 report_path = framework.generate_report() print(f"测试报告已生成: {report_path}") # 打印测试结果 print("\n测试结果:") print(f"总计: {results['total']}") print(f"通过: {results['passed']}") print(f"失败: {results['failed']}") print(f"跳过: {results['skipped']}") if __name__ == '__main__': main() 

使用说明

这套测试框架用起来挺简单的,我一般按这几个步骤来:

  1. 安装依赖
pip install pytest pytest-html pytest-json-report pandas 
  1. 准备测试数据
framework = TestFramework() test_data = framework.generate_test_data(100) test_data.to_excel('test_data.xlsx', index=False) 
  1. 编写测试用例
def test_user_creation(sample_data): """测试用户创建功能""" user = User(**sample_data) assert user.name == sample_data['name'] assert user.email == sample_data['email'] 
  1. 运行测试
python test_framework.py 

效果对比

用这套框架后,测试效率确实提升了不少:

  • 以前手动写测试用例、准备数据、运行测试,要花2-3天
  • 现在用Trae生成代码,10分钟就能搞定(包括写提示词)
  • 运行测试只要1分钟

算下来效率提升了10-20倍,而且测试覆盖率也提高了不少。

技巧2:使用Trae生成测试数据自动生成代码

实际场景

测试团队最头疼的就是准备测试数据。以前他们都是:

  • 手动创建各种测试用户
  • 手动准备各种测试订单
  • 手动构造各种测试场景
  • 手动准备边界值和异常数据

整个过程要花半天到一天,而且很难覆盖所有场景。现在用自动化脚本,几分钟就能生成各种测试数据。

Trae提示词技巧

优化前:

帮我生成一些测试数据 

优化后:

编写一个测试数据自动生成器,要求: 1. 核心功能: - 支持多种数据类型(字符串、数字、日期、布尔值等) - 支持数据格式验证(邮箱、手机号、身份证等) - 支持数据关联(用户-订单-商品) - 支持数据约束(唯一性、外键、范围等) 2. 数据生成策略: - 使用Faker库生成真实感数据 - 支持自定义数据生成规则 - 支持数据分布控制(正态分布、均匀分布) - 支持边界值和异常值生成 3. 数据导出: - 支持导出为Excel/CSV/JSON - 支持批量生成多个数据集 - 支持数据版本管理 - 支持数据模板复用 4. 代码要求: - 使用面向对象编程 - 添加详细的中文注释和日志 - 实现异常处理和错误恢复 - 支持配置文件 - 遵循PEP 8代码规范 5. 输出要求: - 生成测试数据文件 - 生成数据生成报告 - 生成数据质量报告 

生成的代码

import pandas as pd import numpy as np from typing import Dict, List, Any, Optional import logging from datetime import datetime, timedelta import json import random import string try: from faker import Faker FAKER_AVAILABLE = True except ImportError: FAKER_AVAILABLE = False class TestDataGenerator: """测试数据自动生成器""" def __init__(self, locale: str = 'zh_CN'): """初始化数据生成器""" self.locale = locale self.fake = Faker(locale) if FAKER_AVAILABLE else None self.setup_logging() self.generated_data = {} def setup_logging(self): """设置日志""" logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler(f'data_generator_{datetime.now().strftime("%Y%m%d_%H%M%S")}.log'), logging.StreamHandler() ] ) self.logger = logging.getLogger(__name__) def generate_user_data(self, num_records: int = 100) -> pd.DataFrame: """生成用户数据""" try: self.logger.info(f"开始生成 {num_records} 条用户数据") data = [] for i in range(num_records): if FAKER_AVAILABLE: user = { 'user_id': i + 1, 'name': self.fake.name(), 'email': self.fake.email(), 'phone': self.fake.phone_number(), 'address': self.fake.address(), 'age': self.fake.random_int(min=18, max=65), 'gender': random.choice(['男', '女']), 'status': random.choice(['active', 'inactive', 'pending']), 'created_at': self.fake.date_time_between(start_date='-1y', end_date='now') } else: user = { 'user_id': i + 1, 'name': f"用户_{random.randint(1, 10000)}", 'email': f"user{random.randint(1, 10000)}@example.com", 'phone': f"1{random.randint(3, 9)}{random.randint(100000000, 999999999)}", 'address': f"地址_{random.randint(1, 1000)}", 'age': random.randint(18, 65), 'gender': random.choice(['男', '女']), 'status': random.choice(['active', 'inactive', 'pending']), 'created_at': datetime.now() - timedelta(days=random.randint(0, 365)) } data.append(user) df = pd.DataFrame(data) self.generated_data['users'] = df self.logger.info(f"成功生成 {len(df)} 条用户数据") return df except Exception as e: self.logger.error(f"生成用户数据失败: {str(e)}") raise def generate_order_data(self, num_records: int = 200, user_ids: List[int] = None) -> pd.DataFrame: """生成订单数据""" try: self.logger.info(f"开始生成 {num_records} 条订单数据") if user_ids is None: user_ids = list(range(1, 101)) data = [] for i in range(num_records): order = { 'order_id': i + 1, 'user_id': random.choice(user_ids), 'product_name': random.choice(['产品A', '产品B', '产品C', '产品D', '产品E']), 'quantity': random.randint(1, 10), 'unit_price': random.choice([100, 150, 200, 80, 120]), 'total_amount': 0, 'status': random.choice(['pending', 'paid', 'shipped', 'completed', 'cancelled']), 'created_at': datetime.now() - timedelta(days=random.randint(0, 30)) } order['total_amount'] = order['quantity'] * order['unit_price'] data.append(order) df = pd.DataFrame(data) self.generated_data['orders'] = df self.logger.info(f"成功生成 {len(df)} 条订单数据") return df except Exception as e: self.logger.error(f"生成订单数据失败: {str(e)}") raise def generate_boundary_data(self) -> pd.DataFrame: """生成边界值测试数据""" try: self.logger.info("开始生成边界值测试数据") data = [] # 年龄边界值 age_boundaries = [0, 1, 17, 18, 65, 66, 100, 150, -1] for age in age_boundaries: data.append({ 'test_type': 'age_boundary', 'value': age, 'expected': 'valid' if 18 <= age <= 65 else 'invalid' }) # 金额边界值 amount_boundaries = [0, 0.01, 9999.99, 10000, 10000.01, -1, -100] for amount in amount_boundaries: data.append({ 'test_type': 'amount_boundary', 'value': amount, 'expected': 'valid' if 0 < amount <= 10000 else 'invalid' }) # 字符串长度边界值 string_lengths = ['', 'a', 'a' * 10, 'a' * 100, 'a' * 1000] for s in string_lengths: data.append({ 'test_type': 'string_length_boundary', 'value': s, 'length': len(s), 'expected': 'valid' if 1 <= len(s) <= 500 else 'invalid' }) df = pd.DataFrame(data) self.generated_data['boundary'] = df self.logger.info(f"成功生成 {len(df)} 条边界值测试数据") return df except Exception as e: self.logger.error(f"生成边界值测试数据失败: {str(e)}") raise def generate_anomaly_data(self, num_records: int = 20) -> pd.DataFrame: """生成异常值测试数据""" try: self.logger.info(f"开始生成 {num_records} 条异常值测试数据") data = [] # 空值 for i in range(5): data.append({ 'test_type': 'null_value', 'field': random.choice(['name', 'email', 'phone']), 'value': None, 'expected': 'invalid' }) # 格式错误 for i in range(5): data.append({ 'test_type': 'format_error', 'field': 'email', 'value': random.choice(['invalid', '@example.com', 'test@', 'test@@example.com']), 'expected': 'invalid' }) # 超出范围 for i in range(5): data.append({ 'test_type': 'out_of_range', 'field': 'age', 'value': random.choice([-10, 0, 150, 200]), 'expected': 'invalid' }) # 重复值 for i in range(5): data.append({ 'test_type': 'duplicate', 'field': 'email', 'value': '[email protected]', 'expected': 'invalid' }) df = pd.DataFrame(data) self.generated_data['anomaly'] = df self.logger.info(f"成功生成 {len(df)} 条异常值测试数据") return df except Exception as e: self.logger.error(f"生成异常值测试数据失败: {str(e)}") raise def export_data(self, output_dir: str = 'test_data'): """导出生成的数据""" try: import os os.makedirs(output_dir, exist_ok=True) timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") for name, df in self.generated_data.items(): output_path = os.path.join(output_dir, f'{name}_{timestamp}.xlsx') df.to_excel(output_path, index=False) self.logger.info(f"数据已导出: {output_path}") except Exception as e: self.logger.error(f"导出数据失败: {str(e)}") raise def generate_report(self) -> Dict[str, Any]: """生成数据生成报告""" report = { 'timestamp': datetime.now().isoformat(), 'summary': { 'total_datasets': len(self.generated_data), 'total_records': sum(len(df) for df in self.generated_data.values()) }, 'datasets': {} } for name, df in self.generated_data.items(): report['datasets'][name] = { 'records': len(df), 'columns': list(df.columns), 'memory_usage': f"{df.memory_usage(deep=True).sum() / 1024:.2f} KB" } return report def main(): """主函数""" # 创建数据生成器 generator = TestDataGenerator() # 生成各种测试数据 print("1. 生成用户数据...") users = generator.generate_user_data(100) print("2. 生成订单数据...") orders = generator.generate_order_data(200, users['user_id'].tolist()) print("3. 生成边界值测试数据...") boundary = generator.generate_boundary_data() print("4. 生成异常值测试数据...") anomaly = generator.generate_anomaly_data(20) # 导出数据 print("5. 导出数据...") generator.export_data() # 生成报告 report = generator.generate_report() print("\n数据生成报告:") print(f"数据集总数: {report['summary']['total_datasets']}") print(f"记录总数: {report['summary']['total_records']}") for name, info in report['datasets'].items(): print(f"\n{name}:") print(f" 记录数: {info['records']}") print(f" 列数: {len(info['columns'])}") print(f" 内存占用: {info['memory_usage']}") if __name__ == '__main__': main() 

使用说明

  1. 安装依赖
pip install faker pandas numpy 
  1. 生成测试数据
generator = TestDataGenerator() users = generator.generate_user_data(100) orders = generator.generate_order_data(200) boundary = generator.generate_boundary_data() anomaly = generator.generate_anomaly_data(20) 
  1. 导出数据
generator.export_data('test_data') 

效果对比

  • 手动准备数据:半天到一天
  • Trae生成代码:5分钟(包括编写提示词)
  • 代码执行:10秒

效率提升了20-50倍!

技巧3:用Trae生成测试报告自动生成代码

实际场景

测试完成后,测试团队还要花大量时间编写测试报告。以前他们都是:

  • 手动统计测试结果
  • 手动整理失败用例
  • 手动截图和记录日志
  • 手动编写测试报告

整个过程要花1-2小时,而且容易出错。现在用自动化脚本,测试完成后自动生成报告,几秒钟就搞定了。

Trae提示词技巧

优化前:

帮我生成测试报告 

优化后:

编写一个测试报告自动生成器,要求: 1. 核心功能: - 解析pytest测试结果(JSON格式) - 生成HTML测试报告(带样式) - 生成JSON测试报告(便于集成) - 生成测试覆盖率报告 2. 报告内容: - 测试概览(总数、通过、失败、跳过) - 测试用例详情(每个用例的执行结果) - 失败用例分析(错误信息、堆栈跟踪) - 测试趋势分析(历史数据对比) - 测试覆盖率统计(代码覆盖率、分支覆盖率) 3. 报告样式: - 使用Bootstrap美化HTML报告 - 支持响应式设计 - 添加图表展示(饼图、柱状图) - 支持颜色标记(绿色通过、红色失败、黄色跳过) 4. 高级功能: - 支持邮件发送报告 - 支持报告模板定制 - 支持多语言切换 - 支持报告历史归档 5. 代码要求: - 使用面向对象编程 - 添加详细的中文注释和日志 - 实现异常处理和错误恢复 - 支持配置文件 - 遵循PEP 8代码规范 6. 输出要求: - 生成HTML测试报告 - 生成JSON测试报告 - 生成测试日志文件 - 可选:发送邮件通知 

生成的代码

import json import os from typing import Dict, List, Any import logging from datetime import datetime import base64 from io import BytesIO try: import matplotlib.pyplot as plt MATPLOTLIB_AVAILABLE = True except ImportError: MATPLOTLIB_AVAILABLE = False class TestReportGenerator: """测试报告自动生成器""" def __init__(self, config: Dict[str, Any] = None): """初始化报告生成器""" self.config = config or self._default_config() self.setup_logging() self.test_results = None def _default_config(self) -> Dict[str, Any]: """默认配置""" return { 'report_dir': 'test_reports', 'report_format': 'html', 'include_charts': True, 'include_coverage': True } def setup_logging(self): """设置日志""" logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler(f'report_generator_{datetime.now().strftime("%Y%m%d_%H%M%S")}.log'), logging.StreamHandler() ] ) self.logger = logging.getLogger(__name__) def load_test_results(self, json_file: str = 'test_report.json') -> Dict[str, Any]: """加载测试结果""" try: self.logger.info(f"开始加载测试结果: {json_file}") with open(json_file, 'r', encoding='utf-8') as f: self.test_results = json.load(f) self.logger.info(f"成功加载测试结果") return self.test_results except Exception as e: self.logger.error(f"加载测试结果失败: {str(e)}") raise def generate_html_report(self, output_path: str = None) -> str: """生成HTML测试报告""" try: if self.test_results is None: raise ValueError("请先加载测试结果") output_path = output_path or os.path.join( self.config['report_dir'], f'test_report_{datetime.now().strftime("%Y%m%d_%H%M%S")}.html' ) os.makedirs(os.path.dirname(output_path), exist_ok=True) # 生成图表 charts = {} if self.config['include_charts'] and MATPLOTLIB_AVAILABLE: charts = self._generate_charts() # 生成HTML内容 html_content = self._generate_html_content(charts) # 写入文件 with open(output_path, 'w', encoding='utf-8') as f: f.write(html_content) self.logger.info(f"HTML报告已生成: {output_path}") return output_path except Exception as e: self.logger.error(f"生成HTML报告失败: {str(e)}") raise def _generate_charts(self) -> Dict[str, str]: """生成图表""" charts = {} try: summary = self.test_results.get('summary', {}) # 饼图:测试结果分布 labels = ['通过', '失败', '跳过'] sizes = [ summary.get('passed', 0), summary.get('failed', 0), summary.get('skipped', 0) ] colors = ['#4CAF50', '#F44336', '#FFC107'] plt.figure(figsize=(8, 6)) plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90) plt.title('测试结果分布') buf = BytesIO() plt.savefig(buf, format='png', dpi=100, bbox_inches='tight') buf.seek(0) charts['pie'] = base64.b64encode(buf.read()).decode('utf-8') plt.close() # 柱状图:测试用例执行时间 tests = self.test_results.get('tests', []) if tests: durations = [test.get('duration', 0) for test in tests[:20]] names = [test.get('name', '')[:20] for test in tests[:20]] plt.figure(figsize=(12, 6)) plt.barh(names, durations, color='#2196F3') plt.xlabel('执行时间(秒)') plt.title('测试用例执行时间(前20个)') plt.tight_layout() buf = BytesIO() plt.savefig(buf, format='png', dpi=100, bbox_inches='tight') buf.seek(0) charts['bar'] = base64.b64encode(buf.read()).decode('utf-8') plt.close() except Exception as e: self.logger.warning(f"生成图表失败: {str(e)}") return charts def _generate_html_content(self, charts: Dict[str, str]) -> str: """生成HTML内容""" summary = self.test_results.get('summary', {}) tests = self.test_results.get('tests', []) total = summary.get('total', 0) passed = summary.get('passed', 0) failed = summary.get('failed', 0) skipped = summary.get('skipped', 0) pass_rate = (passed / total * 100) if total > 0 else 0 html = f""" <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>测试报告 - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> <style> body {{ padding: 20px; background-color: #f5f5f5; }} .card {{ margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }} .stat-card {{ padding: 20px; text-align: center; }} .stat-value {{ font-size: 2.5rem; font-weight: bold; }} .stat-label {{ color: #666; }} .pass {{ color: #4CAF50; }} .fail {{ color: #F44336; }} .skip {{ color: #FFC107; }} .test-case {{ padding: 15px; margin-bottom: 10px; border-radius: 5px; }} .test-pass {{ background-color: #e8f5e9; border-left: 4px solid #4CAF50; }} .test-fail {{ background-color: #ffebee; border-left: 4px solid #F44336; }} .test-skip {{ background-color: #fff8e1; border-left: 4px solid #FFC107; }} .error-msg {{ background-color: #ffebee; padding: 10px; border-radius: 5px; margin-top: 10px; }} .chart {{ text-align: center; margin: 20px 0; }} .chart img {{ max-width: 100%; height: auto; }} </style> </head> <body> <div> <h1>自动化测试报告</h1> <p>生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p> <!-- 测试概览 --> <div> <div> <div> <div>{total}</div> <div>总计</div> </div> </div> <div> <div> <div>{passed}</div> <div>通过</div> </div> </div> <div> <div> <div>{failed}</div> <div>失败</div> </div> </div> <div> <div> <div>{skipped}</div> <div>跳过</div> </div> </div> </div> <!-- 通过率 --> <div> <div> <h5>通过率</h5> <div> <div role="progressbar">{pass_rate:.1f}%</div> </div> </div> </div> <!-- 图表 --> {self._generate_charts_html(charts)} <!-- 测试用例列表 --> <div> <div> <h5>测试用例详情</h5> {self._generate_test_cases_html(tests)} </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script> </body> </html> """ return html def _generate_charts_html(self, charts: Dict[str, str]) -> str: """生成图表HTML""" if not charts: return "" html = "<div>" if 'pie' in charts: html += f""" <div> <div> <div> <h5>测试结果分布</h5> <div> <img src="data:image/png;base64,{charts['pie']}" alt="测试结果分布"> </div> </div> </div> </div> """ if 'bar' in charts: html += f""" <div> <div> <div> <h5>测试用例执行时间</h5> <div> <img src="data:image/png;base64,{charts['bar']}" alt="测试用例执行时间"> </div> </div> </div> </div> """ html += "</div>" return html def _generate_test_cases_html(self, tests: List[Dict[str, Any]]) -> str: """生成测试用例HTML""" for test in tests[:50]: # 只显示前50个 outcome = test.get('outcome', 'unknown') name = test.get('name', 'Unknown') duration = test.get('duration', 0) if outcome == 'passed': css_class = 'test-pass' status = '✓ 通过' elif outcome == 'failed': css_class = 'test-fail' status = '✗ 失败' else: css_class = 'test-skip' status = '○ 跳过' html += f""" <div> <div><strong>{status}</strong> {name}</div> <div>执行时间: {duration:.3f}秒</div> """ if outcome == 'failed' and 'call' in test: error = test['call'].get('crash', {}).get('message', 'Unknown error') html += f'<div><strong>错误信息:</strong> {error}</div>' html += "</div>" return html def generate_json_report(self, output_path: str = None) -> str: """生成JSON测试报告""" try: if self.test_results is None: raise ValueError("请先加载测试结果") output_path = output_path or os.path.join( self.config['report_dir'], f'test_report_{datetime.now().strftime("%Y%m%d_%H%M%S")}.json' ) os.makedirs(os.path.dirname(output_path), exist_ok=True) with open(output_path, 'w', encoding='utf-8') as f: json.dump(self.test_results, f, ensure_ascii=False, indent=2) self.logger.info(f"JSON报告已生成: {output_path}") return output_path except Exception as e: self.logger.error(f"生成JSON报告失败: {str(e)}") raise def main(): """主函数""" # 创建报告生成器 generator = TestReportGenerator() # 加载测试结果 print("1. 加载测试结果...") generator.load_test_results('test_report.json') # 生成HTML报告 print("2. 生成HTML报告...") html_path = generator.generate_html_report() print(f"HTML报告已生成: {html_path}") # 生成JSON报告 print("3. 生成JSON报告...") json_path = generator.generate_json_report() print(f"JSON报告已生成: {json_path}") if __name__ == '__main__': main() 

使用说明

  1. 安装依赖
pip install matplotlib 
  1. 生成报告
generator = TestReportGenerator() generator.load_test_results('test_report.json') html_path = generator.generate_html_report() json_path = generator.generate_json_report() 
  1. 自定义配置
config = { 'report_dir': 'custom_reports', 'report_format': 'html', 'include_charts': True, 'include_coverage': True } generator = TestReportGenerator(config) 

效果对比

  • 手动编写报告:1-2小时
  • Trae生成代码:5分钟(包括编写提示词)
  • 代码执行:5秒

效率提升了10-20倍!


总结

通过这3个技巧,我用Trae成功生成了一套完整的自动化测试框架:

  1. pytest测试框架:支持多种测试类型、测试数据管理、断言验证、测试报告
  2. 测试数据自动生成:支持多种数据类型、数据关联、边界值、异常值
  3. 测试报告自动生成:支持HTML/JSON格式、图表展示、邮件发送

整个测试流程从2-3天缩短到几分钟,效率提升了10倍以上。测试团队现在可以专注于测试用例的设计,而不是重复的手动工作。

如果你也想提升测试效率,不妨试试用Trae生成自动化测试框架,相信会有意想不到的收获!

📚Python Trae提示词开发实战系列目录

1. 【第1篇】2026最新 3个技巧让代码生成质量提升10倍

2. 【第2篇】2026 最新 10个自动化批处理场景 + 完整代码

3. 【第3篇】2026 最新 用模块化提示词生成可运行电商系统代码

4. 【第4篇】2026 最新 用Pandas Excel打造企业级自动化报表让效率提升10倍

5. 【第5篇】2026 最新 用提示词优化技巧生成爬虫代码

👉 最新发布点击关注  解锁更多深度干货!

💡 如果你觉得有收获,欢迎点个【赞】或【收藏】💡

Read more

如何在Llama-Factory中启用梯度裁剪保护训练稳定性?

如何在 Llama-Factory 中启用梯度裁剪保护训练稳定性 在大模型微调日益普及的今天,一个看似不起眼的配置项,往往能决定整个训练任务是平稳收敛还是中途崩溃。比如你正用 Qwen-7B 做对话微调,学习率设得稍高一点,batch size 又受限于显存不得不压小——结果前几步 loss 还好好的,突然跳成 NaN,重启几次都一样。这时候,问题很可能不在于数据或模型结构,而在于缺少一道关键的“安全阀”:梯度裁剪。 这并不是什么神秘技术,但它的作用堪称救命稻草。尤其是在 Llama-Factory 这类集成化框架中,正确启用梯度裁剪几乎是以最小代价换取最大稳定性的首选策略。 Transformer 架构的深层网络对梯度异常极为敏感,尤其是注意力机制中某些头可能会在特定输入下产生剧烈响应,导致局部梯度激增。这些“尖峰”梯度一旦参与参数更新,就可能把好不容易学来的知识冲垮。更糟的是,在 LoRA 或 QLoRA 这种仅微调少量参数的场景中,适配层的参数空间更小、更新更集中,反而更容易因梯度过大致使权重震荡甚至溢出。 那怎么办?降低学习率当然可以缓解,但代价是收敛变慢;

告别字幕制作烦恼:N46Whisper让日语视频字幕轻松搞定

告别字幕制作烦恼:N46Whisper让日语视频字幕轻松搞定 【免费下载链接】N46WhisperWhisper based Japanese subtitle generator 项目地址: https://gitcode.com/gh_mirrors/n4/N46Whisper 你是否也曾遇到这样的情况:喜欢的日语视频没有字幕,听不懂又看不明?或者想制作双语字幕分享给朋友,却被复杂的软件和漫长的处理过程劝退?现在,有了N46Whisper,这些问题都将成为过去!这款基于AI技术的字幕生成工具,就像你的私人字幕助理,让你轻松拥有专业级字幕效果。 为什么选择N46Whisper?三大核心优势告诉你 无需安装,打开就能用 传统字幕软件往往需要复杂的安装和配置过程,而N46Whisper采用云端处理方式,就像使用在线文档一样简单。你只需要一个浏览器,就能随时随地开始制作字幕,省去了安装软件的麻烦,特别适合电脑小白和追求效率的用户。 AI助力,识别精准又快速 N46Whisper背后有强大的AI引擎作为支撑,它就像一个经验丰富的日语听力专家,能够准确捕捉视频中的语音内容。无论

本地部署AI绘画就这么简单,麦橘超然实操笔记

本地部署AI绘画就这么简单,麦橘超然实操笔记 1. 开门见山:不用折腾显卡,8GB显存也能跑出专业级画质 你是不是也试过下载一堆AI绘画工具,结果刚点开就弹出“CUDA out of memory”?或者被复杂的环境配置、模型下载、依赖冲突搞得头大,最后连第一张图都没生成出来?别急,这次真不一样。 麦橘超然 - Flux 离线图像生成控制台,不是又一个需要你手动编译、调参、查报错的实验项目。它是一套开箱即用、专为中低显存设备打磨的完整方案——模型已打包进镜像,代码已写好,连端口转发都给你配好了命令行模板。你只需要三步:复制脚本、运行命令、打开浏览器,就能在自己的电脑或远程服务器上,亲手生成一张赛博朋克雨夜街景。 它背后用的是当前图像生成领域最前沿的 Flux.1 架构,但做了关键改造:DiT主干网络用 float8 量化压缩,文本编码器和VAE保持高保真精度,再配合 CPU 卸载机制,把原本动辄12GB显存的模型,硬生生压进6–

昔日AI绘画框架王者Stable Diffusion WebUI,已死

昔日AI绘画框架王者Stable Diffusion WebUI,已死

写在前面 【WeThinkIn出品】栏目分享Rocky的认知思考与经验感悟,范围涵盖但不限于AI行业。 欢迎大家关注Rocky的公众号:WeThinkIn 欢迎大家关注Rocky的知乎:Rocky Ding AIGC算法工程师面试面经秘籍分享:WeThinkIn/Interview-for-Algorithm-Engineer欢迎大家Star~ 获取更多AI行业的前沿资讯与干货资源 AIGC时代的 《三年面试五年模拟》AI算法工程师求职面试秘籍独家资源:【三年面试五年模拟】AI算法工程师面试秘籍 Rocky最新撰写10万字Stable Diffusion 3和FLUX.1系列模型的深入浅出全维度解析文章:深入浅出完整解析Stable Diffusion 3(SD 3)和FLUX.1系列核心基础知识 AIGC算法岗/开发岗面试面经交流社群(涵盖AI绘画、AI视频、大模型、AI多模态、数字人等AIGC面试干货资源)欢迎大家加入:https://t.zsxq.com/33pJ0 大家好,我是Rocky。 “还记得我们第一次打开Stable Diffusion WebUI,用上第