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

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

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

应用价值

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

实践演练
实现原理

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

实现思路
测试用例规范与要求

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

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


  1. 1. 打开 https://litemall.hogwarts.ceshiren.com/#/login?redirect=%2Fdashboard

  2. 2. 输入用户名 hogwarts

  3. 3. 输入密码 test12345

  4. 4. 点击登录按钮

  5. 5. 进入主页,获取此时的url

  6. 6. 执行完成,退出浏览器

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

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

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

相关知识点: Agent、 tools

  • 封装好 web 的底层工具


  1. class WebAutoFramework:

  2. def __init__(self):

  3. self.driver = None

  4. self.element = None

  5. def init(self):

  6. if not self.driver:

  7. self.driver = webdriver.Chrome()

  8. self.driver.implicitly_wait(5)

  9. def open(self, url):

  10. self.init()

  11. self.driver.get(url)

  12. return self.source()

  13. def source(self):

  14. return self.driver.execute_script(

  15. """

  16. var content="";

  17. document.querySelectorAll('button').forEach(x=> content+=x.outerHTML);

  18. document.querySelectorAll('input').forEach(x=> content+=x.outerHTML);

  19. //document.querySelectorAll('table').forEach(x=> content+=x.outerHTML);

  20. return content;

  21. """

  22. )

  23. def click(self):

  24. """

  25. 点击当前的元素

  26. :return:

  27. """

  28. self.element.click()

  29. sleep(1)

  30. return self.source()

  31. def send_keys(self, text):

  32. self.element.clear()

  33. self.element.send_keys(text)

  34. return self.source()

  35. def find(self, locator):

  36. print(f"find css = {locator}")

  37. element = self.driver.find_element(by=By.CSS_SELECTOR, value=locator)

  38. self.element = element

  39. return self.source()

  40. def quit(self):

  41. self.driver.quit()

  42. def get_current_url(self):

  43. print(f"当前的url为{self.driver.current_url}")

  44. return self.driver.current_url

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


  1. web = WebAutoFramework()

  2. @tool

  3. def open(url: str):

  4. """

  5. 使用浏览器打开特定的url,并返回网页内容

  6. """

  7. r = web.open(url)

  8. return r

  9. @tool

  10. def find(css: str):

  11. """定位网页元素"""

  12. return web.find(css)

  13. @tool

  14. def click(css: str = None):

  15. """以css的方式定位网页元素后点击"""

  16. web.find(css)

  17. return web.click()

  18. @tool

  19. def send_keys(css, text):

  20. """定位到css指定的元素,并输入text"""

  21. web.find(css)

  22. return web.send_keys(text)

  23. @tool

  24. def sleep(seconds: int):

  25. """等待指定的秒数"""

  26. time.sleep(seconds)

  27. @tool

  28. def quit():

  29. """退出浏览器"""

  30. web.quit()

  31. @tool

  32. def get_current_url():

  33. """获取当前的url"""

  34. return web.get_current_url()

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

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


  1. web_agent = create_structured_chat_agent(llm, tools, prompt)

  2. # Create an agent executor by passing in the agent and tools

  3. web_agent_executor = AgentExecutor(

  4. agent=web_agent, tools=tools,

  5. verbose=True,

  6. return_intermediate_steps=True,

  7. handle_parsing_errors=True)

执行 Agent:

r = web_agent_executor.invoke({"input": query})
记录执行步骤

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

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

  1. # 获取执行结果

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

  3. # 获取执行记录

  4. steps = r["intermediate_steps"]

  5. steps_info = []

  6. # 遍历执行步骤

  7. for step in steps:

  8. action = step[0]

  9. if isinstance(action, AgentAction):

  10. steps_info.append({'tool': action.tool, 'input': action.tool_input})

生成自动化测试用例。

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


  1. prompt = PromptTemplate.from_template("""

  2. 你是一个web自动化测试工程师,主要应用的技术栈为pytest + selenium。

  3. 以下为web自动化测试的测试步骤,测试步骤由json结构体描述

  4. {step}

  5. {input}

  6. """)

AGENT 结合 CHAIN

  1. import json

  2. from langchain import hub

  3. from langchain.agents import create_structured_chat_agent, AgentExecutor

  4. from langchain.globals import set_debug

  5. from langchain_core.agents import AgentAction

  6. from langchain_core.output_parsers import StrOutputParser

  7. from langchain_core.prompts import PromptTemplate

  8. from langchain_core.runnables import RunnablePassthrough

  9. from langchain_openai import ChatOpenAI

  10. from web.selenium_tools import tools

  11. set_debug(True)

  12. prompt = hub.pull("hwchase17/structured-chat-agent")

  13. llm = ChatOpenAI()

  14. web_agent = create_structured_chat_agent(llm, tools, prompt)

  15. # Create an agent executor by passing in the agent and tools

  16. web_agent_executor = AgentExecutor(

  17. agent=web_agent, tools=tools,

  18. verbose=True,

  19. return_intermediate_steps=True,

  20. handle_parsing_errors=True)

  21. query = """

  22. 你是一个自动化测试工程师,接下来需要根据测试步骤,

  23. 每一步如果定位都是根据上一步的返回的html操作完成

  24. 执行对应的测试用例,测试步骤如下

  25. 1. 打开 https://litemall.hogwarts.ceshiren.com/#/login?redirect=%2Fdashboard

  26. 2. 输入用户名 hogwarts

  27. 3. 输入密码 test12345

  28. 4. 点击登录按钮

  29. 5. 进入主页,获取此时的url

  30. 6. 执行完成,退出浏览器

  31. """

  32. def web_execute_result(_):

  33. # 获取执行结果

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

  35. # 获取执行记录

  36. steps = r["intermediate_steps"]

  37. steps_info = []

  38. # 遍历执行步骤,获取每一步的执行步骤以及输入的信息。

  39. for step in steps:

  40. action = step[0]

  41. if isinstance(action, AgentAction):

  42. steps_info.append({'tool': action.tool, 'input': action.tool_input})

  43. return json.dumps(steps_info)

  44. prompt_testcase = PromptTemplate.from_template("""

  45. 你是一个web自动化测试工程师,主要应用的技术栈为pytest + selenium。

  46. 以下为web自动化测试的测试步骤,测试步骤由json结构体描述

  47. {step}

  48. {input}

  49. """)

  50. chain = (

  51. RunnablePassthrough.

  52. assign(step=web_execute_result)

  53. | prompt_testcase

  54. | llm

  55. | StrOutputParser()

  56. )

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

执行效果

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

总结
  1. Web 自动化测试用例生成工具需求说明。

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

感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取   

​​​​​​​

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