通过Chain Prompts方式将LLM的能力引入测试平台:正交实验测试用例生成

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
简介: 通过Chain Prompts方式将LLM的能力引入测试平台:正交实验测试用例生成

通过Chain Prompts方式将LLM的能力引入测试平台:正交实验测试用例生成


Chain Prompts


Chain Prompts是指在一个对话或文本生成任务中,将前一个提示的输出作为下一个提示的输入,形成一个连续的链条。这种方法常常用于创建连贯的、有上下文关联的文本。在对话系统中,这种方法可以模拟真实对话中的连续性,使得生成的回复更加自然和流畅。


利用Chain Prompts,可以将LLM、外部程序、外部数据连接到一起,实现一个完整的解决方案。下面我们使用Chain Prompts的方式实现正交实验测试用例生成。


STEP1:LLM gen参数的边界值

> 文中使用的LLM是讯飞的星火2.0


首先,借助LLM的能力,设计CoT的Prompt实现让大模型返回每个参数的边界值数组,具体的代码如下:

'''
@des  :针对LLM反馈的内容,做一些文本处理,最终仅仅留下边界的数组返回
@params  : LLM反馈的内容
@return  : 处理好的,仅仅剩下list类型的边界值列表
'''
def get_boundary(content):
    result_boundary_list=[]
    if content.find("[") != -1:
        while content.find("[") != -1:
            if  content.find("[")!= content.find("]")+1:
                try:
                    stemp = content[content.index("["):content.index("]")+1]
                    # pattern = r'#.*?\n'
                    # stemp=re.sub(pattern,"",stemp)
                    result=eval(stemp)
                    result_boundary_list.append(result)
                    content = content.replace(content[content.index("[")],"")
                    content = content.replace(content[content.index("]")],"")
                except Exception as e:
                    content = content.replace(content[content.index("[")],"")
                    continue
            else:
                content = content.replace(content[content.index("[")],"")
                content = content.replace(content[content.index("]")],"")
        return result_boundary_list
    else:
        return []
'''
@des  :和大模型交互,生成边界值数组
@params  : 描述变量的Prompts   
@return  :边界值list
'''
def gen_boundary(usr_message_list):
    # 分隔符
    boundary_param_list=[]
    delimiter = "####"
    if len(usr_message_list)<1:
        return [{"error":"no user param prompt!"}]
    for usr_message in usr_message_list:
        text.clear
        # user_message = f"""{usr_message}{delimiter}。"""
        boundary_message=f"""{delimiter}设计参数的边界值,{usr_message}。
                            {delimiter}边界值还要包含不满足要求的一些内容,并将结果放到到一个数组中,不要返回python代码,只返回一个具体数组内容,不要包含任何注释。
                    """
        system_message = f"""{delimiter}是分隔符。{delimiter}你是一名资深测试工程师,{boundary_message}{delimiter}。"""
        SparkApi.answer=""
        question = checklen(getText("user",system_message))
        SparkApi.main(appid,api_key,api_secret,Spark_url,domain,question)
        try:
            boundary_param_list.append(get_boundary(SparkApi.answer))
        except Exception as e:
            print("error:"+SparkApi.answer+"\"}")
    # print(boundary_param_list)
    return boundary_param_list


STEP2 通过传统编码寻找参数的因素和水平,强度默认是2


接下来,我们需要将大模型处理后的反馈处理成Python可以处理的对象,然后处理成正交表的因素和水平字典。

factors = {}
    levels=[]
    istep = 0
    factors['username']=list[0][0]
    factors['password']=list[1][0]


         

STEP3:通过itertool处理,完成正交表设计和测试用例生成

@des  :生成正交表
@params  :每个因素的水平数list     
@return  :正交表(array)
def generate_orthogonal_table(levels):
    return list(itertools.product(*[range(1, l+1) for l in levels]))


通过统一的入口,调用上述步骤,完成测试用例设计


#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
@File    :   main.py
@Time    :   2023/10/18 13:12:25
@Author  :   CrissChan 
@Version :   1.0
@Site    :   https://blog.csdn.net/crisschan
@Desc    :   主要函数,尝试使用Chain Prompts的方式构建基于正交试验的测试用例生成
             step1:LLM gen参数的边界值
             step2:寻找参数的因素和水平,强度默认是2
             step3:LLM 生成正交表
             step4 用正交表替换测试用例
