翻译验证性测试中定位 Web 元素遇到的挑战
翻译验证性测试是全球化测试中的一部分,旨在验证软件用户界面中需要翻译的字符串是否已经正确翻译。为了提高效率,目前一般采用先由熟悉产品的测试支持工程师书写测试用例,再由熟悉各国语言的测试人员执行用例或者先由测试支持工程师将复杂用例的执行结果在各个语言环境下截图,然后再发送给测试人员进行验证两种模式。目前随着持续交付模式的出现,无论是测试人员多语言环境下重复执行用例还是测试支持工程师多语言环境下手动截图都难以满足持续交付对速度的要求,因此测试支持工程师编写自动化脚本完成多语言环境下的自动截图就变成了提高效率的必然选择。
在传统的 Web 自动化测试应用场景中,由于程序编码的不规范,元素通常很难直接通过静态 ID 或 name 定位,幸好有 CSS 选择器和 XPath 定位为我们提供了新的可能。然而由于 DHTML 和 Ajax 的盛行,新的挑战又摆在了测试人员面前,由 Dojo 等客户端脚本生成的 DOM 结构异常复杂:层次繁多且一个 DOM 树上可能存在多个页面的 DOM 子节点,而且其中元素的 ID 是动态的(该 ID 一般由一个前缀和一个动态的数字组成,前缀表明了元素对应的部件类型,数字则由运行时该小部件在 DOM 树上的位置确定)。这导致了有些元素甚至需要依靠 CSS 伪类再运用组合选择器才能精确定位的到。而对于在翻译验证性测试中的自动化,这种问题尤其突出,由于翻译验证性测试中的自动化脚本“一次编写,多个语言环境下”运行的要求,元素定位的最后“救命稻草”-CSS 伪类中的内文本匹配也无法开箱即用了。
下面笔者将通过实例详细阐述元素定位的方法,以期读者能灵活运用以应对上述的各种挑战。
Selenium IDE 与 WebDriver 定位元素概览
Selenium 是一款强大的浏览器自动化工具,利用它可以实现 Web 界面测试的自动化。根据实现原理和使用方式的不同,其又分为 Selenium IDE 和 WebDriver,前者以浏览器插件的方式赋予用户简单快速地创建自动化脚本的能力,后者则通过 API 库的形式向用户提供更加灵活和健壮的 Web 自动化能力。
Selenium IDE 在其命令中采用 locatorType=location 的格式进行定位,该方法将定位到条件匹配的第一个元素,一般情况下 locatorType 可以省略;WebDriver 利用 findElement(By.locatorType("value") 或 findElements(By.locatorType("value") 函数查找元素,前者将返回一个唯一的元素,后者将返回一个元素列表。具体的定位由 By.locatorType("value") 实现。
除去定位使用的方法而言,二者本质上都是通过 locatorType 进行定位的,常用的 locatorType 包括 id,name,link text,dom/JavaScript,xpath,css 等,示例见清单 2(行末括号中的数字显示当前行定位器将定位到清单 1 HTML 文档中的第几行元素):
清单 1. HTML 示例 1(01) (02) (03) (09)清单 2. Selenium 和 WebDriver 中通用的定位方式Are you sure you want to do this?
(10) Continue (11) Cancel (12) (13)
//by IDid=loginForm(03)//in IDEWebElement element = driver.findElement(By.id("loginForm"));(03)//in WebDriver//by Namename=continue type=button(07)//in IDEWebElement element = driver.findElement(By.name("loginForm"));(03)//in WebDriver//by link textlink=Continue(10)//in IDEWebElement element = driver.findElement(By.linkText("Continue"));(10)//in WebDriver//by DOM or JavaScriptdom=document.forms[0].elements['username'](04)//use DOM in IDEWebElement element = (WebElement) ((JavascriptExecutor)driver). executeScript("return $('.required')[0]"); (04)//use JQuery in WebDriver //by XPath//form[@id='loginForm']/input[1](04)//by IDEWebElement element = driver.findElement(By.xpath("//input[@name='username']"));(04)//by WebDriver//by CSScss=#loginForm input[type="password"](05)//by IDEWebElement e = driver.findElement(By.cssSelector("input.passfield")(05)//by WebDriver
通过 ID 和 name 定位是最高效也是首选的定位方式,不过由于 name 不一定唯一,在定位时匹配条件的元素可能有多个,因此这种情况下只会定位到匹配条件的第一个元素。针对多个元素具有相同 name(或链接文本)属性的情况还需额外增加其他的过滤器才能进行精确定位,如清单 2 中 IDE 利用 name 进行定位的示例。
DOM 代表了整个 HTML 文档的结构,使用 JavaScript 可以访问 DOM 中的节点。Selenium IDE 基于 DOM 结构可以使用 JavaScript 的点操作符进行层次定位以简化定位操作,由于只有 DOM 定位器以“document”开头,因此“dom=”也可以省略;此外在 WebDriver 中甚至可以通过执行任意的返回值为 DOM 对象的 JavaScript 语句来查找元素,如清单 2 中 WebDriver 使用 JQuery(一种 JavaScript 框架)的元素查找函数$进行定位。
XPath 最初是用来在 XML 文档中定位 DOM 节点的语言,由于 HTML 也可以算作 XML 的一种实现,所以 Selenium 也可以利用 XPath 这一强大的语言来定位 Web 元素。XPath 在传统属性定位之外扩展了诸如“定位第三个多选框”等定位能力,以便应对没有 ID 或 name 属性的情况。利用 Xpath 可以通过绝对路径,或者相对于一个可精确定位的元素的相对路径来定位。为了保证定位的健壮性,推荐使用相对路径和基于位置关系的定位。同样由于只有 XPath 定位器以“//”开头,所以“xpath=”也可以省略。
CSS (Cascading Style Sheets) 是一种用于渲染 HTML 或者 XML 文档的语言,CSS 利用其选择器可以将样式属性绑定到文档中的指定元素,即前端开发人员可以利用 CSS 设定页面上每一个元素的样式。所以理论上说无论一个元素定位有多复杂,既然开发人员能够定位到并设置样式,那么测试人员同样应该也能定位继而操作该元素。这也正是 Selenium 官方极力推荐使用 CSS 定位,而不是 XPath 定位的主要原因。CSS 定位被推崇的另一个原因是不同的浏览器 XPath 引擎不同甚至没有自己的 Xpath 引擎,这就导致了 XPath 定位速度较慢,而采用 CSS 定位往往能用更简洁的语法快速定位到复杂的元素。因此后文将详细介绍 CSS 定位器的使用方法。
除了以上通用的定位方式之外,在 Selenium IDE 中还可通过 identifier 进行定位,这是最通用也是默认的定位方式,其定位时首先将 identifier 的值视为 ID 继而查找匹配元素,没有匹配项之后再把其看作 name 进行查找,直到找到第一个匹配的元素为止。由于其是默认的定位方式,因此“identifier=”通常也会省略。对于 WebDriver 而言,特有的定位方式更多。首先它可以通过链接文本进行部分匹配,如清单 3 所示;然后它还可以通过标签名或者 CSS 类名的方式进行定位,利用 findElement 的话这两种方式均是定位到第一个匹配条件的元素,利用 findElements 则可获得一个所有满足条件的元素列表,如清单 3 所示。
清单 3. WebDriver 特有的定位方式//by Partial Link TextWebElement element = driver.findElement(By.partialLinkText("Con")); (10)//in WebDriver//by Tag NameWebElement element = driver.findElement(By.tagName("p")); (09)/in WebDriver//by ClassList WEs = driver.findElements(By.className("required"));(4&5)//in WebDriver
CSS 选择器
CSS 选择器是由关系符分开的一个或多个简单选择器序列组成的选择器序列链,最后一个简单选择器序列的后面还可以添加一个伪元素。简单选择器序列是单纯由简单选择器组成的选择器链,它通常由一个标签选择器或者通配符选择器开头,之后序列中不允许再出现其他标签选择器和通配符选择器。简单选择器可以是 ID 选择器、类选择器、类型(标签)选择器、通配符选择器、属性选择器和伪类选择器。关系符可以是空格、大于号、加号和波浪符。关系符和简单选择器周围允许出现空白(空格符、tab 符、换行符、回车符、换页符)。多个 CSS 选择器还可以用逗号拼接为一个组合选择器,满足任意其中一个选择器的元素都会被该组合选择器选中,逗号的前后允许出现空白。某些选择器支持命名空间前缀,命名空间前缀的声明机制应该由使用选择器的语言指定,如果使用选择器的语言没有指定命名空间前缀声明机制,那么就没有前缀声明。在 CSS 中,命名空间通过 @namespace 规则声明。
清单 4. HTML 示例 2(01) (02) (03) (08)Are you sure you want to do this?
(09) Continue (10) Cancel (11)(12) (13) Cat (14) Dog (15)
fish
(16) Car (17) Goat (18) (19)查看更多关于全球化测试中利用Selenium定位Web元素难点解析_html/css_WEB-ITnose的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did111869