基于LangChain手工测试用例转Web自动化测试生成工具

在传统编写 Web 自动化测试用例的过程中,基本都是需要测试工程师,根据功能测试用例转换为自动化测试的用例。市面上自动生成 Web 或 App 自动化测试用例的产品无非也都是通过录制的方式,获取操作人的行为操作,从而记录测试用例。整个过程类似于

[图片上传失败...(image-23545f-1724927282952)]

但是通常录制出来的用例可用性、可维护性都不强,而且依然需要人手工介入录制的过程。

在 LLM 问世之后,我们便在探索,是否有第二种可能性,由大模型执行功能测试用例,生成自动化测试用例?

应用价值

测试工程师在编写用例的过程中,将操作步骤明确的表达出来。即可通过大模型将功能测试用例可以直接转为 Web 自动化测试用例。极大的节省了人力与资源。

实践演练

实现原理

整个实现原理如下图所示:

[图片上传失败...(image-125816-1724927282952)]

实现思路

测试用例规范与要求

如果想要将功能用例转换为自动化测试用例,那么对功能测试用例则需要清晰,明确的表达出来每个操作步骤。如果测试用例本身就表达的含糊不清,那么自然大模型是无法识别它需要进行的具体的操作步骤的。

如下所示,为一个登录功能的测试步骤。在这些测试步骤中,具体打开哪些页面,输入哪些信息,点击哪些按钮都清晰的表达了出来。


1. 打开 https://litemall.hogwarts.ceshiren.com/#/login?redirect=%2Fdashboard
2. 输入用户名 hogwarts
3. 输入密码 test12345
4. 点击登录按钮
5. 进入主页,获取此时的url
6. 执行完成,退出浏览器

通过 AGENT 执行功能测试用例。

大模型本身是不具备任何执行能力或生成能力的,它只会”思考“,但是通过 LangChain 的 Agent,可以将一些”工具”外挂到大模型身上。

那么如果要执行这些功能测试用例,大模型就需要具备执行用例的能力。而我们要做的事情,就是将 tools(工具包),外挂到大模型上面。

相关知识点: Agent、 tools

  • 封装好 web 的底层工具

class WebAutoFramework:

    def __init__(self):
        self.driver = None
        self.element = None

    def init(self):
        if not self.driver:
            self.driver = webdriver.Chrome()
            self.driver.implicitly_wait(5)

    def open(self, url):
        self.init()

        self.driver.get(url)
        return self.source()

    def source(self):
        return self.driver.execute_script(
            """
            var content="";
            document.querySelectorAll('button').forEach(x=> content+=x.outerHTML);
            document.querySelectorAll('input').forEach(x=> content+=x.outerHTML);
            //document.querySelectorAll('table').forEach(x=> content+=x.outerHTML);
            return content;
            """
        )

    def click(self):
        """
        点击当前的元素
        :return:
        """
        self.element.click()
        sleep(1)
        return self.source()

    def send_keys(self, text):
        self.element.clear()
        self.element.send_keys(text)
        return self.source()

    def find(self, locator):
        print(f"find css = {locator}")
        element = self.driver.find_element(by=By.CSS_SELECTOR, value=locator)
        self.element = element
        return self.source()

    def quit(self):
        self.driver.quit()

    def get_current_url(self):
        print(f"当前的url为{self.driver.current_url}")
        return self.driver.current_url

  • 创建工具以及其说明,并且将工具绑定到工具包中

web = WebAutoFramework()
@tool
def open(url: str):
    """
    使用浏览器打开特定的url,并返回网页内容
    """
    r = web.open(url)
    return r

@tool
def find(css: str):
    """定位网页元素"""
    return web.find(css)

@tool
def click(css: str = None):
    """以css的方式定位网页元素后点击"""
    web.find(css)
    return web.click()

@tool
def send_keys(css, text):
    """定位到css指定的元素,并输入text"""
    web.find(css)
    return web.send_keys(text)

@tool
def sleep(seconds: int):
    """等待指定的秒数"""
    time.sleep(seconds)