'''
from gen_boundary import gen_boundary
from gen_boundary import generate_orthogonal_table
import numpy as np
if __name__ == '__main__':
    # step 1 :调用LLM通过Prompt生成参数的边界值。        
    user_message_list=[]
    user_message_1 = f"""username是一个系统的用户名,string类型,长度限制10个字符,不能为空。"""
    user_message_2 = f"""password是一个系统用户的密码,string类型,长度限制10个字符,不能为空。"""
    user_message_list.append(user_message_1)
    user_message_list.append(user_message_2)
    list = gen_boundary(user_message_list)
    print(list)
    # step2 : 寻找参数的因素和水平,强度默认是2
    factors = {}
    levels=[]
    istep = 0
    factors['username']=list[0][0]
    factors['password']=list[1][0]
    # step 3: python计算正交表
    levels_list=[]
    # 创建强度为2的正交表
    for k,v in factors.items():
        levels_list.append(len(v))
    art_array = generate_orthogonal_table(levels_list)
    #step4:将正交表替换测试用例
    tc_list = []
    for a_arr in art_array:
        tc_list.append((factors['username'][a_arr[0]-1],factors['password'][a_arr[1]-1]))
    print(tc_list)

运行结果

请注意,这只是一个示例,实际的数组内容可能会根据具体需求而有所不同。

因素和水平数组:

[[['', '12345678901', 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', '!@#$%^&*()', 'username', 'extra_long_username_that_exceeds_the_limit', '']], 
[['', '1234567890', 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'password', 'passw0rd', 'Passw0rd!', 'p@ssw0rd', 'p@$$w0rd', 'p@ssword']]]


生成的测试用例

 [('', ''), 
('', '1234567890'), 
('', 'abcdefghijklmnopqrstuvwxyz'),
('', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 
('', 'password'), 
('', 'passw0rd'), 
('', 'Passw0rd!'), 
('', 'p@ssw0rd'), 
('', 'p@$$w0rd'), 
('', 'p@ssword'), 
('12345678901', ''), 
('12345678901', '1234567890'), 
('12345678901', 'abcdefghijklmnopqrstuvwxyz'),
('12345678901', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
('12345678901', 'password'), 
('12345678901', 'passw0rd'), 
('12345678901', 'Passw0rd!'), 
('12345678901', 'p@ssw0rd'), 
('12345678901', 'p@$$w0rd'), 
('12345678901', 'p@ssword'), 
('abcdefghijklmnopqrstuvwxyz', ''), 
('abcdefghijklmnopqrstuvwxyz', '1234567890'), 
('abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'), ('abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), ('abcdefghijklmnopqrstuvwxyz', 'password'), ('abcdefghijklmnopqrstuvwxyz', 'passw0rd'), ('abcdefghijklmnopqrstuvwxyz', 'Passw0rd!'), ('abcdefghijklmnopqrstuvwxyz', 'p@ssw0rd'), ('abcdefghijklmnopqrstuvwxyz', 'p@$$w0rd'), ('abcdefghijklmnopqrstuvwxyz', 'p@ssword'), ('ABCDEFGHIJKLMNOPQRSTUVWXYZ', ''), 
('ABCDEFGHIJKLMNOPQRSTUVWXYZ', '1234567890'), ('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), ('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), ('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'password'), ('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'passw0rd'), ('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'Passw0rd!'), ('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'p@ssw0rd'), ('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'p@$$w0rd'), ('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'p@ssword'),
('!@#$%^&*()', ''),
('!@#$%^&*()', '1234567890'),
('!@#$%^&*()', 'abcdefghijklmnopqrstuvwxyz'), 
('!@#$%^&*()', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 
('!@#$%^&*()', 'password'), 
('!@#$%^&*()', 'passw0rd'), 
('!@#$%^&*()', 'Passw0rd!'), 
('!@#$%^&*()', 'p@ssw0rd'), 
('!@#$%^&*()', 'p@$$w0rd'), 
('!@#$%^&*()', 'p@ssword'), 
('username', ''), 
('username', '1234567890'), 
('username', 'abcdefghijklmnopqrstuvwxyz'), 
('username', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 
('username', 'password'), 
('username', 'passw0rd'),
('username', 'Passw0rd!'),
('username', 'p@ssw0rd'), 
('username', 'p@$$w0rd'), 
('username', 'p@ssword'), 
('extra_long_username_that_exceeds_the_limit', ''), 
('extra_long_username_that_exceeds_the_limit', '1234567890'), ('extra_long_username_that_exceeds_the_limit', 'abcdefghijklmnopqrstuvwxyz'), ('extra_long_username_that_exceeds_the_limit', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), ('extra_long_username_that_exceeds_the_limit', 'password'), ('extra_long_username_that_exceeds_the_limit', 'passw0rd'), ('extra_long_username_that_exceeds_the_limit', 'Passw0rd!'), ('extra_long_username_that_exceeds_the_limit', 'p@ssw0rd'), ('extra_long_username_that_exceeds_the_limit', 'p@$$w0rd'), ('extra_long_username_that_exceeds_the_limit', 'p@ssword'), ('', ''), ('', '1234567890'), 
('', 'abcdefghijklmnopqrstuvwxyz'), 
('', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 
('', 'password'), 
('', 'passw0rd'), 
('', 'Passw0rd!'), 
('', 'p@ssw0rd'), ('', 'p@$$w0rd'), 
('', 'p@ssword')]





目录
相关文章
|
9天前
|
测试技术 Python
自动化测试项目学习笔记(三):Unittest加载测试用例的四种方法
本文介绍了使用Python的unittest框架来加载测试用例的四种方法,包括通过测试用例类、模块、路径和逐条加载测试用例。
25 0
自动化测试项目学习笔记(三):Unittest加载测试用例的四种方法
|
1月前
|
测试技术
测试用例设计方法之基本路径测试法
基本路径测试法是在程序控制流图的基础上,通过分析控制构造的环路复杂性,导出基本可执行路径集合,从而设计测试用例的方法,设计出的测试用例要保证在测试中程序的语句覆盖100%,条件覆盖100%
64 7
测试用例设计方法之基本路径测试法
|
1月前
|
测试技术 数据库
『软件测试2』 关于黑盒测试和测试用例的基础知识
该文章讲解了黑盒测试的基本概念以及如何编写有效的测试用例,包括选择合适的输入数据、预期结果的设定和测试执行的步骤。
|
2月前
|
NoSQL Linux Android开发
内核实验(三):编写简单Linux内核模块,使用Qemu加载ko做测试
本文介绍了如何在QEMU中挂载虚拟分区、创建和编译简单的Linux内核模块,并在QEMU虚拟机中加载和测试这些内核模块,包括创建虚拟分区、编写内核模块代码、编译、部署以及在QEMU中的加载和测试过程。
158 0
内核实验(三):编写简单Linux内核模块,使用Qemu加载ko做测试
|
2月前
|
测试技术
测试与开发问题之测试用例设计的重点是什么,如何实现
测试与开发问题之测试用例设计的重点是什么,如何实现
|
1月前
|
测试技术 数据安全/隐私保护
软件测试的艺术:如何高效地编写测试用例
【9月更文挑战第2天】在软件开发的海洋中,测试用例是导航灯塔,指引着质量保障的航向。本文将带你航行于测试用例编写的技巧之海,从理解需求到设计思路,再到实际执行,我们将一起探索如何高效而精准地构建测试用例,确保软件的稳健与可靠。
52 0
|
2月前
|
Java 测试技术 API
SpringBoot单元测试快速写法问题之计算测试用例的分支覆盖率如何解决
SpringBoot单元测试快速写法问题之计算测试用例的分支覆盖率如何解决
|
3月前
|
测试技术
单元测试策略问题之寻找边界问题如何解决
单元测试策略问题之寻找边界问题如何解决
|
3月前
|
测试技术
软件交付问题之为什么测试用例不能全由开发人员告知测试人员
软件交付问题之为什么测试用例不能全由开发人员告知测试人员
|
3月前
|
测试技术 开发工具 git
后端测试,好的建议,后端测试----Postman如何创建项目,导入测试用例和测试集,注意对测试用例进行保存,格式用测试用例---xxx测试用例
后端测试,好的建议,后端测试----Postman如何创建项目,导入测试用例和测试集,注意对测试用例进行保存,格式用测试用例---xxx测试用例