ai:把用例捡起来!把用例捡起来!
给大模型需求文档,让它完成设计用例,编写用例,包括功能用例、接口用例、自动化测试用例,自执行~最后发送至工作群中
直接使用deepseek即可
执行一下看看:
调用ds分析需求:
生成功能/接口用例:
生成自动化用例:
看一下自动生成的功能用例和接口用例:- # 为了验证用户登录功能,我们将使用 `pytest` 框架和 `requests` 库来进行 API 测试。以下是一个示例代码,展示了如何实现这个测试用例。
- #
- # ### 安装依赖
- # 首先,确保你已经安装了 `pytest` 和 `requests` 库。如果没有安装,可以使用以下命令进行安装:
- #
- # ```bash
- # pip install pytest requests
- # ```
- #
- # ### 测试代码
- #
- # ```python
- import pytest
- import requests
- # 定义登录API的URL
- LOGIN_URL = "http://127.0.0.1:5000/login"
- # 测试用例:验证用户登录功能
- def test_user_login():
- # 定义测试数据
- username = "user1"
- password = "password1"
-
- # 构造请求体
- payload = {
- "username": username,
- "password": password
- }
-
- # 发送POST请求到登录API端点
- response = requests.post(LOGIN_URL, json=payload)
-
- # 验证响应状态码是否为200
- assert response.status_code == 200, f"Expected status code 200, but got {response.status_code}"
-
- # 解析API响应
- response_data = response.json()
-
- # 验证响应中是否包含预期的字段
- assert "token" in response_data, "Response does not contain 'token' field"
- assert "user_id" in response_data, "Response does not contain 'user_id' field"
-
- # 验证token和user_id是否有效
- assert isinstance(response_data["token"], str), "Token is not a string"
- assert isinstance(response_data["user_id"], int), "User ID is not an integer"
- # 运行测试
- if __name__ == "__main__":
- pytest.main()
- # ```
- #
- # ### 代码说明
- #
- # 1. **LOGIN_URL**: 这是登录API的URL,你需要将其替换为实际的API端点。
- #
- # 2. **test_user_login**: 这是测试函数,使用 `pytest` 框架进行测试。
- #
- # 3. **payload**: 这是发送到API的请求体,包含用户名和密码。
- #
- # 4. **requests.post**: 发送POST请求到登录API端点。
- #
- # 5. **assert response.status_code == 200**: 验证响应状态码是否为200,表示请求成功。
- #
- # 6. **response.json()**: 解析API响应为JSON格式。
- #
- # 7. **assert "token" in response_data**: 验证响应中是否包含 `token` 字段。
- #
- # 8. **assert "user_id" in response_data**: 验证响应中是否包含 `user_id` 字段。
- #
- # 9. **assert isinstance(response_data["token"], str)**: 验证 `token` 是否为字符串类型。
- #
- # 10. **assert isinstance(response_data["user_id"], int)**: 验证 `user_id` 是否为整数类型。
- #
- # ### 运行测试
- #
- # 你可以通过以下命令运行测试:
- #
- # ```bash
- # pytest test_login.py
- # ```
- #
- # 如果所有断言都通过,测试将成功完成。如果有任何断言失败,`pytest` 将输出详细的错误信息,帮助你定位问题。
- """
- 自动化测试执行器
- """
- import pytest
- import os
- import sys
- from datetime import datetime
- from typing import List, Dict
- import json
- from dotenv import load_dotenv
- # 添加项目根目录到Python路径
- current_dir = os.path.dirname(os.path.abspath(__file__))
- project_root = os.path.abspath(os.path.join(current_dir, "../../../.."))
- src_dir = os.path.join(project_root, "ai-test-generator", "src")
- sys.path.insert(0, src_dir)
- # 加载环境变量
- env_path = os.path.join(project_root, "ai-test-generator", ".env")
- print(f"正在加载环境变量文件: {env_path}")
- load_dotenv(env_path)
- try:
- from test_reporter import TestReporter, TestResult
- except ImportError as e:
- print(f"错误:无法导入test_reporter模块。请确保项目结构正确。")
- print(f"当前目录: {current_dir}")
- print(f"项目根目录: {project_root}")
- print(f"src目录: {src_dir}")
- print(f"Python路径: {sys.path}")
- raise e
- def run_tests(test_files: List[str] = None) -> bool:
- """
- 运行测试用例并生成报告
-
- Args:
- test_files: 要运行的测试文件列表,如果为None则运行所有测试
-
- Returns:
- bool: 所有测试是否通过
- """
- print("\n开始执行测试...")
-
- # 初始化测试报告器
- reporter = TestReporter()
-
- # 如果没有指定测试文件,则运行所有测试
- if test_files is None:
- test_files = [f for f in os.listdir(os.path.dirname(__file__))
- if f.endswith('_test.py') and f != '_automation.py']
- print(f"将运行所有测试文件: {test_files}")
-
- all_passed = True
-
- for test_file in test_files:
- test_path = os.path.join(os.path.dirname(__file__), test_file)
- test_id = os.path.splitext(test_file)[0]
-
- print(f"\n执行测试文件: {test_file}")
-
- # 记录测试执行
- start_time = datetime.now()
- try:
- # 运行测试
- result = pytest.main([test_path, '-v'])
- status = 'passed' if result == 0 else 'failed'
- error_msg = None if result == 0 else 'Test execution failed'
- if result != 0:
- all_passed = False
- print(f"测试执行结果: {status}")
- except Exception as e:
- status = 'error'
- error_msg = str(e)
- all_passed = False
- print(f"测试执行出错: {e}")
-
- duration = (datetime.now() - start_time).total_seconds()
-
- # 记录测试结果
- reporter.add_test_result(TestResult(
- test_id=test_id,
- test_name=test_file,
- test_type='api',
- status=status,
- duration=duration,
- error_message=error_msg,
- start_time=start_time.isoformat(),
- end_time=datetime.now().isoformat()
- ))
-
- # 生成并保存报告
- reports_dir = os.path.join(project_root, "ai-test-generator", "test_cases", "reports")
- reporter.save_report(reports_dir)
-
- # 发送钉钉通知
- print("\n准备发送测试报告...")
- reporter.send_dingtalk_notification()
-
- print(f"\n测试执行完成,{'全部通过' if all_passed else '存在失败'}")
- return all_passed
- if __name__ == "__main__":
- # 获取命令行参数中的测试文件
- test_files = sys.argv[1:] if len(sys.argv) > 1 else None
-
- # 运行测试
- success = run_tests(test_files)
-
- # 设置退出码
- sys.exit(0 if success else 1)
复制代码- metadata:
- id: FUNC_1__20250313_155452
- type: functional
- feature: 1._**用户登录功能**:
- generated_time: '2025-03-13T15:54:52.411287'
- test_case:
- title: 用户登录功能测试
- description: 验证用户登录功能是否正常工作,确保用户能够通过正确的用户名和密码成功登录系统。
- test_type: functional
- prerequisites:
- - 系统已安装并运行
- - 用户已注册并拥有有效的用户名和密码
- steps:
- - 打开登录页面
- - 输入有效的用户名
- - 输入有效的密码
- - 点击登录按钮
- expected_results:
- - 登录页面成功加载
- - 用户名和密码输入框接受输入
- - 登录按钮可点击
- - 用户成功登录并跳转到主页
- test_data:
- username: testuser
- password: testpassword
复制代码 本地简单写了个登录接口,用生成的用例跑一下,看看收集结果以及发送结果的功能
接口:
改改用例里面的url和参数:
report中的内容:
发送的wehook通知:
代码:
main.py
- 1 import os
- 2 import sys
- 3 from test_generator import AITestGenerator
- 4 from test_case_manager import TestCaseManager
- 5 from dotenv import load_dotenv
- 6
- 7 def read_requirements():
- 8 """从用户输入读取需求文档"""
- 9 print("\n请输入需求文档(输入完成后请按Ctrl+D或Ctrl+Z结束):")
- 10 lines = []
- 11 try:
- 12 while True:
- 13 line = input()
- 14 lines.append(line)
- 15 except (EOFError, KeyboardInterrupt):
- 16 pass
- 17 return "\n".join(lines)
- 18
- 19 def read_requirements_from_file(file_path):
- 20 """从文件读取需求文档"""
- 21 with open(file_path, 'r', encoding='utf-8') as f:
- 22 return f.read()
- 23
- 24 def main():
- 25 # 加载环境变量
- 26 load_dotenv()
- 27
- 28 # 初始化生成器和管理器
- 29 generator = AITestGenerator()
- 30 manager = TestCaseManager()
- 31
- 32 # 解析命令行参数
- 33 if len(sys.argv) < 2:
- 34 print("用法: python main.py <command> [options]")
- 35 print("命令:")
- 36 print(" generate <requirements_file> - 从需求文件生成测试用例")
- 37 print(" generate - 从用户输入生成测试用例")
- 38 print(" run [type] [feature] - 执行测试用例")
- 39 print("选项:")
- 40 print(" type: functional 或 api")
- 41 print(" feature: 特定功能名称")
- 42 return
- 43
- 44 command = sys.argv[1]
- 45
- 46 if command == "generate":
- 47 # 获取需求文档
- 48 if len(sys.argv) > 2:
- 49 # 从文件读取需求
- 50 requirements = read_requirements_from_file(sys.argv[2])
- 51 else:
- 52 # 从用户输入读取需求
- 53 requirements = read_requirements()
- 54
- 55 if not requirements.strip():
- 56 print("错误:需求文档不能为空")
- 57 return
- 58
- 59 # 分析需求
- 60 print("\n正在分析需求文档...")
- 61 features = generator.analyze_requirements(requirements)
- 62
- 63 print("\n提取的功能点:")
- 64 for i, feature in enumerate(features, 1):
- 65 print(f"{i}. {feature}")
- 66
- 67 # 为每个功能点生成测试用例
- 68 test_types = ['functional', 'api', 'automation']
- 69 for feature in features:
- 70 feature_name = feature.strip().lower().replace(' ', '_')
- 71
- 72 for test_type in test_types:
- 73 print(f"\n正在生成 {test_type} 测试用例,功能点:{feature}")
- 74 test_case = generator.generate_test_cases(feature, test_type)
- 75
- 76 # 保存测试用例
- 77 if test_type == 'functional':
- 78 # 保存为YAML文件
- 79 file_path = manager.save_functional_test(test_case.dict(), feature_name)
- 80 print(f"功能测试用例已保存到: {file_path}")
- 81
- 82 elif test_type == 'api':
- 83 # 保存为Python测试文件和JSON数据文件
- 84 case_path, data_path = manager.save_api_test(test_case.dict(), feature_name)
- 85 print(f"API测试用例已保存到: {case_path}")
- 86 print(f"API测试数据已保存到: {data_path}")
- 87
- 88 elif test_type == 'automation':
- 89 # 生成自动化测试代码
- 90 automation_code = generator.generate_automation_code(test_case)
- 91 # 保存自动化测试代码
- 92 file_path = os.path.join(manager.api_cases_dir, f"{feature_name}_automation.py")
- 93 with open(file_path, 'w', encoding='utf-8') as f:
- 94 f.write(automation_code)
- 95 print(f"自动化测试代码已保存到: {file_path}")
- 96
- 97 print("\n所有测试用例生成完成!")
- 98 print("\n您可以在以下目录找到生成的测试用例:")
- 99 print(f"功能测试用例: {manager.functional_dir}")
- 100 print(f"API测试用例: {manager.api_cases_dir}")
- 101 print(f"API测试数据: {manager.api_data_dir}")
- 102
- 103 elif command == "run":
- 104 # 执行测试用例
- 105 test_type = sys.argv[2] if len(sys.argv) > 2 else None
- 106 feature = sys.argv[3] if len(sys.argv) > 3 else None
- 107
- 108 print(f"\n开始执行测试{'(' + test_type + ')' if test_type else ''}")
- 109 if feature:
- 110 print(f"功能点: {feature}")
- 111
- 112 success = manager.execute_tests(test_type, feature)
- 113
- 114 print("\n测试执行完成!")
- 115 print(f"测试{'全部通过' if success else '存在失败'}")
- 116 print(f"详细报告已保存至: {manager.reports_dir}")
- 117
- 118 else:
- 119 print(f"未知命令: {command}")
- 120 return
- 121
- 122 if __name__ == "__main__":
- 123 main()
复制代码 View Codetest_case_manager.py
- 1 import os
- 2 import sys
- 3 from test_generator import AITestGenerator
- 4 from test_case_manager import TestCaseManager
- 5 from dotenv import load_dotenv
- 6
- 7 def read_requirements():
- 8 """从用户输入读取需求文档"""
- 9 print("\n请输入需求文档(输入完成后请按Ctrl+D或Ctrl+Z结束):")
- 10 lines = []
- 11 try:
- 12 while True:
- 13 line = input()
- 14 lines.append(line)
- 15 except (EOFError, KeyboardInterrupt):
- 16 pass
- 17 return "\n".join(lines)
- 18
- 19 def read_requirements_from_file(file_path):
- 20 """从文件读取需求文档"""
- 21 with open(file_path, 'r', encoding='utf-8') as f:
- 22 return f.read()
- 23
- 24 def main():
- 25 # 加载环境变量
- 26 load_dotenv()
- 27
- 28 # 初始化生成器和管理器
- 29 generator = AITestGenerator()
- 30 manager = TestCaseManager()
- 31
- 32 # 解析命令行参数
- 33 if len(sys.argv) < 2:
- 34 print("用法: python main.py <command> [options]")
- 35 print("命令:")
- 36 print(" generate <requirements_file> - 从需求文件生成测试用例")
- 37 print(" generate - 从用户输入生成测试用例")
- 38 print(" run [type] [feature] - 执行测试用例")
- 39 print("选项:")
- 40 print(" type: functional 或 api")
- 41 print(" feature: 特定功能名称")
- 42 return
- 43
- 44 command = sys.argv[1]
- 45
- 46 if command == "generate":
- 47 # 获取需求文档
- 48 if len(sys.argv) > 2:
- 49 # 从文件读取需求
- 50 requirements = read_requirements_from_file(sys.argv[2])
- 51 else:
- 52 # 从用户输入读取需求
- 53 requirements = read_requirements()
- 54
- 55 if not requirements.strip():
- 56 print("错误:需求文档不能为空")
- 57 return
- 58
- 59 # 分析需求
- 60 print("\n正在分析需求文档...")
- 61 features = generator.analyze_requirements(requirements)
- 62
- 63 print("\n提取的功能点:")
- 64 for i, feature in enumerate(features, 1):
- 65 print(f"{i}. {feature}")
- 66
- 67 # 为每个功能点生成测试用例
- 68 test_types = ['functional', 'api', 'automation']
- 69 for feature in features:
- 70 feature_name = feature.strip().lower().replace(' ', '_')
- 71
- 72 for test_type in test_types:
- 73 print(f"\n正在生成 {test_type} 测试用例,功能点:{feature}")
- 74 test_case = generator.generate_test_cases(feature, test_type)
- 75
- 76 # 保存测试用例
- 77 if test_type == 'functional':
- 78 # 保存为YAML文件
- 79 file_path = manager.save_functional_test(test_case.dict(), feature_name)
- 80 print(f"功能测试用例已保存到: {file_path}")
- 81
- 82 elif test_type == 'api':
- 83 # 保存为Python测试文件和JSON数据文件
- 84 case_path, data_path = manager.save_api_test(test_case.dict(), feature_name)
- 85 print(f"API测试用例已保存到: {case_path}")
- 86 print(f"API测试数据已保存到: {data_path}")
- 87
- 88 elif test_type == 'automation':
- 89 # 生成自动化测试代码
- 90 automation_code = generator.generate_automation_code(test_case)
- 91 # 保存自动化测试代码
- 92 file_path = os.path.join(manager.api_cases_dir, f"{feature_name}_automation.py")
- 93 with open(file_path, 'w', encoding='utf-8') as f:
- 94 f.write(automation_code)
- 95 print(f"自动化测试代码已保存到: {file_path}")
- 96
- 97 print("\n所有测试用例生成完成!")
- 98 print("\n您可以在以下目录找到生成的测试用例:")
- 99 print(f"功能测试用例: {manager.functional_dir}")
- 100 print(f"API测试用例: {manager.api_cases_dir}")
- 101 print(f"API测试数据: {manager.api_data_dir}")
- 102
- 103 elif command == "run":
- 104 # 执行测试用例
- 105 test_type = sys.argv[2] if len(sys.argv) > 2 else None
- 106 feature = sys.argv[3] if len(sys.argv) > 3 else None
- 107
- 108 print(f"\n开始执行测试{'(' + test_type + ')' if test_type else ''}")
- 109 if feature:
- 110 print(f"功能点: {feature}")
- 111
- 112 success = manager.execute_tests(test_type, feature)
- 113
- 114 print("\n测试执行完成!")
- 115 print(f"测试{'全部通过' if success else '存在失败'}")
- 116 print(f"详细报告已保存至: {manager.reports_dir}")
- 117
- 118 else:
- 119 print(f"未知命令: {command}")
- 120 return
- 121
- 122 if __name__ == "__main__":
- 123 main()
复制代码 View Codetest_generator.py
[code] 1 import os 2 import sys 3 import time 4 import json 5 import re 6 from typing import List, Dict 7 import requests 8 import httpx 9 from dotenv import load_dotenv 10 from pydantic import BaseModel 11 12 class TestCase(BaseModel): 13 """测试用例模型""" 14 title: str 15 description: str 16 test_type: str # 'functional', 'api', 'automation' 17 prerequisites: List[str] 18 steps: List[str] 19 expected_results: List[str] 20 test_data: Dict[str, str] 21 22 class AITestGenerator: 23 def __init__(self): 24 load_dotenv() 25 self.api_key = os.getenv("DEEPSEEK_API_KEY") 26 if not self.api_key: 27 print("错误: 未找到DEEPSEEK_API_KEY环境变量。请确保.env文件中包含有效的API密钥。") 28 sys.exit(1) 29 30 self.url = "https://api.deepseek.com/chat/completions" 31 self.headers = { 32 "Content-Type": "application/json", 33 "Authorization": f"Bearer {self.api_key}" 34 } 35 print("成功初始化DeepSeek API配置") 36 37 def _format_json_prompt(self, content: str) -> str: 38 """格式化提示词,确保AI生成标准JSON格式响应""" 39 return f"""请严格按照以下JSON格式生成响应: 40 {{ 41 "title": "测试用例标题", 42 "description": "测试用例描述", 43 "test_type": "api", 44 "prerequisites": ["前置条件1", "前置条件2"], 45 "steps": ["步骤1", "步骤2"], 46 "expected_results": ["预期结果1", "预期结果2"], 47 "test_data": {{ 48 "key1": "value1", 49 "key2": "value2" 50 }} 51 }} 52 53 请基于以下内容生成测试用例(请确保生成的是合法的JSON格式): 54 {content}""" 55 56 def _extract_json_from_text(self, text: str) -> str: 57 """从文本中提取JSON部分""" 58 # 查找第一个 { 和最后一个 } 之间的内容 59 json_match = re.search(r'({[\s\S]*})', text) 60 if json_match: 61 return json_match.group(1) 62 return text 63 64 def _clean_json_string(self, json_str: str) -> str: 65 """清理和修复常见的JSON格式问题""" 66 # 移除可能导致解析错误的Unicode字符 67 json_str = json_str.encode('utf-8', 'ignore').decode('utf-8') 68 69 # 修复常见的格式问题 70 json_str = re.sub(r'(?来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |