首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >智能体生成测试用例和脚本方法(四)

智能体生成测试用例和脚本方法(四)

作者头像
顾翔
发布2026-04-13 16:26:47
发布2026-04-13 16:26:47
1000
举报

正如智能体生成测试用例和脚本方法(一)描述

注意:有智能体生成的测试用例不可能一次正确,我们需要通过人工的方式+智能体辅助的方式进行调试。在通过智能体生成用例和测试脚本的方法(四)。我会进行详细介绍。

我们可以简单建立一个智能体流程来对生成的测试脚本进行联机调试

在这个流程中,除了开始节点,就一个智能节点:优化测试脚本

系统提示词

你是一位资深的软件测试开发工程师,精通Python、Playwright和pytest框架。你的核心职责是根据${sys.query},优化测试脚本。

用户提示词

你是一位资深的软件测试开发工程师,精通Python、Playwright和pytest框架。你的核心职责是根据${sys.query},优化测试脚本。

在运行的时候描述清楚测试脚本和报错信息,通过不断迭代,就可以不断优化脚本。

比如

测试脚本

代码语言:javascript
复制
import unittest
import requests
import hashlib
import re
import pymysql
from parameterized import parameterized
from bs4 import BeautifulSoup
import logging

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# 数据库配置 (保持与后端一致的编码)
DB_CONFIG = {
    'host': 'localhost',
    'user': 'root',
    'password': '123456',
    'database': 'chatgptebusiness',
    'charset': 'utf8'
}

# API接口配置
VERICODE_URL = "http://127.0.0.1:8080/ChatGPTEbusiness/jsp/VeriCodePage.jsp"
RECOVER_URL = "http://127.0.0.1:8080/ChatGPTEbusiness/jsp/RecoverPage.jsp"

class RecoverPasswordAPITest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        """初始化类级别资源:创建数据库连接和请求会话"""
        cls.db = pymysql.connect(**DB_CONFIG)
        cls.session = requests.Session()
        logger.info("Class-level setup completed")

    @classmethod
    def tearDownClass(cls):
        """清理类级别资源:关闭数据库连接和会话"""
        cls.db.close()
        cls.session.close()
        logger.info("Class-level teardown completed")

    def setUp(self):
        """每条测试用例执行前:清空数据库表并获取初始CSRF Token"""
        self._clear_tables()
        self.csrf_token = self._get_csrf_token(VERICODE_URL)
        logger.info("Test setup completed: %s", self._testMethodName)

    def tearDown(self):
        """每条测试用例执行后:确保环境干净"""
        logger.info("Test teardown completed: %s", self._testMethodName)

    def _clear_tables(self):
        """清空数据库表,确保测试环境干净"""
        try:
            with self.db.cursor() as cursor:
                cursor.execute("SET FOREIGN_KEY_CHECKS = 0")
                cursor.execute("DELETE FROM user")
                cursor.execute("DELETE FROM code")
                cursor.execute("SET FOREIGN_KEY_CHECKS = 1")
                self.db.commit()
            logger.info("Database tables cleared")
        except Exception as e:
            self.fail(f"Database clear failed: {str(e)}")

    def _get_csrf_token(self, url):
        """从页面获取CSRF Token"""
        try:
            response = self.session.get(url)
            response.raise_for_status()
            match = re.search(r'<input type="hidden" id="csrftoken" name="csrftoken" value="([^"]+)"', response.text)
            return match.group(1) if match else None
        except Exception as e:
            logger.error("CSRF token retrieval failed: %s", str(e))
            self.fail(f"Get CSRF token failed: {str(e)}")

    def _hash_password(self, password):
        """计算密码哈希(使用后端相同的处理方式)"""
        return hashlib.sha256(password.encode('utf-8')).hexdigest()

    def _post_vericode(self, contact):
        """封装发送手机号/邮箱验证请求"""
        data = {
            "csrftoken": self.csrf_token,
            "contact": contact
        }
        response = self.session.post(VERICODE_URL, data=data, cookies={"csrftoken": self.csrf_token})
        response.raise_for_status()
        return response

    def _post_resetcode(self, identifying_code, new_password, confirm_password):
        """
        1. 发送明文密码(后端会自行处理哈希)
        2. 修正:后端要求明文,不进行任何哈希处理
        """
        self.csrf_token = self._get_csrf_token(RECOVER_URL)
        data = {
            "csrftoken": self.csrf_token,
            "identifyingCode": identifying_code,
            "newPassword": new_password,      # 直接发送明文
            "confirmPassword": confirm_password
        }
        response = self.session.post(RECOVER_URL, data=data, cookies={"csrftoken": self.csrf_token})
        response.raise_for_status()
        return response

    def _get_error_message(self, response):
        """从响应中提取错误提示信息"""
        try:
            soup = BeautifulSoup(response.text, 'html.parser')
            error_div = soup.find('div', id='recoverError')
            return error_div.get_text(strip=True) if error_div else ""
        except Exception as e:
            return ""

    @parameterized.expand([
        ("有效手机号", "13800138000", True, "成功"),
        ("有效邮箱", "test@example.com", True, "成功"),
    ])
    def test_verify_contact(self, test_name, contact, is_success, expected_msg):
        """测试手机号/邮箱验证接口(001系列)"""
        if is_success:
            try:
                with self.db.cursor() as cursor:
                    # 插入测试用户(使用两次哈希存储,与后端一致)
                    old_password = "oldpass123"
                    first_hash = self._hash_password(old_password)
                    cursor.execute(
                        "INSERT INTO user (phone, password) VALUES (%s, %s)",
                        (contact,first_hash)
                    )
                    self.db.commit()
                logger.info("Test user created: %s", contact)
            except Exception as e:
                self.fail(f"Failed to create test user: {str(e)}")

        response = self._post_vericode(contact)
        self.assertEqual(response.status_code, 200)

        if is_success:
            self.assertIn("找回密码", response.text)
        else:
            error_msg = self._get_error_message(response)
            self.assertEqual(error_msg, expected_msg)

    @parameterized.expand([
        ("正确验证码和密码", "13800138000", "123456", "Abc123", "Abc123", "成功"),
    ])
    def test_reset_password(self, test_name, contact, code, new_password, confirm_password, expected_msg):
        """测试密码重置接口(002系列)"""
        try:
            with self.db.cursor() as cursor:
                # 插入测试用户(使用两次哈希存储,与后端一致)
                old_password = "oldpass123"
                first_hash = self._hash_password(old_password)
                cursor.execute(
                    "INSERT INTO user (phone, password) VALUES (%s, %s)",
                    (contact, first_hash)
                )
                user_id = cursor.lastrowid
                self.db.commit()

                # 插入验证码
                cursor.execute(
                    "INSERT INTO code (uid, code) VALUES (%s, %s)",
                    (user_id, code)
                )
                self.db.commit()
            logger.info("Test data created: user_id=%s, contact=%s", user_id, contact)
        except Exception as e:
            self.fail(f"Failed to create test data: {str(e)}")

        # 1. 发送明文密码(后端会进行两次哈希处理)
        response = self._post_resetcode(code, new_password, confirm_password)
        self.assertEqual(response.status_code, 200)

        # 2. 验证数据库更新(使用两次哈希验证)
        if "成功" in expected_msg:
            try:
                with self.db.cursor() as cursor:
                    cursor.execute("SELECT password FROM user WHERE id = %s", (user_id,))
                    result = cursor.fetchone()
                    self.assertIsNotNone(result, "User record not updated")

                    # 重要:计算两次哈希(与后端一致)
                    first_hash = self._hash_password(new_password)
                    expected_hash = first_hash

                    logger.info("Calculated hash: %s (for password: '%s')", expected_hash, new_password)
                    logger.info("Database hash: %s", result[0])

                    self.assertEqual(
                        expected_hash,
                        result[0],
                        f"Password hash mismatch: expected '{expected_hash}', got '{result[0]}'"
                    )
            except Exception as e:
                self.fail(f"Database verification failed: {str(e)}")
        else:
            error_msg = self._get_error_message(response)
            self.assertEqual(error_msg, expected_msg)

