-
目录一、一个“附近”引发的面试翻车现场二、本质变化:意图识别从关键词匹配走向语义依存三、核心机制拆解:多槽位提取的工程架构四、典型案例 / 对比:规则匹配 vs 序列标注 vs 依存分析五、工程落地启示:你的测试用例需要补什么六、趋势判断:槽位间的逻辑关系会成为新门槛一、一个“附近”引发的面试翻车现场去年美团招NLP算法测试工程师,我到第三面,面试官给了一道真实线上case。用户原话:“帮我找附近的便宜餐厅”。我的意图识别模型输出:意图=找餐厅,槽位={价格=便宜}。没有“附近”。面试官没直接说错,而是反问:用户明确说了“附近”,你的模型为什么没提取?如果这个请求打到美团App,你觉得应该返回方圆三公里的店,还是全城的店?我下意识解释:训练数据里“便宜”出现频率高,“附近”可能被当成语气词或未标注…他打断我:别解释原因。告诉我,你打算怎么设计测试用例,确保这类问题在上线前被拦住?我哑口无言。因为我知道,我平时测意图识别,用的都是单槽位用例——“便宜餐厅”“附近的咖啡厅”“带我去火车站”。我从来没测过“附近+便宜”这种复合约束。这不是我一个人的问题。很多做对话系统和搜索测试的朋友,今天还在用“关键词命中率”和“准确率”评估模型。用户说“不辣的川菜”,模型只提取了“川菜”;说“适合约会的安静酒吧”,只提取了“酒吧”。这类错误在线上比比皆是,但测试报告里从来不体现。面试最后,面试官说了一段话我记到现在:意图识别的下一场竞争,不再是准不准,而是全不全。用户同时提两个约束,你漏一个,体验就崩了。二、本质变化:意图识别从关键词匹配走向语义依存五年前做意图识别,核心任务是分类——用户说的是“查天气”还是“订机票”。槽位提取是辅助,用个CRF或者BERT序列标注,能抽到实体就算赢。今年风向彻底变了。大模型普及后,意图分类的准确率在很多场景下已经超过95%。大家发现用户真正的痛点不是“模型认错意图”,而是“模型漏了约束”。本质上是用户表达习惯在升级。早期语音助手只能接受“天气 北京”,用户会主动简化。现在用户已经习惯用自然语言一口气说多个条件:“帮我找海淀区评分4.5以上、人均100以下、有停车位、还不用排队的火锅店”。这种句子里的槽位不是扁平列表,它们之间有逻辑关系:“附近”和“便宜”是并列约束,必须同时满足“海淀区”是“附近”的具体化,可能互相冲突“不用排队”隐含时间敏感,优先级更高传统的序列标注模型把句子当词串,抽取出一个个实体标签,但不知道这些标签之间是“且”还是“或”,也不知道哪个是主约束哪个是修饰。所以面试官问“为什么没提取‘附近’”,本质是在问:你的模型有没有能力理解“附近”和“便宜”是同一个槽位类别(餐厅属性)下的两个并列约束?你的测试体系有没有覆盖多约束组合的case?三、核心机制拆解:多槽位提取的工程架构一个能处理“附近+便宜”这类复合约束的意图识别系统,需要从三层重构。用这张图来说明:第一层:意图分类(略,不是本文重点)第二层:槽位提取的进阶要求传统做法是序列标注,给每个词打标签(B-price, I-price, B-distance, I-distance)。但对于“附近”这类词,它不是具体数值,而是一个相对范围。工程上需要做两件事:实体标准化:“附近”映射成“radius=3km”(城市POI密度中位数),“便宜”映射成“price_range=0-80元”边界识别:确保“附近”修饰的是“餐厅”还是整个动作“找”。看依存关系——“附近”通常附着在地理名词或直接作状语。第三层:槽位关系解析(核心难点)这一步决定了最终查询是“AND”还是“OR”。实现方式有三种:方式一:规则模板。预定义常见组合模式,例如“A的B”中A修饰B,“又A又B”中A和B并列。优点是可控,缺点是泛化差。方式二:轻量依存解析。用一个小型BERT判别两个槽位之间的语义关系。输入[CLS]槽位A [SEP]槽位B [SEP]原句,输出关系类别(并列/修饰/冲突/无关系)。我们内部测试准确率能做到87%。方式三:大模型直接生成结构化输出(GPT-3.5/4级别)。给定prompt,要求输出JSON,key为槽位类型,value为值,并增加relation字段列出约束组合逻辑。优点是准确率高,缺点是延迟和成本。生产环境的成熟方案是方式二+方式三结合:离线用大模型生成高质量训练数据,在线用小模型推理。有了关系解析层,系统才能输出类似这样的结构:{ "intent": "search_restaurant", "slots": [ {"type": "distance", "value": "nearby", "normalized": "radius_3km"}, {"type": "price", "value": "cheap", "normalized": "0-80"} ], "constraints": { "operator": "AND", "relations": [["distance", "price"]] }}面试官期待的答案,就是你能讲清楚这一层怎么设计和测试。 四、典型案例 / 对比:规则匹配 vs 序列标注 vs 依存解析拿三句真实用户请求,横向对比三种方案。Case 1:“找附近便宜的餐厅”Case 2:“找便宜餐厅,要附近的”Case 3:“找餐厅,便宜的和附近的都行”方案A:基于规则的关键词匹配。预定义词表{便宜, 附近, 餐厅}三个case的输出完全一样:{价格=便宜, 距离=附近, 品类=餐厅}问题:case3的语义是“便宜或附近”(二选一),但规则引擎输出成了“且”,会漏召回。方案B:BERT序列标注(无关系层)。标注结果:case1和case2都能正确标出所有实体,但不知道约束关系,默认全部“且”case3同样出错,因为它无法区分“和…都行”表示的是OR方案C:序列标注+依存解析(本文第三层)。依存分析识别出case3中“便宜的和附近的”通过“都行”连接,关系为“OR”输出约束改为OR,查询逻辑正确对case1和case2,依存分析能发现“附近”和“便宜”共同修饰“餐厅”,关系为AND这个对比说明:单纯把实体抽全只是第一步。没搞清楚关系的抽取,等于没抽。美团内部的一个A/B测试显示,加上依存关系层后,多约束请求的满意度(用户点击率)提升了19%,因为系统不再输出一堆矛盾的结果。五、工程落地启示:你的测试用例需要补什么如果你是测试工程师或者算法工程师,以下三个方向立刻可以动手。第一,构建“多槽位+关系”的测试集。 不要只写“价格=便宜”的单槽用例。写50条组合用例,覆盖以下关系类型:并列且(and):舒服且便宜的酒店并列或(or):川菜或者粤菜修饰(attribute):海淀附近的咖啡馆冲突(conflict):便宜的米其林(模型应该识别为不可能,走澄清流程)每条用例标注期望的约束逻辑(AND/OR/优先级)。跑你的模型看准确率。很多号称95%准确率的系统,在这个测试集上会掉到70%以下。第二,增加“槽位关系断言”到自动化测试。 传统测试只断言slots列表是否包含某实体。升级后,添加断言约束逻辑。例如:assert model.constraints.operator == "AND"assert model.constraints.relations == [["price","distance"]]这样就能拦截case3那种“都行”被误判为AND的回归。第三,用线上日志挖掘“漏召”模式。 定期抽样用户请求,对比模型输出的槽位和用户真实点击/后续对话。如果用户说“找附近便宜的餐厅”,模型只出了便宜,但用户最后点击了三公里内的店,说明他补了距离约束。这类样本应该回流训练。我在一家OTA公司做咨询时,他们的意图识别漏召率高达22%,大部分是复合约束。加了上述三个动作,漏召率降到9%,且没有增加人工标注成本——用的是用户行为隐式反馈。六、趋势判断:槽位间的关系理解会成为意图识别的标配大模型的出现,让单槽位提取变得廉价。随便一个BERT微调就能做到90+% F1。但关系理解依然棘手,因为它需要逻辑推理,而不是模式匹配。未来两年会看到两个变化:一是测试标准升级。技术面试和内部考评会越来越多地出现类似“用户说X和Y,你的系统怎么处理关系”的问题。只会序列标注的简历会越来越难通过。二是工程上会形成“小模型+轻量关系模块”的标配。大模型太贵太慢,不适合线上实时推理。但可以用大模型离线生成关系标注数据,训练一个小的关系分类器(参数量<100M)。我们团队用GPT-4生成了2万条复合约束样本,训练了一个DistilBERT,在线延迟仅3ms,关系分类准确率85%。对三类读者的建议:在校生:做意图识别项目时,别只满足于跑通ATIS数据集。自己手写20条含“和/或/但/不要”的复合约束用例,尝试用spaCy的依存解析或小模型做关系分类。能讲清楚这个,面试官会刮目相看。初级工程师:拿你现在的对话系统或搜索接口,跑一遍多约束测试集。记录漏召和关系误判。把这个分析写成技术笔记,附上改进方案。这是晋升答辩里的硬通货。中高级工程师:思考测试体系的升级。传统QA只验证“模型输出了什么”,未来需要验证“模型没输出什么”。设计端到端的约束覆盖度指标,比如“用户约束满足率”。这比单纯看准确率更能反映体验。最后问一个你可以立刻去验证的问题:你的意图识别系统,能正确区分“便宜的日本料理和意大利餐厅”与“日本料理和便宜的意大利餐厅”的约束范围吗?拿这两句话去测一下。答案会让你吃惊。
-
用了一周了,一天比一天卡啊,提个问题有时候要等10多分钟,怎么办呀?是用的人太多了,还是不够智能要算的太多了,赶紧加快速度呀!!!
-
最近 **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 的组合可提高代码的可读性,并使其更易于重用组件。
-
使用鼠标双击打开桌面应用程序,显示执行成功但是应用没有打开。换了点击图片也显示屏幕不匹配,请问怎么可以实现打开桌面应用呢
推荐直播
-
Skill 构建 × 智能创作:基于华为云码道的 AI 内容生产提效方案2026/03/25 周三 19:00-20:00
余伟,华为云软件研发工程师/万邵业(万少),华为云HCDE开发者专家
本次直播带来两大实战:华为云码道 Skill-Creator 手把手搭建专属知识库 Skill;如何用码道提效 OpenClaw 小说文本,打造从大纲到成稿的 AI 原创小说全链路。技术干货 + OPC创作思路,一次讲透!
回顾中 -
码道新技能,AI 新生产力——从自动视频生成到开源项目解析2026/04/08 周三 19:00-21:00
童得力-华为云开发者生态运营总监/何文强-无人机企业AI提效负责人
本次华为云码道 Skill 实战活动,聚焦两大 AI 开发场景:通过实战教学,带你打造 AI 编程自动生成视频 Skill,并实现对 GitHub 热门开源项目的智能知识抽取,手把手掌握 Skill 开发全流程,用 AI 提升研发效率与内容生产力。
回顾中 -
华为云码道:零代码股票智能决策平台全功能实战2026/04/18 周六 10:00-12:00
秦拳德-中软国际教育卓越研究院研究员、华为云金牌讲师、云原生技术专家
利用Tushare接口获取实时行情数据,采用Transformer算法进行时序预测与涨跌分析,并集成DeepSeek API提供智能解读。同时,项目深度结合华为云CodeArts(码道)的代码智能体能力,实现代码一键推送至云端代码仓库,建立起高效、可协作的团队开发新范式。开发者可快速上手,从零打造功能完整的个股筛选、智能分析与风险管控产品。
回顾中
热门标签