-
用了一周了,一天比一天卡啊,提个问题有时候要等10多分钟,怎么办呀?是用的人太多了,还是不够智能要算的太多了,赶紧加快速度呀!!!
yd_233687402
发表于2026-03-13 11:03:06
2026-03-13 11:03:06
最后回复
CodeArts小助手-蚂蚁
2026-03-13 11:22:30
52 1 -
最近 **Anthropic 官方发布了一份 33 页的 Claude Skills 构建指南**。很多人看到这个消息时的第一反应是:> Skills 不就是 Prompt 模板吗?如果只是这么理解,那就低估它了。这份指南其实透露了一件更大的事情:**AI 应用的开发方式正在发生变化。**过去几年,大多数 AI 应用是这样的:```用户 → Prompt → LLM → 输出```但现在越来越多 AI 系统开始变成:```用户 → Agent → Skills → 工具 → 结果```也就是说:**Prompt 在减少,能力模块在增加。**Anthropic 的这份 Skills 指南,本质是在告诉开发者:**如何把 AI 能力做成模块化系统。**---# 目录- 1 Claude Skills 到底是什么- 2 Skills 的核心设计思想- 3 Skills 的工程结构- 4 Skills + MCP 的 Agent 架构- 5 Skills 的五种设计模式- 6 Skills 如何测试- 7 Prompt工程 vs Agent工程- 8 AI Agent 技术栈- 9 为什么 Skills 会成为 Agent 的核心能力---# 1 Claude Skills 到底是什么Anthropic 的官方定义其实很简单:**Skill = 一组可复用的任务流程。** 本质上,它就是一个 **能力模块**。一个 Skill 的典型结构是:```your-skill-name/SKILL.mdscripts/references/assets/```其中最重要的是:```SKILL.md```这个文件包含:* YAML 元信息* 技能描述* 执行步骤* 示例* 错误处理例如:```yaml---name: sprint-planningdescription: 自动规划项目冲刺任务 当用户说“规划冲刺”“创建任务”时使用---```执行流程:```1 获取项目状态2 分析团队容量3 建议任务优先级4 创建任务```简单来说:**Skill = 把经验封装成模块。**---# 2 Skills 的核心设计思想Anthropic 在文档中提出了三个核心理念。 ---## 1 渐进式加载Skill 不会一次性加载全部内容。而是三层结构:```Layer1 YAML metadataLayer2 SKILL.mdLayer3 references```加载流程如下:```mermaidflowchart TDA[用户请求] --> B[加载YAML元信息]B --> C{是否触发Skill}C -->|是| D[加载SKILL.md]D --> E[执行任务流程]E --> F[按需读取references]```这种设计带来的好处:* 节省 token* 保留复杂知识* 降低上下文污染---## 2 可组合性Claude 可以 **同时加载多个 Skills**。例如:```design-skillcoding-skillanalysis-skillreport-skill```一个 Agent 任务中可能变成:```Agent ├ design skill ├ coding skill └ report skill```所以设计 Skill 时必须注意:**不要假设自己是唯一技能。**---## 3 可移植性同一个 Skill 可以运行在:* Claude.ai* Claude Code* API* Agent 系统也就是说:**写一次,到处使用。**---# 3 Skills 的工程结构官方推荐的工程结构如下:```skill-name│├── SKILL.md├── scripts├── references└── assets```每个组件的作用:| 组件 | 作用 || ---------- | ------ || SKILL.md | 核心逻辑 || scripts | 自动执行脚本 || references | 知识文档 || assets | 模板资源 |一个 Skill 的典型执行流程:```mermaidsequenceDiagramUser->>Claude: 创建项目计划Claude->>Skill: 触发SkillSkill->>MCP: 获取项目数据MCP->>Skill: 返回数据Skill->>Claude: 生成计划Claude->>User: 输出结果```---# 4 Skills + MCP 的 Agent 架构如果说:**MCP 是连接层**那么:**Skills 就是知识层。** 架构如下:```mermaidflowchart TDUser --> AgentAgent --> SkillsSkills --> MCPMCP --> GitHubMCP --> NotionMCP --> LinearMCP --> Slack```一句话总结:```MCP 解决:AI 能做什么Skills 解决:AI 应该怎么做```---# 5 Skills 的五种设计模式Anthropic 总结了五种常见设计模式。---## 1 顺序工作流适合:多步骤自动化任务。```创建账户↓设置支付↓创建订阅↓发送欢迎邮件```---## 2 多 MCP 协同例如设计交接流程:```mermaidflowchart TDA[Figma MCP]A --> B[导出设计资产]B --> C[Drive MCP]C --> D[创建文件夹]D --> E[Linear MCP]E --> F[创建开发任务]F --> G[Slack MCP]G --> H[通知团队]```---## 3 迭代优化适合:报告生成、数据分析。```生成初稿↓质量检查↓修改↓重新验证```---## 4 情境工具选择```大文件 → 云存储协作文档 → Notion代码文件 → GitHub```---## 5 领域知识 Skill例如金融风控系统:* 风险规则* 合规流程* 审计记录都可以嵌入 Skill 中。---# 6 Skills 如何测试官方给出三种测试方式。 ---## 1 触发测试验证 Skill 是否正确触发。例如:应该触发:```帮我创建项目帮我规划冲刺创建任务```不应该触发:```今天天气写Python脚本```---## 2 功能测试验证任务是否成功执行。例如检查:```任务是否创建参数是否正确MCP调用是否成功```---## 3 对比测试比较:```无 Skillvs有 Skill```官方示例:| 指标 | 无技能 | 有技能 || ------- | ----- | ---- || 消息数 | 15 | 2 || API错误 | 3 | 0 || token消耗 | 12000 | 6000 |---# 7 Prompt工程 vs Agent工程这张图最能说明问题:```mermaidflowchart LRPrompt[Prompt]Prompt --> LLMLLM --> OutputAgent[Agent]Agent --> SkillsSkills --> ToolsTools --> Result```对比:```传统AI应用Prompt → LLM → 输出Agent系统Agent → Skills → 工具 → 结果```---# 8 AI Agent 技术栈如果从系统架构看,AI Agent 的技术栈大致如下:```mermaidflowchart TDUser --> AgentAgent --> MemoryAgent --> SkillsSkills --> MCPMCP --> ToolsTools --> ExternalSystems```系统分层:```用户↓Agent↓Skills↓MCP↓外部系统```---# 9 为什么 Skills 会成为 Agent 的核心能力Prompt 最大的问题是:**经验无法沉淀。**每次都要重新写。但 Skills 可以:```把经验封装成能力模块```例如:```coding-skillanalysis-skillreport-skilldesign-skill```未来 AI 系统很可能变成:```mermaidflowchart TDAgentOS --> SkillsMarketplaceSkillsMarketplace --> MCPMCP --> ToolsTools --> ExternalSystems```也就是:```Agent+ Skills+ MCP+ Tools```这非常像软件系统:```操作系统+ 函数库+ 插件```---# 结语Anthropic 发布 Skills 指南,其实透露出一个非常清晰的趋势:**AI 正在从“聊天系统”变成“能力系统”。**未来 AI 工程的核心很可能不再是:```Prompt Engineering```而是:```Agent Engineering```在这种架构下:* Skills 是能力模块* MCP 是工具连接层* Agent 是调度系统如果你正在做:* AI Agent* 自动化系统* MCP工具* 企业AI应用那么 Skills 这种能力封装方式,很可能会成为 **下一代 AI 工程的重要模式**。
-
WebElement是WebDriver.find_element()方法返回的一个对象,该对象用来描述Web上的一个元素,比如输入框,按钮等。本节介绍WebElement的常用属性和方法。一、WebElement的常用属性属性属性描述1id标识2size宽高3rect宽高和坐标4tag_name标签名称5text文本内容二、WebElement的常用方法方法方法描述1send_keys()输入内容2clear()清空内容3click()单击4get_attribute()获得属性值5is_selected()是否被选中6is_enabled()是否可用7is_displayed()是否显示8value_of_css_property()css属性值三、代码示例from time import sleepfrom selenium import webdriverfrom selenium.webdriver.common.by import Byclass Testcase: def __init__(self): self.driver = webdriver.Edge() self.driver.get("https://sahitest.com/demo/linkTest.htm") self.driver.maximize_window() #输出属性值 def test_webelement_prop(self): e = self.driver.find_element(By.ID, "t1") print(type(e))#类型:WebElement print(e.tag_name)#标签名:input print(e.rect)#宽高和坐标 print(e.size)#宽高 print(e.text)#文本:可空 #测试方法 def test_webelement_method(self): e=self.driver.find_element(By.ID, "t1") e.send_keys("Hello World")#输入内容 #get_attribute()获取属性值 print(e.get_attribute('type'))#类型:text print(e.get_attribute('name')) print(e.get_attribute('value'))#值:Hello World print(e.value_of_css_property('font'))#字体 print(e.value_of_css_property('color')) #颜色 sleep(2) e.clear()#清空内容 sleep(2) if __name__ == "__main__": testcase=Testcase() testcase.test_webelement_prop() #testcase.test_webelement_method()`
-
Selenium中有三种弹框,本文介绍了处理三种弹框的方法一、Selenium三种弹框alert:用来提示,显示一个带有指定消息和确认按钮的警告框confirm:用于确认,显示一个带有指定消息和确定及取消按钮的对话框prompt:用于用户输入内容,显示可进行输入的对话框这三种弹框不是html的页面元素,而是javascript的控件,所以不能用传统的方法去操作,需要用另外的方法操作,下面介绍处理三种弹框的方法已经弹框的属性:(1)accept():用于确认,适用三种弹框(2)dismiss():用于取消,适用三种弹框(3)send_keys():仅适用于prompt方法,用于输入文本(4)text:用于获取提示的文本值二、定义form表单定义三个超链接,点击分别弹出不同弹框 <a href="javascript:alert('提示框')" id="alert">Alert</a><br><a href="javascript:confirm('确认删除吗')" id="confirm">Confirm</a><br>prompt返回内容存在变量age中,取到返回值后将变量写入页面<a href="javascript:var age=prompt('请输入年龄');document.write(age)" id="prompt">Prompt</a><br>界面如下三、表单测试1、alert测试(1)用例1:点击超链接alert结果1:弹出alert类型弹窗自动化代码:直接调用WebElement类中的click()方法 self.driver.find_element(By.ID,"alert").click()#点击超链接alert(2)用例2:弹框中点击确定结果2:弹框消失自动化代码:首先需要将Webdriver的作用域从主窗口切到弹框上,操作三种弹框:alert、confirm、prompt前,都需要执行该操作,用到的方法是self.driver.switch_to.alert,第二步就可以在弹框中操作,点击确定,用到的方法是accept() alert=self.driver.switch_to.alert#由主窗口切换到alert,返回一个alert对象sleep(2)#print(alert.text)alert.accept()#点击确定sleep(2)2、confirm测试(1)用例1:点击超链接confirm结果2:弹出confirm类型的弹框自动化代码:同样直接调用WebElement类中的click()方法 self.driver.find_element(By.ID,"confirm").click()#点击confirm超链接(2)用例2:点击确定结果2:弹框消失自动化代码:用到的方法是accept() confirm=self.driver.switch_to.alert#切换至confirm弹框sleep(2)print(confirm.text)#打印弹窗中文本confirm.accept()#点击确定sleep(2)(3)用例3:点击取消结果3:弹框消失自动化代码:用到的方法是dismiss() confirm.dismiss()#点击取消sleep(2)3、prompt测试(1)用例1:点击超链接prompt结果1:弹出prompt类型弹框自动化代码:直接调用WebElement类中的click()方法 self.driver.find_element(By.ID,"prompt").click()(2)用例2:输入内容并确认用例2:文本成功输入并写入页面自动化代码:输入文本用到的是send_keys()方法,点击确定用到的是accept() prompt=self.driver.switch_to.alert#切换到prompt弹框sleep(2)prompt.send_keys('12')sleep(2)prompt.accept()sleep(2)
-
处理form表单中的下拉列表,需要用到一个Selenium工具类-Select一、Select工具类常用属性和方法方法/属性描述1select_by_value()根据值选择2select_by_index()根据索引选择3select_by_visible_text()根据文本选择4deselect_by_value根据值反选5deselect_by_index()根据索引反选6deselect_by_visible_text()根据文本反选7deselect_all()反选所有8options所有选项9all_selected_options所有选中选项10frist_selected_option第一个选择选项二、form表单测试1、下拉列表选项为单选时,定义from表单(1)form表单代码 <select name="provise" id="provise"></select>如下图所示,form表单中定义了一个单选城市的下拉列表(2)测试用例用例:选中不同选项结果:可正常选中,各个选项互斥自动执行测试用例代码:利用Select类中三个不同方法实现:select_by_value(); select_by_index(); select_by_visible_text() select.select_by_index(1)#根据索引值选中选项,index:0,1,2···sleep(2)select.select_by_value('bj')#根据值选中选项sleep(2)select.select_by_visible_text('TianJing')#根据可视化文本选中对象sleep(2)2、下拉列表选项为多选时,需多定义一个属性multiple(1)form表单代码 <select name="provise" id="provise" multiple></select>如下图所示,定义了一个可多选城市的form表单(2)测试用例1用例1:选中多个选项结果1:可正常选中,各个选项不互斥自动化执行测试用例代码:通过索引遍历选项,逐个选中,用到的Select类方法是select_by_index():通过索引选中 #多选的情况下将选项全选for i in range(3):select.select_by_index(i)sleep(1)sleep(2)也可以利用的是Select类中options属性,遍历options列表逐个点击 for option in select.options:option.click()#点击选项sleep(2)sleep(2)(3)测试用例2用例2:反选所有选项结果2:所有选项取消选中状态自动化执行用例代码:用到Select类中的deselect_all()方法 #反选全部select.deselect_all()sleep(2)三、总代码1、form表单定义<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/html" xmlns="http://www.w3.org/1999/html"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <form action="javascript:alert('test')" > provide: <select name="provise" id="provise" multiple> <option value="bj">BeiJing</option> <option value="sh">ShangHai</option> <option value="tj">TianJing</option> </select></form></body></html>2、form表单测试from selenium import webdriverfrom time import sleepimport osfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.select import Select class Testcase(object):#继承object类 def __init__(self): self.driver=webdriver.Edge() path=os.path.dirname(os.path.abspath(__file__)) file_path ='file:///' + path + '/form2.html' self.driver.get(file_path)#加载form表单 def test_select(self): se=self.driver.find_element(By.ID,"provise")#定位元素 select=Select(se)#实例化Select对象,参数为WebElement对象 # select.select_by_index(1)#根据索引值选中选项,index:0,1,2··· # sleep(2) # select.select_by_value('bj')#根据值选中选项 # sleep(2) # select.select_by_visible_text('TianJing')#根据可视化文本选中对象 # sleep(2) # #多选的情况下将选项全选 # for i in range(3): # select.select_by_index(i) # sleep(1) # sleep(2) # # #反选全部 # select.deselect_all() # sleep(2) for option in select.options: option.click()#点击选项 sleep(2) sleep(2) self.driver.quit() if __name__=="__main__": case=Testcase() case.test_select()
-
一、定义form表单用到的元素:checkbox和radiobutton下图定义了一个选择爱好和选择性别的form表单,区域1用到的表单元素是checkbox(复选框),区域2用到的表单元素是radiobutton<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><form action="javascript:alert('test')"> swimming:<input type="checkbox" name="swimming" value="swimming"><br> reading:<input type="checkbox" name="reading" value="reading"><br><hr> gender<br> <input type="radio" name="gender" value="male" text="male"><label>male</label><br> <input type="radio" name="gender" value="female" text="female"><label>female</label><br> <input type="submit" name="login" value="login"></form></body></html>二、测试checkbox用例1:选中checkbox选项预期结果1:正常选中 swimming=self.driver.find_element(By.NAME, 'swimming')#定位元素if not swimming.is_selected():swimming.click() #选中swimmingreading=self.driver.find_element(By.NAME, 'reading')#定位元素if not reading.is_selected():reading.click() #选中readingsleep(10)用例2:反选checkbox选项结果2:不选中选项 swimming.click()sleep(2)三、测试radiobutton用例1:选中男性结果1:正常选中 ls=self.driver.find_elements(By.NAME, 'gender')#find_elements()方法返回一个WebElement对象列表ls[0].click()sleep(2)用例2:选中女性结果2:正常选中 ls=self.driver.find_elements(By.NAME, 'gender')ls[1].click()sleep(2)四、代码from selenium import webdriverfrom time import sleepimport osfrom selenium.webdriver.common.by import By class TestCase: def __init__(self): self.driver = webdriver.Edge() path = os.path.dirname(os.path.abspath(__file__)) # 获取当前路径的父目录 file_path = 'file:///' + path + '/form1.html' # 获取form表单完整路径 self.driver.get(file_path) # 加载form表单 def test_checkbox(self): swimming=self.driver.find_element(By.NAME, 'swimming') if not swimming.is_selected(): swimming.click()# 选中swimming reading=self.driver.find_element(By.NAME, 'reading') if not reading.is_selected(): reading.click() # 选中reading sleep(2) swimming.click() sleep(2) self.driver.quit() def test_radio(self): ls=self.driver.find_elements(By.NAME, 'gender') #ls[0].click() ls[1].click() sleep(2) self.driver.quit() if __name__=="__main__": case = TestCase() #case.test_checkbox() case.test_radio()
-
from表单是经常测试的用例,用户登录、注册等都会用到form表单,本文简单设计了一个用户登录的form表单,并对该form表单进行测试一、自定义form表单1、用到的组件如下图,图中定义了一个登录界面的form表单,用到的表单元素:type="text"; type="submit"2、代码示例新建HTML文件文件中输入代码<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><form action="javascript:alert('hello')"> Username:<input type="text" name="username" id="username"><br> Password:<input type="text" name="pwd" id="pwd"><br> Submit:<input type="submit" value="submit" id="submit"></form></body></html>二、form表单测试1、定位表单元素(1)获取form表单路径(a)当前文件所在路径 path = os.path.abspath(__file__)#获取当前完整路径,即绝对路径#print(file_path)输出:C:...\desktop\demo.py(b)当前路径的父目录 path = os.path.dirname(os.path.abspath(__file__))#获取当前路径的父目录print(path)输出:C:...\desktop(c)form表单完整路径 file_path = 'file:///'+path + '/form.html'#获取form表单完整路径print(file_path)输出:C:...\desktop\form.html(2)加载form表单 self.driver.get(file_path)2、输入测试值测试值1:输入账号和密码并提交 username=self.driver.find_element(By.ID,"username")#定位元素username.send_keys("admin")#账号:adminpwd=self.driver.find_element(By.ID,"pwd")#定位元素pwd.send_keys('123')#密码:123sleep(2)self.driver.find_element(By.ID,"submit").click()#提交结果1:弹出提示框,提示“Hello”测试值2:获取输入的账号密码 self.driver.switch_to.alert.accept()#关闭提示print(username.get_attribute('value'))#获取输入的账号print(pwd.get_attribute('value'))#获取输入的密码结果2:控制台输出账号密码测试值3:清空账号密码 username.clear()pwd.clear()结果3:输入框中账号密码被清空from time import sleepfrom selenium import webdriverimport osfrom selenium.webdriver.common.by import By class Testcase: def __init__(self): self.driver=webdriver.Edge() #path = os.path.abspath(__file__)#获取当前完整路径,即绝对路径 path = os.path.dirname(os.path.abspath(__file__)) #获取当前路径的父目录 file_path = 'file:///'+path + '/form.html'#获取form表单完整路径 self.driver.get(file_path)#加载form表单 #print(file_path) def test_login(self): #用例1 username=self.driver.find_element(By.ID,"username")#定位元素 username.send_keys("admin")#账号:admin pwd=self.driver.find_element(By.ID,"pwd")#定位元素 pwd.send_keys('123')#密码:123 sleep(2) self.driver.find_element(By.ID,"submit").click()#提交 #用例2 self.driver.switch_to.alert.accept()#关闭提示 print(username.get_attribute('value'))#获取输入的账号 print(pwd.get_attribute('value'))#获取输入的密码 #用例3 username.clear() pwd.clear() sleep(2) self.driver.quit() if __name__=="__main__": case=Testcase() case.test_login()
-
除了上一篇的元素定位方法,Selenium中的WebDriver类中还有一些常用的属性和方法一、常用的属性1、下表列出了WebDriver的常用属性#属性属性描述用途1driver.name浏览器名称2driver.url当前url3driver.title当前页面标题可用于判断是否成功打开目标页面4driver.page_source当前页面源码5driver.current_window_handle窗口句柄6driver.window_handles当前窗口所有句柄2、代码示例下面代码能够输出webdriver类中属性的值` from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom time import sleep class Testcase: def __init__(self): self.driver = webdriver.Edge() self.driver.get("https://www.baidu.com") #输出WebDriver类常用的属性 def test_prop(self): print(self.driver.name) print(self.driver.current_url) print(self.driver.title) print(self.driver.current_window_handle) #print(self.driver.page_source) if __name__ == '__main__': testcase=Testcase() testcase.test_prop()输出结果如下:二、常用的方法1、下表列出了WebDriver类常用方法#方法用途1driver.find_element()定位元素2driver.switch_to.window()切换窗口,目标页面句柄作为参数3driver.back()后退至上一页面4driver.forward()前进至下一页面5driver.refresh()刷新当前页面6driver.close()关闭当前窗口7driver.quit()关闭所有窗口2、代码示例以下代码调用WebDriver中常用方法from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom time import sleep class Testcase: def __init__(self): self.driver = webdriver.Edge() self.driver.get("https://www.baidu.com") def test_method(self): #输入框中输入关键词“Python”并点击搜索 self.driver.find_element(By.ID, "kw").send_keys("Python") self.driver.find_element(By.ID,"su").click() sleep(2) #点击链接,打开另一个窗口 self.driver.find_element(By.LINK_TEXT,"百度百科").click() sleep(2) #切换回第一个窗口 self.driver.switch_to.window(self.driver.window_handles[0]) sleep(2) #后退到上一页面 self.driver.back() sleep(2) #前进到下一页面 self.driver.forward() sleep(2) #刷新当前页面 self.driver.refresh() sleep(2) #关闭当前窗口 self.driver.close() sleep(2) #关闭整个页面,所有窗口 self.driver.quit() if __name__ == '__main__': testcase=Testcase() testcase.test_method()
-
Selenium提供了定位元素的方法find_element(),该方法被定义在WebDriver类中。一、参数1、两个参数,参数1根据不同定位方法确定,定位方法如下:(1)通过id定位:使用参数By.ID定位元素的ID属性;(2)通过元素名定位:使用参数By.NAME定位元素的NAME属性;(3)通过标签名定位:使用参数BY.TAG_NAME定位元素的TAG_NAME属性;一般不使用该参数,使用该参数后方法会返回list,不能准确定位所找元素(4)通过xpath定位:使用参数By.XPATH通过xpath表达式定位元素;(5)通过css class定位:使用参数By.CLASS_NAME定位元素的class属性;(6)通过css选择器定位:使用参数By.CSS_SELECTOR通过CSS选择器定位元素;(7)通过链接文本定位:使用参数By.LINK_TEXT定位元素(8)通过部分链接文本定位:使用参数By.PARTIAL_LINK_TEXT定位元素2、参数2为上述对应属性的值如何确定参数2:打开网页,选择任意元素,比如输入框,按钮,右键单击检查,就会有对应属性出现。以百度为例:By.ID="kw"By.NAME="wd"By.TAG_NAME="input"By.CLASS_NAME="s_ipt"By.XPATH和By.CSS_SELECTOR可右键单击该元素,直接复制By.LINK_TEXT和By.PARTIAL_LINK_TEXT为页面上任意链接文本,比如百度页面上的"新闻","首页"等,均可作为其值,两者区别在于,前者为链接的全部文本,后者为链接的部分文本二、返回值返回一个WebElement对象,这个对象代表页面上的一个元素三、简单的代码示例以下是一个简单的示例代码,展示如何使用find_element()方法通过各个属性定位元素from time import sleepfrom selenium import webdriverfrom selenium.webdriver.common.by import By #将各个元素定位方法封装成一个类class TestCase: #初始化方法 def __init__(self): #驱动程序打开浏览器 self.driver=webdriver.Edge() #跳转对应网页 self.driver.get("http://www.baidu.com") #网页最大化 self.driver.maximize_window() #通过id定位元素 def test_id(self): #网页中定位到输入框,输入关键词python self.driver.find_element(By.ID,"kw").send_keys("python") #定位到按钮并点击搜索 self.driver.find_element(By.ID,"su").click() sleep(2) quit() #通过name定位元素 def test_name(self): self.driver.find_element(By.NAME,"wd").send_keys("selenium") self.driver.find_element(By.ID,"su").click() sleep(2) quit() #通过xpath定位元素 def test_xpath(self): self.driver.find_element(By.XPATH,"//*[@id='kw']").send_keys("selenium") self.driver.find_element(By.XPATH,"//*[@id='su']").click() sleep(2) quit() #通过CSS_SELECTOR定位 def test_css_selector(self): self.driver.find_element(By.CSS_SELECTOR,"#kw").send_keys("selenium") self.driver.find_element(By.CSS_SELECTOR,"#su").click() sleep(2) quit() #通过CSS_NAME定位元素 def test_class_name(self): self.driver.find_element(By.CLASS_NAME,"s_ipt").send_keys("selenium") self.driver.find_element(By.ID,"su").click() sleep(2) quit() #通过LINK_TEXT定位元素 def test_link_text(self): #网页中找到"贴吧"文本的链接并点击 self.driver.find_element(By.LINK_TEXT,"贴吧").click() sleep(2) quit() #通过PARTIAL_LINK_TEXT定位元素 def test_partial_link_text(self): #网页中找到含有"AI"文本的链接并点击 self.driver.find_element(By.PARTIAL_LINK_TEXT,"AI").click() sleep(2) quit() if __name__ == "__main__": testcase = TestCase() #testcase.test_id() #testcase.test_name() #testcase.test_xpath() #testcase.test_css_selector() #testcase.test_class_name() #testcase.test_link_text() testcase.test_partial_link_text()
-
如何构建企业测试中台,实现一站式云端全流程测试自动化解决方案?本期直播将聚焦华为云PaaS 测试计划(CodeArts TestPlan)服务,它是面向软件开发者提供的一站式云端测试平台,覆盖测试管理、接口测试,融入DevOps敏捷测试理念,帮助您高效管理测试活动,保障产品高质量交付。直播链接:cid:link_0Q:自动化测试在不同数据源下怎么做数据整合?A:如果不同数据源只的是针对不同的测试数据。TestPlan的接口自动化测试,提供了全局变量功能,在全局变量中支持配置不同的环境变量。Q:如何在不牺牲性能的前提下,支持更多的用户和测试用例?A:要支持更多的用户和测试用例,实际就是要提高并发。这就要求客户端能提供更大的并发数量,以及服务端提供更高的处理性能(吞吐量,请求处理时延等),同时,用例脚本本身的测试内容也要在合理的范围内。 如果用例或系统已经没有优化的空间,提高并发,必然也需要更大的性能开销。Q:做过的测试用例可以形成模板吗?用例间依赖关系如何管理?A:暂不支持将已有用例固化为模板。但,在测试用例页面的右上角,有一个测试资产中心,内置了大量优秀的测试用例作为范本。 用例间要尽量减少耦合,如果有前后置需求,如接口自动化,可以在创建测试套时,使用前置用例,或后置用例进行管理,用例之间可以使用动态全局变量进行数据传递。Q:服务支持哪些协议和标准(如REST, SOAP, GraphQL等)进行接口测试,是否有扩展性?A:CodeArts TestPlan支持Restful接口,同时系统关键字也提供了系统关键字,进行中间件(redis、obs、kafka),数据库(MongoDB、Mysql)的关键字,而且处于持续更新中,更多关键字可以联系技术支持。Q:测试用例批量导入和导出支持哪些格式?A:手工和功能自动化测试用例支持excel导入导出,接口自动化支持postman、swagger、exce方式导入,和excel的导出。Q:自动化测试可以自定义系统资源的动态分配吗?A:自动化测试,可以根据需要选择自定义资源池,控制资源的使用。Q:测试用例如何进行版本回溯?最多可以保留多少个版本?A:版本回溯属于业务流程管控,平台当前没有内置该流程。专业版\企业版最多可以保留50个版本(包括基线版本)。Q:测试中台如何实现灾难恢复和保证业务连续性?在发生系统故障时,如何快速恢复测试活动?A:公有云和私有云都是多AZ部署,平台经过系统的可靠性、韧性测试。Q:CodeArts TestPlan是否支持基于风险的测试策略?A:测试设计中内置了华为公司多年沉淀的测试策略和设计模板,可以作为参考,输出自有产品的测试策略。Q:对于测试覆盖率,平台有功能生成全覆盖的脚本吗A:基于风险的测试策略下,测试是无法穷尽的。但是在确定的场景下,可以使用测试设计,基于因子组合选择全组合的方式生成用例。Q:如果不同的语言环境,能配合k8s+docker进行自动化测试吗?比如有java,有c++,有pythonA:支持,使用功能自动化,可以支持接入自定义执行机,支持任意脚本语言。Q:如何确保自动化测试脚本的稳定性和可维护性?A:可以通过三层用例管理,以版本的方式管理用例和对应的脚本。Q:CodeArts TestPlan支持移动端应用测试吗?目前适配哪些类型终端?A:CodeArts TestPlan的功能自动化能力,没有内置具体的移动端测试框架,可以支持接入自定义执行机(和测试框架),提供对应的移动端功能测试。Q:华为云PaaS测试计划(CodeArts TestPlan)的测试计划包含哪些内容?A:包含迭代、版本、周期、需求范围等内容。Q:做跨平台测试,不同操作系统和浏览器间可以支持吗?A:支持,可以使用功能自动化测试,支持接入自定义执行机(和测试框架),不限制具体的操作系统和浏览器。Q:自动化测试的脚本,可以和现有的融合吗?比如pytest的或者其他的A:支持,可以使用功能自动化测试,支持接入自定义执行机(和测试框架),不限制具体脚本语言。Q:如何确保不同团队(开发、测试、运维)在使用测试中台时的高效协作?A:测试计划(CodeArts TestPlan)是面向软件开发者提供的一站式云端测试平台,覆盖测试管理、接口测试,融入DevOps敏捷测试理念,帮助您高效管理测试活动,保障产品高质量交付。Q:测试用例可以做优先级排序吗?应该遵循什么原则排序?A:用例有不同的等级,分别用P0、P1…表示。0级:最基本的功能验证,用例不宜过多,各模块尽量保证在10-20个,占比5%左右1级:基本功能验证,可用于继承特性的基本功能验证、迭代验收前的基本功能验证等,占比20%左右2级:重要特性验证,可用于测试版本(非回归版本)中手工测试,占比60%左右3级:一般功能/非重要功能验证,包括对基本/重要功能的异常测试,占比10%~15%左右4级:非常特殊输入、场景、阈值条件的用例,该级别用例不宜过多,占比0%~5%左右Q:CodeArts TestPlan支持自定义测试模板吗?A:暂不支持将已有用例固化为模板。在测试用例页面的右上角,有一个测试资产中心,内置了大量优秀的测试用例作为范本。Q:华为云PaaS测试计划(CodeArts TestPlan)的测试设计有哪些方式?A:支持按特性或需求创建,也可以使用空白脑图,或基于模板创建。Q:在DevOps环境下,如何实现测试活动的自动化和持续集成?A:可以通过在流水线中配置测试验证的插件来实现。部署完成,就可以执行一遍对应的自动化测试。Q:在性能测试方面,该平台提供哪些实时监控和分析工具,以帮助开发者快速识别和解决性能瓶颈?A:支持AOM和APM,可以帮助分析cpu、内存等指标,以及调用链指标,配合压测指标曲线快速识别问题。Q:华为云PaaS测试计划(CodeArts TestPlan)产品都有哪些特性?A:测试计划(CodeArts TestPlan)是一款自主研发的一站式测试管理平台,沉淀了华为多年高质量的软件测试工程方法与实践,覆盖测试计划、测试设计、测试用例、测试执行和测试评估等全流程,旨在帮助企业协同、高效、可信的开展测试活动,保障产品高质量上市。Q:测试数据怎么做隔离和清理?A:可以通过全局变量中的环境进行隔离,同时,可以在测试的后置步骤中进行清理操作。Q:华为云PaaS测试计划(CodeArts TestPlan)产品使用流程包括哪些?A:通用的流程包括测试计划、测试设计、测试用例、测试执行和测试评估。Q:在编写接口测试自动化脚本过程中,前后步骤如何传递变量?A:可以使用局部变量,或动态全局变量。Q:CodeArts TestPlan在软件交付方面有哪些优势?A:大规模高效协同测试、启发式测试设计、测试验证双向可追溯、自动化测试、可视化设计与度量等。Q:支持压力测试和负载测试?A:可以使用CodeArts PerfTest进行压测和负载测试,服务提供了丰富的压测模型,灵活的用例脚本,可以满足多种压测场景的使用。Q:该服务支持哪些编程语言?A:支持,可以使用功能自动化测试,支持接入自定义执行机(和测试框架),不限制具体脚本语言。Q:使用CodeArts TestPlan时,如何处理接口自动化脚本文件过大问题?A:首先,需要建立好用例规范,每个用例建议不要包含过多的用例步骤;其次,常用的脚本可以封装为关键字、组合关键字。Q:华为云PaaS 测试计划(CodeArts TestPlan)服务适用于哪些应用场景?A:如:软件测试和质量管理场景、持续自动化测试场景等。想要了解更多华为云PaaS 测试计划(CodeArts TestPlan)服务相关知识,欢迎观看DTSE Tech Talk 系列技术直播
-
有哪些好用的自动化测试工具
-
单元测试/集成测试自动化工具--WinAMSCoverageMaster winAMS : 适用于嵌入式目标机代码的单元测试/集成测试工具全面支持嵌入式微机!验证嵌入式C/C++软件 实施以模块为单位的自动化单元测试工具不需要HookCode 直接使用目标机代码进行单元测试联合静态解析工具[CasePlayer2],提供C0(语句),C1(判定),MC/DC覆盖率报告,优化测试用例制作已取得第三方认证机构TUVSUD对适用于汽车机能安全ISO26262软件工具的认证产品概要[Coverage master winAMS]是以嵌入式软件的函数为单位,实施模块单元测试以及C0/C1/MCDC覆盖率测试(coverage test)的嵌入式软件自动化单元测试工具。目标机源代码通过交叉编译器生成目标机执行代码,通过跟实际处理器同样的模拟处理器环境进行单元测试,不需要对执行代码做任何变动,使高信赖性的模块测试成为可能。在汽车控制软件这样的对安全性要求极高的领域,单元测试已经成为不可缺少的一部分。使用目标机代码进行单元测试也是为了符合汽车行业中ISO26262功能安全认证标准。产品特长全面支持嵌入式微机!验证嵌入式C/C++软件 实施以模块为单位的自动化单元测试工具作为能够检验出仅凭系统测试以及整体测试无法发现的[潜在错误]的检测方法,[单元测试]在嵌入式开发领域受到广泛重视。同时,单元测试也是汽车用软件功能安全(ISO26262)领域中要求实施的认证项目之一。[Coverage master winAMS]直接使用通过交叉编译生成的目标机代码,在模拟处理器环境下进行单元测试。既能实现C语言程序的逻辑上的单元验证,又能够对嵌入式微机组装为产品后可能发生的问题等进行具有高信赖度的白盒(white box)测试。不需要HookCode 使直接使用目标机代码进行单元测试成为可能的业界唯一的工具有些公司的单元测试工具往往采用在被测试对象的源代码中追加测试用代码或者测试用驱动器的方法,导致测试时所用的代码与组装为产品后的目标机用代码不同。虽然[理论上运行功能应该是相同的],但是从嵌入式开发的角度考虑,这样就如同对交叉编译所生成的经过优化处理的代码进行了加工,无法确保最终产品的质量。Coverage master winAMS是业界唯一的,具有[不需要对被测试对象做任何加工]实施单元测试功能的工具,特别是在安全性要求高的领域中得到很高的评价。不需建立单元测试专用的环境,可以在开发用交叉编译环境进行单元测试Coverage master winAMS不需要追加任何测试用驱动器或测试用代码,可以直接使用将组装成产品的目标代码进行单元测试。单元测试能够与软件开发使用共同的交叉编译环境,不再需要对测试资源进行专门管理,也不再需要建立其他专用环境。因此,既方便程序资源管理,又能够缩短准备测试环境所需的时间。符合汽车功能安全标准(ISO26262)[不做加工直接使用目标机代码实施单元测试]这一要求的最佳工具ISO26262是从IEC61508衍生出来的适用于汽车制造领域的功能安全标准。其中的Part.6-9[软件程序单元测试]包括了关于软件程序的构造覆盖率测试以及有关的规定项目。根据汽车安全标准(ASIL),提出了测试语句覆盖率(statement coverage),分支覆盖率(branch coverage),MC/DC覆盖率的推荐性事项。其中的另一个推荐性事项是[尽可能使单元测试的环境与目标环境相同]的规定。如果在与目标环境不同的环境下进行单元测试,必须表明源代码与目标代码的差别,以及目标环境和测试环境的差别。因此,对于那些使用与目标微机不同的电脑进行编译和单元测试的其他公司的工具而言,这个要求很难满足。 还有些公司的单元测试工具虽然包括交叉编译环境及编译功能,而且也能够在与目标环境相同的环境下进行测试,但是所有的测试都需要插入测试用代码,进行再次编译,因此测试也只能在与目标环境不同的环境下实施。GAIO提供的单元测试工具Coverage master winAMS具有●采用全面支持嵌入式微机的微机化功能测试平台环境●不需要插入测试用代码直接使用目标机代码进行测试的特征,提供符合ISO26262标准要求的必须功能。GAIO提供的Coverage master winAMS是符合ISO26262标准[直接使用整装用代码实施单元测试]这一要求的业界唯一的工具。关于汽车机能安全ISO26262的对应以及认证的获得已取得第三方认证机构TUVSUD对适用于汽车机能安全ISO26262软件工具的认证2012年6月28日,「Coverage master winAMS / General」测试工具获得由德国TUVSUD第三方认证机构,在汽车机能安全规格的ISO26262软件工具方面的认证,包括日本在内亚洲地区首次获得该项认证。通过此项认证,说明本公司的单元测试工具「Coverage master winAMS / General」,以及程序分析工具「CasePlayer2」,在静态分析和单元测试领域,是符合所有安全度水准的工具,并由TUVSUD认证机构得到了保障。ISO 26262对于不同的开发用软件工具在工具置信水平(TCL),都需要开发者提供开发软件工具的认证书。此项认证适用于在工具认证当中,最为复杂的TCL3工具认证标准。因此,导入本公司的单元测试工具之后,不需要对TCL的部分进行认证,进而可以缩减手续跟时间。主要的单元测试功能采用SSTManager管理单元测试projectSSTManager是Coverage master winAMS的应用功能,用于管理单元测试project,制作测试数据(test data)。从设定测试环境开始,到报告测试结果为止,均由微机化功能测试平台(ISS)实施综合管理。采用通用便利的CSV文件管理测试数据的输入输出Coverage master winAMS不需要插入测试用代码,直接使用目标机代码进行单元测试。采用通用便利的CSV文件管理函数测试时使用的输入输出数据。测试结束后,输出的测试结果和输出的期待值也将以相同的格式显示在CSV文件之中。C0/C1覆盖率报告的自动化制作功能(标准功能)根据测试的输入输出数据自动报告相应源代码的C0/C1测试覆盖率结果。包括通过图形(viewer)显示测试数据,以及与其相应的被测试的源代码路径的功能,用于分析测试结果。作为选项功能也包括MC/DC覆盖率测试功能。MC/DC覆盖率的自动化测试功能(选项功能)作为选项功能提供MC/DC覆盖率测试功能。C0/C1覆盖率测试不需要加工即可直接使用目标机代码。然而,MC/DC覆盖率测试对于复合式的条件式,需要自动插入HookCode将复合式的条件式分解,才能对各条件式进行测试。这样就有可能导致测试用代码与目标机用代码的不同。为了验证HookCode的妥当性,在MC/DC覆盖率测试的同时,运行目标机代码,确认运行结果与期待值的一致性。注:右图举例显示,第2个if句的复合条件式中,[gbc>30]为false时的分支没有被测试到。以C1覆盖率测试来说,它的测试结果是OK;而对于MC/DC覆盖率测试来说,它的结果是NG。注: MC/DC覆盖率测试功能不支持C++程序。单元测试的效率化功能联合程序解析工具CasePlayer2,实现代码参照解析作业的效率化利用CasePlayer2生成的流程图表以及模块构造图(调用函数的构造图)与源代码的连接(link)功能,使单元测试用源代码的解析工作效率化。能够自动检索被测试函数的外部变量,使测试条件设定效率化联合程序解析工具CasePlayer2,自动检索被测试函数所使用的外部变量。缩短了以往必须对源代码进行搜索找出输入条件的变量所需的工作。而且,能够防止人工操作导致的类似变量指定遗漏的的错误。根据代码解析自动化制作C0,C1,MC/DC 覆盖率测试计划联合程序解析工具CasePlayer2,自动化制作符合覆盖率测试要求的条件分支if,switch,for,while等的测试数据。可以将被测试函数中含有的条件式(if以及switch等)在数据制成图形(Viewer)上列表显示。点击其中的条件,工具将自动开始检索与之相关的变量,进而从所设置的条件的境界值中自动生成覆盖率测试所需要的数据。为了达到C1/MCDC覆盖率,测试时需要对各函数的数据进行组合。利用CasePlayer2提供的解析结果,分析条件式的net构造,在重复性限制在最小限度下生成C1/MCDC覆盖率测试用数据。支持MPU CoverageMaster winAMS Supported Processor List(English)动作环境・操作PC/OS・IBM PC/AT 兼容机・Pentium(相当) 2GHz 以上的CPU・存储器 512MB 以上(推荐值)・显示器分辨率 XGA(1024*768)以上(推荐值)・Windows XP, Windows Vista, Windows 7(32bit/64bit)(※Windows 95/98/Me/NT/2000 未支持)
-
前言我们都希望为我们的 Web 应用程序构建易维护的测试。作为这个目标的一部分,我们都希望能集中精力在测试本身,而尽量避免困在实施的具体细节中。从长远来看,测试应该是可维护的,对软件定期的变更并不会破坏测试本身或者让团队的开发节奏变慢。某些测试工具可以在做出更改和查看结果之间提供简短的反馈循环,但不能精确地模仿浏览器的行为。其他工具可能会使用实际的浏览器环境,但会降低迭代速度,并且在连续集成系统中可能会变得更加脆弱。1. Selenium知名的浏览器 web 应用测试框架,可以用 Java、C#、Ruby、JavaScript、R 和 Python 等多种编程语言编写测试案例。Selenium为每种语言提供客户端 API。Selenium WebDriver 尽可能使用原生操作系统级别的功能,而非基于浏览器 JavaScript 的命令来驱动浏览器。这样就绕过了原生功能和 JavaScript 命令之间由于细微差别而产生的问题(包括安全限制)。它提供了很大的灵活性,甚至还支持 iframe 和多个浏览器标签。卓越的跨浏览器功能令人印象深刻。可以在主流浏览器(Chrome、Firefox、Safari、Edge、Internet Explorer)上执行 Selenium 测试。Selenium Grid 可以与 WebDriver 一起使用,以在远程系统上执行测试。使用 Selenium 的唯一缺点是,它需要大量的技能,并且编写测试非常耗时。对没有编程经验的人来说,乍一看用 Selenium 编写测试似乎很容易;但是如果没有最佳实践,将导致项目内的测试自动化框架难以维护且不够稳定可靠。2. EndtestEndtest是智能自动化测试解决方案,它使用多个开源和闭源组件去简化创建和执行测试的流程。其中之一就是 Recorder 组件可以让用户不用编程技巧就能创建和执行测试。你可以用图形化界面编辑管理自己的测试案例,而不用编写任何代码。它和 Selenium 一样拥有灵活性,允许你自动化测试场景,其中包含 iframe、多个浏览器标签、文件上传、ShadowDOM, 等等。它同 Selenium 一样拥有跨浏览器的特性, 支持所有主流的浏览器(Chrome、Firefox、Safari、Edge、Internet Explorer)。同时,它也包括跨浏览器的云框架,支持 Windows、Mac 以及移动设备上的浏览器。此外,它还有支持 JavaScripts 执行的组件,以及发送 API 请求和连接数据库执行 SQL 语句的组件。这些组件可用于在测试中添加额外的验证步骤,并可准备或清理测试环境。3. WatirWatir是一个 Ruby 的浏览器自动化测试开源库。Watir 与对浏览器的互动方式和人类是一样的:如点击一个网页元素,填输入字符。它的底层使用了 Selenium 并且提供同样的灵活性,也支持跨浏览器。同时,它也支持 iframes 以及多个浏览器标签。Watir 最大的优点是 API 很容易使用,它在繁复的 Selenium API 之上增加了一层简单性。不过,它的主要缺点是,它不如 Selenium 受欢迎,在寻找答案和解决方案方面你会遇到一些困难。4. Puppeteer一个 Node 库,它提供了高级的 API 并通过 DevTools 协议来控制 Chrome(或 Chromium)。我认为未来它可以代替 Selenium。它也具有支持 iframe 和多个浏览器标签的灵活性。值得一提的是,它有 2 种不同的软件包:puppeteer-core 和 puppeteer唯一的区别是 puppeteer-core 在安装后不会自动下载 Chromium。puppeteer的主要缺点是缺乏跨浏览器功能,因为它仅适用于基于 Chromium 的浏览器。即使 Opera 和 Edge 迁移到 Chromium,也无法保证 Firefox 和 Safari 将来也会这样做。另一个缺点是,唯一受支持的语言是 Node.js。即使到 2020 年一切似乎都围绕 JS 展开,但是仍然有一些用户可能想使用其他语言进行自动化测试的开发。5. Playwright一个 Node 库,可通过单个 API 在 Chromium、Firefox 和 WebKit 浏览器上执行自动化测试。Playwright旨在不断增长的 Web 浏览器集上实现自动化操作。Playwright 类似于 Puppeteer。它支持多页面、多域名和 iframes 测试,还可以模拟移动端设备,地理指向和权限控制也是可以测试的。即使它具有更广泛的跨浏览器支持,但它也不支持 Internet Explorer。因为它是一个相对较新的库,所以你可能现在在线上找不到很多资源。如果你在编写 Node.js 代码方面有扎实的经验,那么 Playwright 可以一试。6. Sikuli在运行 Windows、Mac 或 Linux 的台式计算机屏幕上看到的任何内容,都可以使用 Sikuli 执行自动化测试。它使用由 OpenCV 支持的图像识别来识别视觉组件。如果无法轻松访问 GUI 内部或要操作的应用程序或网页的源代码,这个工具会非常方便。实际上,这是大多数现代 RPA 解决方案背后的技术。Sikuli的优点是,元素具有唯一属性或属性是否更改都无关紧要,因为 Sikuli 仅依赖于视觉识别。它的主要缺点是视觉容忍度让用户很难在不同的浏览器和屏幕尺寸之间实现自动化。并且,使用 Sikuli 库需要编程技巧,并且你可以在 Python、Ruby 和 Java 之间选择。如果你有涉及 Web 应用程序和桌面应用程序的混合自动化测试,则较好的做法是将 Selenium 用于 Web 组件,将 Sikuli 用于桌面组件。7. Micro Focus UFT (QTP)专有解决方案,以前称为 QuickTest Professional(QTP)。它提供了使 Web 应用程序和桌面应用程序自动化的功能。它使用 Visual Basic 脚本语言来定位应用程序中的元素并与之交互。同时,它还提供了一个 IDE,你只需在 GUI 中创建一个流程即可在不编写任何代码的情况下构建测试。该工具已经存在很长时间,并且确实使 Selenium 失去了很多市场份额。8. IBM Rational Functional Tester一个提供功能、回归、GUI 和数据驱动测试的自动化测试的专业工具。它确实包括有限的跨浏览器功能,因为它仅适用于 Chrome、Firefox 和 Internet Explorer。主要优点是它还可用于自动化桌面应用程序。优势之一是它具有 Eclipse Java Developer Toolkit 编辑器,这让你的团队可以轻松地使用 Eclipse 在 Java 中编写测试脚本。自带的 IDE 工具箱编辑器包含以下功能,如代码自动完成和高级调试选项。将IBM Rational Functional Tester与 CI/CD 系统集成可能会很困难,因为它被设计用在你自己的工作站上9. JestJest是一个 JavaScript 框架,允许你通过 jsdom 访问 DOM。值得一提的是,jsdom 只是浏览器工作方式的一个近似值,用于 React 应用程序的测试框架,但不是跨浏览器测试的可靠选择。Jest 确实提供了良好的迭代速度,并且具有强大的功能,例如模拟模块和计时器。理想情况下,开发人员应使用它来测试某些组件,但结果不能保证该应用程序在实际的浏览器中可以正常工作。10. CucumberCucumber是一个开源的行为驱动测试工具,支持多种编程语言,包括 Ruby,Java,Scala 和 Groovy。创建测试案例需要编程技术。实际功能可以通过使用 Gherkin 来调用。使用 Cucumber 的明显优势是,非技术用户可以轻松理解这些方案。可以说 Cucumber 并不是 Selenium 的替代品,而仅仅是对 Selenium 进行了一层包装。Selenium 和 Cucumber 的组合可提高代码的可读性,并使其更易于重用组件。
-
使用鼠标双击打开桌面应用程序,显示执行成功但是应用没有打开。换了点击图片也显示屏幕不匹配,请问怎么可以实现打开桌面应用呢
-
自2018年被评选为编程语言以来,Python在各大排行榜上一直都是名列前茅。目前,它在Tiobe指数中排名第三个,仅次于Java和C。随着该编程语言的广泛使用,基于Python的自动化测试框架也应运而生,且不断发展与丰富。因此,开发与测试人员在为手头的项目选择测试框架时,需要考虑许多方面的因素,其中包括:框架的脚本质量,测试用例的简单性,以及运行模块可能存在的技术弱点。为了避免出现“选择困难症”,我在此为大家准备了五种Python类型的自动化测试框架,以供比较和讨论。1.Robot Framework作为最重要的Python测试框架之一,Robot Framework主要被用在测试驱动(test-driven)类型的开发与验收中。虽然是由Python开发而来,但是它也可以在基于.Net的IronPython和基于Java的Jython上运行。同时,作为一个Python框架,Robot还能够兼容诸如Windows、MacOS、以及Linux等平台。使用先决条件在使用Robot Framework(RF)之前,您需要先安装Python 2.7.14及以上的版本。我推荐您使用Python 3.6.4,以确保适当的注释能够被添加到代码段中,并能够跟踪程序的更改。同时,您还需要安装Python包管理器--pip。当然,您也必须下载相应的开发框架,例如:在开发者圈子里比较流行的PyCharm社区版。另外,由于其代码段本身并不依赖于任何IDE,因此您完全可以沿用手头既有的IDE工具。优点通过使用关键字驱动测试(keyword-driven-test)的方法,它能够帮助测试人员轻松地创建具有可读性的测试用例,进而简化了整个自动化的过程。用户能够轻松地测试数据中的语法。因为是由各种通用工具和测试库所组成,所以它不但拥有庞大的生态系统,而且可以在单独的项目中使用其各个元素。由于拥有许多类型的API,因此该框架具有高度的可扩展性。虽然并非内置功能,但是Robot可以通过Selenium Grid(请参见https://www.lambdatest.com/blog/lambdatest-now-live-with-an-online-selenium-grid-for-automated-cross-browser-testing/),来帮助用户运行各种并行测试。缺点虽然有着上述各种便利,但是Robot Framework在创建自定义的HTML报告方面比较繁琐。您顶多能用它来生成xUnit格式的简短报告。另外,Robot Framework在并行测试方面也并不见长。Robot的特点与竞品比较由于Robot具有丰富的内置库,并能使用更为简单的面向测试的DSL(Domain Specific Language),因此如果您是自动化测试领域的新手,并且缺乏开发经验的话,那么将它作为Python测试框架要比下面将要提到的Pytest或Pyunit,更容易上手一些。当然,如果您需要开发复杂的自动化框架,那么还请使用Pytest、或其他类型的Python框架。2.Pytest适用于多种软件测试的Pytest,是另一个Python类型的自动化测试框架。凭借着其开源和易学的特点,该工具经常被QA(质量分析)团队、开发团队、个人团队、以及各种开源项目所使用。鉴于Pytest具有“断言重写(assert rewriting)”之类的实用功能,许多大型互联网应用,如Dropbox和Mozilla,都已经从下面将要提到的unittest(Pyunit)切换到了Pytest之上。使用先决条件除了基本的Python知识,用户并不需要更多的技术储备。另外,用户只需要有一台带有命令行界面的测试设备,并且安装好了Python包管理器、以及可用于开发的IDE工具。优点过去,开发人员必须将他们的测试包含在各种大型的类中。如今,Pytest可以让用户写出更为紧凑的测试套件。其他的测试工具会要求开发或测试人员使用调试器,或以日志检查的方式检测某个特定值的来源。而用户在用Pytest来编写测试用例时,完全可以将所有的值都存储在测试用例之中,直到再获悉有哪些值失败了、以及哪些值得到了断言。由于涉及到的样板代码(boilerplate code)并不多,因此用户能够容易地编写和理解各种测试。测试夹具(Fixture)函数常被用来向测试函数添加某个参数,并返回不同的值。在Pytest中,您可以通过使用一个夹具来模块化另外一个。同时,用户可以使用多个夹具,在无需重写测试用例的情况下,将测试覆盖到所有参数的组合。Pytest开发人员通过发布各种实用插件,来保持框架的可扩展性。例如:pytest-xdist可以在不使用其他测试器的情况下,被用于执行并行测试。同时,单元测试也可以在无需复制任何代码的情况下,实现参数化。通过为开发人员提供各种特殊的例程,它能够使得测试用例的编写更为简单、更不易出错,同时代码也会变得更短、更易被理解。缺点上述提及的特殊例程,也意味着用户必须放弃一定的兼容性。虽然方便了用户编写测试用例,但是这些用例却无法与任何其他的测试框架一起被使用。Pytest的特点与竞品比较就编写功能性测试用例和开发复杂的框架而言,Pytest胜过下面将要提到的UnitTest。不过,它和Robot Framework类似,仅适用于开发出简单的测试框架。如果您正在考虑使用Pytest,请进一步参考《使用Pytest和Selenium WebDriver实现测试自动化》。3.UnitTest/PyUnit受到了JUnit启发的UnitTest/PyUnit,也是一种标准化的针对单元测试的Python类自动化测试框架。它的基类TestCase提供了各种断言方法、以及所有清理和设置的例程。因此,TestCase子类中的每一种方法都是以“test”作为名词前缀,以标识它们能够被作为测试用例所运行。用户可以使用load方法和TestSuite类来分组、并加载各种测试。当然,您也可以通过联合使用,来构建自定义的测试运行器。正如我们使用Junit去测试Selenium那样,UnitTest也会用到UnitTest-sml-reporting、并能生成各种XML类型的报告。使用先决条件由于UnitTest默认使用了Python,因此我们并不需要什么先决条件。除了需要具备Python框架的基本知识,您也可以额外地安装pip、以及用于开发的IDE工具。优点开发人员并不需要安装任何其他的模块。UnitTest是xUnit的衍生产品,其工作原理与其他xUnit框架十分类似。因此对于那些没有过硬Python背景的人来说,也能很快地上手。用户能够以更为简单的方式运行单个测试用例。您只需在终端上预定好名称,该框架便可灵活地执行各种用例的测试,并产生精炼的输出。它能够在几毫秒内生成各种测试报告。缺点虽然该框架常用snake_case来命名各种Python代码,但是由于它源自Junit,因此仍保留了一些传统的camelCase命名方法。这往往会让人产生混淆。由于它过多地支持了抽象方法,因此造成了测试代码的目的有时不够清晰。 需要大量的样板代码。PyUnit的特点与竞品比较和部分Python开发人员的观点相似,我认为:Pytest能够培养测试人员以非常紧凑的方式编写出更好的自动化代码,这一编程习惯。尽管UnitTest是Python默认的自动化测试框架,但是其工作原理、及命名规则仍与标准的Python代码略有不同。同时,它也需要太多的样板代码。因此该框架并不太受欢迎。4.Behave我们都知道:行为驱动开发(behavior-driven development,BDD),是一种基于敏捷软件开发的方法。它能够鼓励开发人员、业务参与者和QA人员,三者之间的协作。作为另一种Python测试框架,Behave允许团队避开各种复杂的情况,去执行BDD测试。从本质上说,该框架与SpecFlow和Cucumber非常相似,常被用于执行自动化测试。用户可以通过简单易读的语言来编写测试用例,并能够在其执行期间粘贴到代码之中。而且,那些被设定的行为规范与步骤,也可以被重用到其他的测试方案中。使用先决条件任何具备Python基础知识的人都可以使用Behave。其他先决条件还包括:您必须先安装Python 2.7.14及以上的版本。需要通过Python包管理器或pip来与Behave协作。大多数开发人员会选择Pycharm作为开发环境,当然您也可以选用其他的IDE工具。优点由于系统行为使用了半正式(semi-formal)语言、以及域词汇表(domain vocabulary),因此Behave有助于在组织中保持一致性的行为。让那些工作在不同模块上的开发团队,通过协调处理来具有类似的特征。其构建的各个功能块能够执行各种测试用例。由于具有更多值得用户推理和思考的细节,因此目标产品会具有更好的规范性。根据类似的规范格式,它能够让项目经理和利益相关者,对开发团队和QA团队的输出具有更清楚地了解。缺点只适用于黑盒测试。Behave的特点与竞品比较Behave最适合于诸如简单Web测试之类的黑盒测试。但是,对于那些具有复杂场景的集成测试与单元测试而言,Behave并不是一个很好的选择。作为Behave的替代品,一些开发与测试人员会推荐使用pytest-bdd。该工具融合了Pytest的所有优点,并实现了各种行为驱动测试的场景。如果您正在考虑使用Behave,那么您可以借用《Behave with Selenium》(请参见https://www.lambdatest.com/support/docs/display/TD/Behave+with+Selenium+-+Running+Behave+Automation+Scripts+on+LambdaTest+Selenium+Grid)中提到的自动化脚本。5.LettuceLettuce是另一种基于Cucumber和Python的行为驱动类自动化工具。Lettuce主要专注于那些具有行为驱动开发特征的普通任务。它不但简单易用,而且能够使得整个测试过程更流畅、甚至更有趣。使用先决条件您需要安装带有IDE的Python 2.7.14、及以上的版本。当然,您也可以使用Pycharm或任何其他IDE工具。同时,您还需要安装Python包管理器。优点和其他BDD测试框架类似,Lettuce能够让开发人员创建多个场景,并用简单的自然语言去描述不同的功能。根据类似的规范格式,开发与QA团队能够协调共事。对于黑盒测试而言,Lettuce非常适合于那些行为驱动的测试用例。缺点为了成功地实现行为驱动测试,开发团队、QA人员以及利益相关者之间需要持续进行沟通。倘若缺乏此类沟通,则会产生流程模糊不清,并让团队遇到问题。 竞品比较在普通开发人员和自动化测试人员看来,Cucumber在执行BDD测试方面更为实用。而在Python开发和QA人员看来,Pytest-bdd才是的。Pytest的强大之处在于:其框架实现了紧凑且易于理解的代码,并能紧密地结合到行为驱动的测试之中。结语综上所述,在上述五种自动化测试的Python框架中,Pytest、Robot Framework和UnitTest可主要用于功能与单元测试,而Lettuce和Behave仅适用于行为驱动测试。通过进一步比较,我们认为:对于功能测试而言,Pytest是的。如果您是基于Python自动化测试的新手,那么Robot Framework是的入门工具。虽然其功能有所受限,但是它非常容易上手。对于基于Python的BDD测试而言,Lettuce和Behave同样优秀。不过,如果你已经有了一定的Pytest经验,那么请使用Pytest-bdd,希望本文能够帮助您选出合适的Python测试框架,并顺利开展测试工作。
推荐直播
-
华为云码道-玩转OpenClaw,在线养虾2026/03/11 周三 19:00-21:00
刘昱,华为云高级工程师/谈心,华为云技术专家/李海仑,上海圭卓智能科技有限公司CEO
OpenClaw 火爆开发者圈,华为云码道最新推出 Skill ——开发者只需输入一句口令,即可部署一个功能完整的「小龙虾」智能体。直播带你玩转华为云码道,玩转OpenClaw
回顾中 -
华为云码道-AI时代应用开发利器2026/03/18 周三 19:00-20:00
童得力,华为云开发者生态运营总监/姚圣伟,华为云HCDE开发者专家
本次直播由华为专家带你实战应用开发,看华为云码道(CodeArts)代码智能体如何在AI时代让你的创意应用快速落地。更有华为云HCDE开发者专家带你用码道玩转JiuwenClaw,让小艺成为你的AI助理。
回顾中 -
Skill 构建 × 智能创作:基于华为云码道的 AI 内容生产提效方案2026/03/25 周三 19:00-20:00
余伟,华为云软件研发工程师/万邵业(万少),华为云HCDE开发者专家
本次直播带来两大实战:华为云码道 Skill-Creator 手把手搭建专属知识库 Skill;如何用码道提效 OpenClaw 小说文本,打造从大纲到成稿的 AI 原创小说全链路。技术干货 + OPC创作思路,一次讲透!
回顾中
热门标签