selenium自动化测试用例需要关注的几点
自动化测试设计简介注:参看文章地址
我们在本章提供的信息,对自动化测试领域的新人和经验丰富的老手都是有用的。本篇中描述最常见的自动化测试类型, 还描述了可以增强您的自动化测试套件可维护性和扩展性的“设计模式”。还没有使用这些技术的、有经验的自动化测试工程师会对这些技术更加感兴趣。
测试类型
您应该测试应用程序中的哪些部分?这取决于您的项目的各种影响因素:用户的期望,时间期限,项目经理设置的优先事项等等。但是,一旦项目边界定义完成,作为测试工程师,你必须做出要测试什么的决定。
为了对Web应用的测试类型进行分类,我们在这里创建了一些术语。这些术语并不意味着标准,但是这些概念对web应用测试来说非常典型。
● 测试静态内容
静态内容测试是最简单的测试,用于验证静态的、不变化的UI元素的存在性。例如:
→ 每个页面都有其预期的页面标题?这可以用来验证链接指向一个预期的页面。
→ 应用程序的主页包含一个应该在页面顶部的图片吗?
→ 网站的每一个页面是否都包含一个页脚区域来显示公司的联系方式,隐私政策,以及商标信息?
→ 每一页的标题文本都使用的<h1>标签吗?每个页面有正确的头部文本内吗?
您可能需要或也可能不需要对页面内容进行自动化测试。如果您的网页内容是不易受到影响手工对内容进行测试就足够了。如果,例如您的应用文件的位置被移动,内容测试就非常有价值。
● 测试链接
Web站点的一个常见错误为的失效的链接或链接指向无效页。链接测试涉及点各个链接和验证预期的页面是否存在。如果静态链接不经常更改,手动测试就足够。但是,如果你的网页设计师经常改变链接,或者文件不时被重定向,链接测试应该实现自动化。
●功能测试
在您的应用程序中,需要测试应用的特定功能,需要一些类型的用户输入,并返回某种类型的结果。通常一个功能测试将涉及多个页面,一个基于表单的输入页面,其中包含若干输入字段、提交“和”取消“操作,以及一个或多个响应页面。用户输入可以通过文本输入域,复选框,下拉列表,或任何其他的浏览器所支持的输入。
功能测试通常是需要自动化测试的最复杂的测试类型,但也通常是最重要的。典型的测试是登录,注册网站账户,用户帐户操作,帐户设置变化,复杂的数据检索操作等等。功能测试通常对应着您的应用程序的描述应用特性或设计的使用场景。
● 测试动态元素
通常一个网页元素都有一个唯一的标识符,用于唯一地定位该网页中的元素。通常情况下,唯一标识符用HTML标记的’id’属性或’name’属性来实现。这些标识符可以是一个静态的,即不变的、字符串常量。它们也可以是动态生产值,在每个页面实例上都是变化的。例如,有些Web服务器可能在一个页面实例上命名所显示的文件为doc3861,并在其他页面实力上显示为doc6148,这取决于用户在检索的‘文档’。验证文件是否存在的测试脚本,可能无法找到不变的识别码来定位该文件。通常情况下,具有变化的标识符的动态元素存在于基于用户操作的结果页面上,然而,显然这取决于Web应用程序。
下面是一个例子。
<input /> |
这是一个HTML标记的复选框,
其ID (addForm:_ID74:_ID75:0:_ID79:0:checkBox) 是一个动态生成的值。这个页面下次被打开时,复选框的ID将可能是一个不同的值。
● Ajax的测试
Ajax是一种支持动态改变用户界面元素的技术。页面元素可以动态更改,但不需要浏览器重新载入页面,如动画,RSS源,其他实时数据更新等等。Ajax有不计其数的更新网页上的元素的方法。但是了解AJAX的最简单的方式,可以这样想,在Ajax驱动的应用程序中,数据可以从应用服务器检索,然后显示在页面上,而不需重新加载整个页面。只有一小部分的页面,或者只有元素本身被重新加载。
验证结果
● 断言assert与验证verify
什么时候使用断言命令,什么时候使用验证命令?这取决于你。差别在于在检查失败时,你想让测试程序做什么。你想让测试终止,还是想继续而只简单地记录检查失败?
这需要权衡。如果您使用的断言,测试将在检查失败时停止,并不运行任何后续的检查。有时候,也许是经常的,这是你想要的。如果测试失败,你会立刻知道测试没有通过。TestNG和JUnit等测试引擎提供在开发测试脚本时常用的插件,可以方便地标记那些测试为失败的测试。优点:你可以直截了当地看到检查是否通过。缺点:当检查失败,后续的检查不会被执行,无法收集那些检查的结果状态。
相比之下,验证命令将不会终止测试。如果您的测试只使用验证,可以得到保证是—假设没有意外的异常—测试会被执行完毕,而不管是否发现缺陷。缺点:你必须做更多的工作,以检查您的测试结果。也就是说,你不会从TestNG和JUnit得到反馈。您将需要在打印输出控制台或日志文件中查看结果。每次运行测试,你都需要花时间去查看结果输出。如果您运行的是数以百计的测试,每个都有它自己的日志,这将耗费时间。及时得到反馈会更合适,因此断言通常比验证更常使用。
● 权衡:assertTextPresent,assertElementPresent和assertText
您现在应该熟悉这些命令及使用它们的机制。如果没有,请参阅相关章节。在构建你的测试时,你需要决定
→ 只检查在页面上的文本吗?(verify/ assertTextPresent)
→ 只检查是否在页面上存在HTML元素吗?即文本,图像,或其他没被检查的内容,只要和HTML标记相关。(verify/ assertElementPresent)
→ 需要同时检查元素和它的文本内容?(verify/ assertText)
没有正确的答案。这取决于您的测试要求。如有疑问,请使用assertText,因为这是最严格的类型检查点。您可以随后更改它,但至少你不会遗漏任何潜在的故障。
Verify/ assertText是最特殊的测试类型。HTML元素(标签)或文本的不符合都会导致测试失败。也许你的网页设计师经常改变页面面,而你不希望在他们改变页面时,你的测试失败,因为这是期望中的周期性变更。但是,假如你仍然需要检查的页面上的东西,如段落、标题文本或图像。在这种情况下,您可以使用verify/ assertElementPresent。这将确保一个特定类型的元素存在(如果使用XPath,可以确保它相对页面内其他对象的存在)。但你不关心的内容是什么,你只关心某个特定的元素,比方说,一个图片在一个特定的位置。
随着时间的推移和经验的积累,如何决定使用还是非常简单的。
定位元素的策略
● 选择一个定位策略
有多种方式选择页面上的对象。但面对这些定位类型,如何权衡呢?回想一下,我们定位一个对象的方式:
→ 元素的ID
→ 元素的name属性
→ XPath语句
→ 通过一个链接的文本
→ 文档对象模型(DOM)
使用元素的ID或name定位符,在测试执行方面来说,是最有效的方式。也让你的测试代码更具可读性,如果在页面源代码中的ID或name属性被友好命名的话。XPath语句需要更长的时间来处理,因为浏览器必须运行它的XPath处理器。在Internet Explorer 7,XPath出了名的慢。
使用链接的文本进行定位是很方便的,并运行起来也不错。这种技术只适用于链接。另外,如果链接文本很可能会经常改变,使用<a>标签定位元素将是更好的选择。
不过,有时你必须使用XPath定位。如果一个页面元素没有一个ID或者name属性,除了XPath定位没得选择。(DOM定位器不再普遍使用,因为,XPath可以做得更好。DOM定位器只简单地为遗留测试而存在)。
相对使用ID或name属性定位,使用XPath进行定位有一个独特的优势。使用XPath(DOM)中,你可以找到页面上相对于其他对象的一个对象。例如,如果有一个链接必须存在<div>标签里的第二个段落内,您可以使用XPath进行定位。使用ID和name属性定位,你只能得出它们存在指定的页面,而不知具体的页面位置。如果你必须测试显示公司标志的图像出现在页面顶部的头部分,XPath定位可能是更好的选择。
● 定位动态元素
正如前面测试类型部分所述,动态元素的页面标识在不同的页面实例上市不同的。例如,
<a class="button" >View Archived Allocation Events</a> |
这个HTML锚标记定义了一个ID属性为“adminHomeForm”按钮。和大部分HTML标签相比,这是一个相当复杂的锚标记,但它仍然是一个静态标签。每次页面被浏览器加载时,HTML将保持不变。它的ID在所有的页面实例里保持不变,也就是说,页面被展示时,这个UI元素总是有同样的标识符。所以,点击此按钮的测试脚本(Selenium Server)如下所示:
selenium.click("adminHomeForm"); |
然而,你的应用程序,可能生成动态的HTML标识符。在不同的网页实例中,标识符发生改变。例如,一个动态的页面的HTML元素可能会是这个样子:
<input /> |
这是一个复选框,id和name属性都是addForm:_ID74:_ID75:0:_ID79:0:checkBox。在这种情况下,使用标准的定位,测试脚本应该是这样子的:
selenium.click("addForm:_ID74:_ID75:0:_ID79:0:checkBox"); |
对于动态生成的标识符,这种做法行不通。下一次页面加载时,标识符将是一个不同的值,执行上述脚本会遇到“element not found”错误。
要更正该问题,一个简单的解决办法是使用XPath定位替代ID定位器。因此,对于该复选框,可以简单地使用
selenium.click("//input"); |
或者,如果它不是在页面上的第一个文本输入域,尝试一个更详细的XPath语句。
selenium.click("//input[3]"); |
或
selenium.click("//div/p[2]/input[3]"); |
但是,如果你确实需要使用ID来定位元素,可以换一种不同的解决方案。您可以先捕捉到网站的这个ID,然后再使用它,例如:
String[] checkboxids = selenium.getAllFields(); // Collect all input IDs on page. for(String checkboxid:checkboxids) { if(checkboxid.contains("addForm")) { selenium.click(expectedText); } } |
如果页面上只有一个复选框的ID文本为“expectedText”时,这种方法工作。
● 定位Ajax元素
定位、验证AJAX元素的最好的方式是使用Selenium 2.0 webdriver的API,它专门解决Selenium 1.0测试AJAX元素的一些限制。
在Selenim 2.0中,可以使用waitfor()方法来等待一个页面元素变得可用。该参数是一个WebDriver用来实现定位的By对象。这是WebDriver的章节中详细解释。
在Selenium 1.0(Selenium-RC的)中,要做到这一点需要编写更多的编码,但它并不难。首先检查元素,如果它存在,等待预定义的时间段,然后再重新检查。这在循环内执行,如果超过一个预定的超时,元素不存在则终止循环。
让我们考虑页面上实现AJAX效果的一个链接(链接= ajaxLink),可以使用循环处理:
// Loop initialization. for (int second = 0;; second++) { // If loop is reached 60 seconds then break the loop. if (second >= 60) break; // Search for element "link=ajaxLink" and if available then break loop. try { if (selenium.isElementPresent("link=ajaxLink")) break; } catch (Exception e) {} // Pause for 1 second. Thread.sleep(1000); } |
这当然不是唯一的解决办法。Ajax是一个共同的话题,在用户论坛上,查找一下之前的讨论,看看别人是如何做的。
封装Selenium调用
与任何编程一样,你需要使用工具函数来处理在测试代码中重复的函数。避免重复的方法之一是封装常用的Selenium方法的调用。例如,测试时经常点击页面上的元素,等待页面加载。
selenium.click(elementLocator); selenium.waitForPageToLoad(waitPeriod); |
为了不重复上述代码,你可以写一个包装方法实现这两个功能。
/** * Clicks and Waits for page to load. * * param elementLocator * param waitPeriod */ public void clickAndWait(String elementLocator, String waitPeriod) { selenium.click(elementLocator); selenium.waitForPageToLoad(waitPeriod); } |
● 判断元素存在的“安全操作”
另一种常见的封装Selenium的方法,在执行进一步操作前检查页面上的元素存在性。这有时被称为“安全操作”。例如,下面的方法可用于实现一个依赖期望的元素存在的安全操作。
/** * Selenum-RC -- Clicks on element only if it is available on page. * * param elementLocator */ public void safeClick(String elementLocator) { if(selenium.isElementPresent(elementLocator)) { selenium.click(elementLocator); } else { // Using the TestNG API for logging Reporter.log("Element: " +elementLocator+ ", is not available on page - " +selenium.getLocation()); } } |
上述例子使用的是Selenium 1.0 API,Selenium 2.0同样支持安全操作。
/** * Selenium-WebDriver -- Clicks on element only if it is available on page. * * param elementLocator */ public void safeClick(String elementLocator) { WebElement webElement = getDriver().findElement(By.XXXX(elementLocator)); if(webElement != null) { selenium.click(elementLocator); } else { // Using the TestNG API for logging Reporter.log("Element: " +elementLocator+ ", is not available on page - " + getDriver().getUrl()); } } |
在第二个例子中,’XXXX’方法是一个占位符,可以用元素定位方法进行替换。
使用安全方法取决于测试开发人员的决定。因此,如果测试需要继续执行,即使知道页面上一些元素没有发现,这时可以使用安全方法,并发送一条缺少元素的消息到日志文件。这基本上等于实现了带报告机制的验证,而不是一个失败就终止执行的断言。但是,如果元素必须在页面上出现,以便能够执行进一步的操作(如一个门户网站主页上的登录按钮),这时安全方法技术不应该被使用。
最后:下方这份完整的软件测试视频学习教程已经整理上传完成,朋友们如果需要可以自行免费领取 【保证100%免费】
相关文章:

selenium自动化测试用例需要关注的几点
自动化测试设计简介注:参看文章地址 我们在本章提供的信息,对自动化测试领域的新人和经验丰富的老手都是有用的。本篇中描述最常见的自动化测试类型, 还描述了可以增强您的自动化测试套件可维护性和扩展性的“设计模式”。还没有使用这些技术…...

harfbuzz 的用法
hb-blob: HarfBuzz Manual harfbuzz 的用法 HarfBuzz 整形 API 的核心是函数。此函数采用一种字体,即 包含一串 Unicode 代码点的缓冲区和 (可选)字体功能列表作为其输入。它取代了 缓冲区中的代码点,其中包含来自 字…...

JSP 在线学习管理系统myeclipse定制开发sqlserver数据库网页模式java编程jdbc
一、源码特点 JSP 在线学习管理系统是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为SQLServer2008&#x…...

Python学习笔记——PIL库(Pillow库)总结
一、图像数据的格式 ①jpg 支持高级别的压缩,利用部分损耗,使图片变小,方便网络传播。 ②png 无损压缩格式,比jpg略大,较好的保存图片画质,支持透明效果。 ③gif 动图效果,多帧图像组合到…...

C. Build Permutation【整数理论、构造、思维】
链接 理论基础 结论:在区间[n,2n]上,至少存在一个完全平方数。结论:在区间[n,2n]上,至少存在一个完全平方数。结论:在区间[n,2n]上,至少存在一个完全平方数。 构造⌈n⌉2构造\lceil \sqrt{n}\rceil^2构造⌈…...

关于ETL的两种架构(ETL架构和ELT架构)
ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数据从来源端经过抽取(extract)、转换(transform)、加载(load)至目的端的过程。ETL一词较常用在数据仓库,但其对象…...

android系统目录
环境:android studio引入android系统源码android和ubuntu策略路由的差异android源码编译问题(单编)repo(android源码)命令使用和注意事项wifi:wifi的加密类型梳理android11 wifisetting 流程跟踪android wifi热点settingandroid n…...

【C/C++】中【typedef】用法大全
总结一下typedef用法,一共七种,分别是:为基本数据类型起别名、为结构体起别名、为指针类型起别名、为数组类型起别名、为枚举类型起别名、为模版函数起别名。 目录 一、为基本数据类型起别名 二、为结构体起别名 三、为指针类型起别名 四…...

超实用的公众号运营攻略分享,纯干货
很多小伙伴抱怨,公众号运营真的越来越难做了! 每天会因为少得可怜的阅读量发愁,每天会因为纠结写什么选题发愁,每天更会因为公众号没有什么起色而感到无力。 现阶段公众号运营趋于饱和状态,公众号创建门槛低…...

编写NodeJs脚本实现接口请求
要编写运行脚本,需要先搭建开发环境 环境搭建 nodeJs脚本运行,当然需要先安装nodejs环境 官方地址在这里: nodejs官网 打开官网地址,可以看到下面一句话: Node.js is an open-source, cross-platform JavaScript runtime environment. 在打开的页面,可以直接下载最新的…...

【无人机】回波状态网络(ESN)在固定翼无人机非线性控制中的应用(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

YAML 文件简介
简介 我们在安装 kubernetes 集群的时候使用了一些 YAML 文件来创建相关的资源,但是对 YAML 文件还是非常陌生。所以我们先来简单看一看 YAML 文件是如何工作的,并使用 YAML 文件来定义一个 kubernetes pod,然后再来定义一个 kubernetes dep…...

Python四大主题之一【 Web】 编程框架
目前Python的网络编程框架已经多达几十个,逐个学习它们显然不现实。但这些框架在系统架构和运行环境中有很多共通之处,本文带领读者学习基于Python网络框架开发的常用知识,及目前的4种主流Python网络框架:Django、Tornado、Flask、Twisted。 …...

【C++】哈希表
1. unordered系列关联式容器 在C98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到 ,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好的查询是,进行…...

深度学习入门(六十七)循环神经网络——注意力机制
深度学习入门(六十七)循环神经网络——注意力机制前言循环神经网络——注意力机制课件心理学注意力机制注意力机制是显式地考虑随意线索非参注意力池化层Nadaraya-Watson 核回归:总结教材(注意力提示)1 生物学中的注意…...

阿里云云通信风控系统的架构与实践
作者:铭杰 阿里云云通信创立于 2017 年,历经 5 年发展已经孵化出智能消息、智能语音、隐私号、号码百科等多个热门产品。目前,已成为了国内云通信市场的领头羊,在国际市场上服务范围也覆盖了 200 多个国家。随着业务的不断壮大&am…...

【性能测试】loadrunner(一)知识准备
【性能测试】loadrunner(一)知识准备 目录:导读 1.0. 前言 1.1 性能测试术语介绍 1.2 性能测试分类 1.3 HTTP我们需要知道的 1.4 Loadrunner 12.55安装 1.0. 前言 在性能测试中,牵扯到了许多比较杂的知识点,…...

【Vue3源码】第五章 ref的原理 实现ref
【Vue3源码】第五章 ref的原理 实现ref 上一章节我们实现了reactive 和 readonly 嵌套对象转换功能,以及shallowReadonly 和isProxy几个简单的API。 这一章我们开始实现 ref 及其它配套的isRef、unRef 和 proxyRefs 1、实现ref 接受一个内部值,返回一…...

[Flink]部署模式(看pdf上的放上面)
运行一个wordcountval dataStream: DataStream[String] environment.socketTextStream("hadoop1", 7777) //流式数据不能进行groupBy,流式数据要来一条处理一次.0表示第一个元素,1表示第二个元素 //keyBy(0)根据第一个元素进行分组 val out: DataStream[(String, In…...

Linux 查看 CPU 信息,机器型号,内存等信息
平时用的可能少,但需要记住,使用的命令,转载https://my.oschina.net/hunterli/blog/140783,以记录学习 系统 # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/…...

三维量子力学 量子力学(3)
动量ppp有三个分量,为pxp_xpx等。它们分别满足与位置坐标的对易关系,比如px−iℏ∂∂xp_x-i\hbar\frac{\partial }{\partial x}px−iℏ∂x∂。可以用位置坐标梯度算符表示即p−iℏ∇\bm{p}-i\hbar\nablap−iℏ∇。位置矢量用r\bm{r}r表示。 在d3r…...

Blazor入门100天 : 身份验证和授权 (6) - 使用 FreeSql orm 管理ids数据
目录 建立默认带身份验证 Blazor 程序角色/组件/特性/过程逻辑DB 改 Sqlite将自定义字段添加到用户表脚手架拉取IDS文件,本地化资源freesql 生成实体类,freesql 管理ids数据表初始化 Roles,freesql 外键 > 导航属性完善 freesql 和 bb 特性 本节源码 https://github.com/…...

Java文件IO操作:File类的相关内容
Java文件IO操作一、File类1.相对路径和绝对路径2.路径分隔符(同一路径下、多个路径下)3.实例化4.常见方法一、File类 File类继承自Object类,实现了Serializable接口和Comparable接口; File类属于java.io包; File类是文…...

竣达技术 | 巡检触摸屏配合电池柜,电池安全放首位!
机房蓄电池常见的故障 1.机房电池着火和爆炸 目前在数据机房蓄电池爆炸着火事故频发,导致业主损失严重。一般机房电池是由于其中一节电池裂化后未妥善管理,电池急剧恶化导致爆炸着火。由于电池是串联及并联在使用,只要一节着火燃烧整片瞬间…...

什么是自动化运维?为什么选择Python做自动化运维?
“Python自动化运维”这个词,想必大家都听说过,但是很多人对它并不了解,也不知道是做什么的,那么你对Python自动化运维了解多少呢?跟着蛋糕往下看。 什么是Python自动化运维? 随着技术的进步、业务需求的快速增长,…...

【经验】移植环境requirement时报错
问题描述 在使用pip freeze > ./requirements.txt和pip install -r requirement.txt (requirements.txt文件用来记录当前程序的所有依赖包及其精确版本号)从一台电脑移植到另一台电脑的 conda 环境时,出现了一堆类似的报错: E…...

计算机专业要考什么证书?
大家好,我是良许。 从去年 12 月开始,我已经在视频号、抖音等主流视频平台上连续更新视频到现在,并得到了不错的评价。 视频 100% 原创录制,绝非垃圾搬运号,每个视频都花了很多时间精力用心制作,欢迎大家…...

一个列表引发的思考(简单版)
最近老板让我按照设计图写一个页面,不嫌丢人的说这是我第一次写页面,哈哈哈。 然后设计图里有一个这样的需求,感觉挺有意思的。 为什么感觉有意思呢,因为这个列表它前面是图片,然后单行和双行的不一样。(请…...

Protobuf 学习简记(三)Unity C#中的序列化与反序列化
Protobuf 学习简记(三)Unity C#中的序列化与反序列化对文本的序列化与反序列化内存二进制流的序列化与反序列化方法一方法二参考链接对文本的序列化与反序列化 private void Text() {TestMsg1 myTestMsg new TestMsg1();myTestMsg.TestInt32 1;myTest…...
Flask入门(10):Flask使用SQLAlchemy
目录11.SQLAlchemy11.1 简介11.2 安装11.3 基本使用11.4 连接11.5 数据类型11.6 执行原生sql11.7 插入数据11. 8 删改操作11.9 查询11.SQLAlchemy 11.1 简介 SQLAlchemy的是Python的SQL工具包和对象关系映射,给应用程序开发者提供SQL的强大功能和灵活性。它提供了…...