@tool
def quit():
    """退出浏览器"""
    web.quit()

@tool
def get_current_url():
    """获取当前的url"""
    return web.get_current_url()

tools = [open, quit, get_current_url, find, click, send_keys]

声明 Agent,并将tools传递过去:

 web_agent = create_structured_chat_agent(llm, tools, prompt)
# Create an agent executor by passing in the agent and tools
web_agent_executor = AgentExecutor(
    agent=web_agent, tools=tools,
    verbose=True,
    return_intermediate_steps=True,
    handle_parsing_errors=True)

执行 Agent:

r = web_agent_executor.invoke({"input": query})

记录执行步骤

在 Agent 的配置中,可以要求 agent 将所有的执行步骤记录下来。而执行记录会记录在返回结果中的intermediate_steps中。

而我们则需要将这些步骤取出来,按照我们的需求记录下来。

# 获取执行结果
r = agent.invoke({"input": query})
# 获取执行记录
steps = r["intermediate_steps"]
steps_info = []
# 遍历执行步骤
for step in steps:
    action = step[0]
    if isinstance(action, AgentAction):
        steps_info.append({'tool': action.tool, 'input': action.tool_input})

生成自动化测试用例。

拥有执行步骤之后,可以将执行步骤传递给大模型,然后让大模型根据执行步骤直接生成 web 自动化测试用例。


prompt = PromptTemplate.from_template("""
你是一个web自动化测试工程师,主要应用的技术栈为pytest + selenium。
以下为web自动化测试的测试步骤,测试步骤由json结构体描述
{step}

{input}
""")

AGENT 结合 CHAIN

import json

from langchain import hub
from langchain.agents import create_structured_chat_agent, AgentExecutor
from langchain.globals import set_debug
from langchain_core.agents import AgentAction
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI

from web.selenium_tools import tools

set_debug(True)

prompt = hub.pull("hwchase17/structured-chat-agent")
llm = ChatOpenAI()
web_agent = create_structured_chat_agent(llm, tools, prompt)
# Create an agent executor by passing in the agent and tools
web_agent_executor = AgentExecutor(
    agent=web_agent, tools=tools,
    verbose=True,
    return_intermediate_steps=True,
    handle_parsing_errors=True)

query = """
你是一个自动化测试工程师,接下来需要根据测试步骤,
每一步如果定位都是根据上一步的返回的html操作完成
执行对应的测试用例,测试步骤如下
1\. 打开 https://litemall.hogwarts.ceshiren.com/#/login?redirect=%2Fdashboard
2\. 输入用户名 hogwarts
3\. 输入密码 test12345
4\. 点击登录按钮
5\. 进入主页,获取此时的url
6\. 执行完成,退出浏览器
"""

def web_execute_result(_):
    # 获取执行结果
    r = web_agent_executor.invoke({"input": query})
    # 获取执行记录
    steps = r["intermediate_steps"]
    steps_info = []
    # 遍历执行步骤,获取每一步的执行步骤以及输入的信息。
    for step in steps:
        action = step[0]
        if isinstance(action, AgentAction):
            steps_info.append({'tool': action.tool, 'input': action.tool_input})
    return json.dumps(steps_info)

prompt_testcase = PromptTemplate.from_template("""
你是一个web自动化测试工程师,主要应用的技术栈为pytest + selenium。
以下为web自动化测试的测试步骤,测试步骤由json结构体描述

{step}

{input}

""")

chain = (
        RunnablePassthrough.
        assign(step=web_execute_result)
        | prompt_testcase
        | llm
        | StrOutputParser()
)

print(chain.invoke({"input": "请根据以上的信息,给出对应的web自动化测试的代码"}))

执行效果

最后,自动生成的 Web 自动化测试用例效果如下:

[图片上传失败...(image-9c2312-1724927282951)]

总结

  1. Web 自动化测试用例生成工具需求说明。
  2. 如何通过 LangChain 实现 Web 自动化测试用例生成工具。

获取更多软件测试技术资料/面试题解析,请点击!

[图片上传失败...(image-a84dea-1724927282951)]

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容