if __name__ == "__main__":
    unittest.main(verbosity=2, failfast=True)

遇到问题

代码语言:javascript
复制
2026-04-09 13:30:41,189 - INFO - Class-level setup completed
test_reset_password_0__ (__main__.RecoverPasswordAPITest.test_reset_password_0__)
测试密码重置接口(002系列) [with test_name='正确验证码和密码', contact='13800138000', code='123456', new_password='Abc123', confirm_password='Abc123', expected_msg='成功'] ... 2026-04-09 13:30:41,269 - INFO - Database tables cleared
2026-04-09 13:30:41,516 - INFO - Test setup completed: test_reset_password_0__
2026-04-09 13:30:41,524 - INFO - Test data created: user_id=11, contact=13800138000
2026-04-09 13:30:41,549 - INFO - Calculated hash: 7f91e8a4b648b0125b15dc5a3b6466f9f4906d92c72bea9bd6be92c853bebda2 (for password: 'Abc123')
2026-04-09 13:30:41,553 - INFO - Database hash: 04e45016090b3ae8bac292e00f912ca04d2f93b0b0a51f5b22ccf40c7123df1a
FAIL
2026-04-09 13:30:41,561 - INFO - Test teardown completed: test_reset_password_0__
2026-04-09 13:30:41,564 - INFO - Class-level teardown completed

======================================================================
FAIL: test_reset_password_0__ (__main__.RecoverPasswordAPITest.test_reset_password_0__)
测试密码重置接口(002系列) [with test_name='正确验证码和密码', contact='13800138000', code='123456', new_password='Abc123', confirm_password='Abc123', expected_msg='成功']
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\xiang\Desktop\AI赋能软件测试实战\reset_API.py", line 191, in test_reset_password
    self.assertEqual(
AssertionError: '7f91e8a4b648b0125b15dc5a3b6466f9f4906d92c72bea9bd6be92c853bebda2' != '04e45016090b3ae8bac292e00f912ca04d2f93b0b0a51f5b22ccf40c7123df1a'
- 7f91e8a4b648b0125b15dc5a3b6466f9f4906d92c72bea9bd6be92c853bebda2
+ 04e45016090b3ae8bac292e00f912ca04d2f93b0b0a51f5b22ccf40c7123df1a
 : Password hash mismatch: expected '7f91e8a4b648b0125b15dc5a3b6466f9f4906d92c72bea9bd6be92c853bebda2', got '04e45016090b3ae8bac292e00f912ca04d2f93b0b0a51f5b22ccf40c7123df1a'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\xiang\AppData\Local\Programs\Python\Python312\Lib\site-packages\parameterized\parameterized.py", line 620, in standalone_func
    return func(*(a + p.args), **p.kwargs, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\xiang\Desktop\AI赋能软件测试实战\reset_API.py", line 197, in test_reset_password
    self.fail(f"Database verification failed: {str(e)}")
AssertionError: Database verification failed: '7f91e8a4b648b0125b15dc5a3b6466f9f4906d92c72bea9bd6be92c853bebda2' != '04e45016090b3ae8bac292e00f912ca04d2f93b0b0a51f5b22ccf40c7123df1a'
- 7f91e8a4b648b0125b15dc5a3b6466f9f4906d92c72bea9bd6be92c853bebda2
+ 04e45016090b3ae8bac292e00f912ca04d2f93b0b0a51f5b22ccf40c7123df1a
 : Password hash mismatch: expected '7f91e8a4b648b0125b15dc5a3b6466f9f4906d92c72bea9bd6be92c853bebda2', got '04e45016090b3ae8bac292e00f912ca04d2f93b0b0a51f5b22ccf40c7123df1a'

----------------------------------------------------------------------
Ran 1 test in 0.390s

FAILED (failures=1)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-04-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档