Selenium自动化测试用例设计注意事项.docx
- 文档编号:2319270
- 上传时间:2023-05-03
- 格式:DOCX
- 页数:15
- 大小:27.88KB
Selenium自动化测试用例设计注意事项.docx
《Selenium自动化测试用例设计注意事项.docx》由会员分享,可在线阅读,更多相关《Selenium自动化测试用例设计注意事项.docx(15页珍藏版)》请在冰点文库上搜索。
Selenium自动化测试用例设计注意事项
Selenium自动化测试用例设计注意事项
来源:
51Testing发布于2013-4-11
1032次浏览 评价:
好 中 差
自动化测试设计简介
我们在本章提供的信息,对自动化测试领域的新人和经验丰富的老手都是有用的。
本篇中描述最常见的自动化测试类型,还描述了可以增强您的自动化测试套件可维护性和扩展性的“设计模式”。
还没有使用这些技术的、有经验的自动化测试工程师会对这些技术更加感兴趣。
测试类型
您应该测试应用程序中的哪些部分?
这取决于您的项目的各种影响因素:
用户的期望,时间期限,项目经理设置的优先事项等等。
但是,一旦项目边界定义完成,作为测试工程师,你必须做出要测试什么的决定。
为了对Web应用的测试类型进行分类,我们在这里创建了一些术语。
这些术语并不意味着标准,但是这些概念对web应用测试来说非常典型。
测试静态内容
静态内容测试是最简单的测试,用于验证静态的、不变化的UI元素的存在性。
例如:
→每个页面都有其预期的页面标题?
这可以用来验证链接指向一个预期的页面。
→应用程序的主页包含一个应该在页面顶部的图片吗?
→网站的每一个页面是否都包含一个页脚区域来显示公司的联系方式,隐私政策,以及商标信息?
→每一页的标题文本都使用的
标签吗?
每个页面有正确的头部文本内吗?
您可能需要或也可能不需要对页面内容进行自动化测试。
如果您的网页内容是不易受到影响手工对内容进行测试就足够了。
如果,例如您的应用文件的位置被移动,内容测试就非常有价值。
测试链接
Web站点的一个常见错误为的失效的链接或链接指向无效页。
链接测试涉及点各个链接和验证预期的页面是否存在。
如果静态链接不经常更改,手动测试就足够。
但是,如果你的网页设计师经常改变链接,或者文件不时被重定向,链接测试应该实现自动化。
功能测试
在您的应用程序中,需要测试应用的特定功能,需要一些类型的用户输入,并返回某种类型的结果。
通常一个功能测试将涉及多个页面,一个基于表单的输入页面,其中包含若干输入字段、提交“和”取消“操作,以及一个或多个响应页面。
用户输入可以通过文本输入域,复选框,下拉列表,或任何其他的浏览器所支持的输入。
功能测试通常是需要自动化测试的最复杂的测试类型,但也通常是最重要的。
典型的测试是登录,注册网站账户,用户帐户操作,帐户设置变化,复杂的数据检索操作等等。
功能测试通常对应着您的应用程序的描述应用特性或设计的使用场景。
测试动态元素
通常一个网页元素都有一个唯一的标识符,用于唯一地定位该网页中的元素。
通常情况下,唯一标识符用HTML标记的’id’属性或’name’属性来实现。
这些标识符可以是一个静态的,即不变的、字符串常量。
它们也可以是动态生产值,在每个页面实例上都是变化的。
例如,有些Web服务器可能在一个页面实例上命名所显示的文件为doc3861,并在其他页面实力上显示为doc6148,这取决于用户在检索的‘文档’。
验证文件是否存在的测试脚本,可能无法找到不变的识别码来定位该文件。
通常情况下,具有变化的标识符的动态元素存在于基于用户操作的结果页面上,然而,显然这取决于Web应用程序。
下面是一个例子。
_ID74: _ID75: 0: _ID79: 0: checkBox"type="checkbox"value="true"/> 这是一个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,因为这是最严格的类型检查点。 您可以随后更改它,但至少你不会遗漏任何潜在的故障。 erify/assertText是最特殊的测试类型。 HTML元素(标签)或文本的不符合都会导致测试失败。 也许你的网页设计师经常改变页面面,而你不希望在他们改变页面时,你的测试失败,因为这是期望中的周期性变更。 但是,假如你仍然需要检查的页面上的东西,如段落、标题文本或图像。 在这种情况下,您可以使用verify/assertElementPresent。 这将确保一个特定类型的元素存在(如果使用XPath,可以确保它相对页面内其他对象的存在)。 但你不关心的内容是什么,你只关心某个特定的元素,比方说,一个图片在一个特定的位置。 随着时间的推移和经验的积累,如何决定使用还是非常简单的。 定位元素的策略 选择一个定位策略 元素的ID →元素的name属性 →XPath语句 →通过一个链接的文本 →文档对象模型(DOM) 使用元素的ID或name定位符,在测试执行方面来说,是最有效的方式。 也让你的测试代码更具可读性,如果在页面源代码中的ID或name属性被友好命名的话。 XPath语句需要更长的时间来处理,因为浏览器必须运行它的XPath处理器。 在InternetExplorer7,XPath出了名的慢。 使用链接的文本进行定位是很方便的,并运行起来也不错。 这种技术只适用于链接。 另外,如果链接文本很可能会经常改变,使用标签定位元素将是更好的选择。 不过,有时你必须使用XPath定位。 如果一个页面元素没有一个ID或者name属性,除了XPath定位没得选择。 (DOM定位器不再普遍使用,因为,XPath可以做得更好。 DOM定位器只简单地为遗留测试而存在)。 相对使用ID或name属性定位,使用XPath进行定位有一个独特的优势。 使用XPath(DOM)中,你可以找到页面上相对于其他对象的一个对象。 例如,如果有一个链接必须存在 使用ID和name属性定位,你只能得出它们存在指定的页面,而不知具体的页面位置。 如果你必须测试显示公司标志的图像出现在页面顶部的头部分,XPath定位可能是更好的选择。 定位动态元素 正如前面测试类型部分所述,动态元素的页面标识在不同的页面实例上市不同的。 例如, 'adminHomeForm: _ID38');"href="#">ViewArchivedAllocationEvents 这个HTML锚标记定义了一个ID属性为“adminHomeForm”按钮。 和大部分HTML标签相比,这是一个相当复杂的锚标记,但它仍然是一个静态标签。 每次页面被浏览器加载时,HTML将保持不变。 它的ID在所有的页面实例里保持不变,也就是说,页面被展示时,这个UI元素总是有同样的标识符。 所以,点击此按钮的测试脚本(SeleniumServer)如下所示: selenium.click("adminHomeForm"); 然而,你的应用程序,可能生成动态的HTML标识符。 在不同的网页实例中,标识符发生改变。 例如,一个动态的页面的HTML元素可能会是这个样子: _ID74: _ID75: 0: _ID79: 0: checkBox" type="checkbox"name="addForm: _ID74: _ID75: 0: _ID79: 0: checkBox" value="true"/> 这是一个复选框,id和name属性都是addForm: _ID74: _ID75: 0: _ID79: 0: checkBox。 在这种情况下,使用标准的定位,测试脚本应该是这样子的: selenium.click("addForm: _ID74: _ID75: 0: _ID79: 0: checkBox"); 对于动态生成的标识符,这种做法行不通。 下一次页面加载时,标识符将是一个不同的值,执行上述脚本会遇到“elementnotfound”错误。 要更正该问题,一个简单的解决办法是使用XPath定位替代ID定位器。 因此,对于该复选框,可以简单地使用 selenium.click("//input"); 或者,如果它不是在页面上的第一个文本输入域,尝试一个更详细的XPath语句。 selenium.click("//input[3]"); 或 selenium.click("//div/p[2]/input[3]"); 但是,如果你确实需要使用ID来定位元素,可以换一种不同的解决方案。 您可以先捕捉到网站的这个ID,然后再使用它,例如: String[]checkboxids=selenium.getAllFields();//CollectallinputIDsonpage. for(Stringcheckboxid: checkboxids){ if(checkboxid.contains("addForm")){ selenium.click(expectedText); } } 如果页面上只有一个复选框的ID文本为“expectedText”时,这种方法工作。 定位Ajax元素 定位、验证AJAX元素的最好的方式是使用Selenium2.0webdriver的API,它专门解决Selenium1.0测试AJAX元素的一些限制。 在Selenim2.0中,可以使用waitfor()方法来等待一个页面元素变得可用。 该参数是一个WebDriver用来实现定位的By对象。 这是WebDriver的章节中详细解释。 在Selenium1.0(Selenium-RC的)中,要做到这一点需要编写更多的编码,但它并不难。 首先检查元素,如果它存在,等待预定义的时间段,然后再重新检查。 这在循环内执行,如果超过一个预定的超时,元素不存在则终止循环。 让我们考虑页面上实现AJAX效果的一个链接(链接=ajaxLink),可以使用循环处理: //Loopinitialization. for(intsecond=0;;second++){ //Ifloopisreached60secondsthenbreaktheloop. if(second>=60)break; //Searchforelement"link=ajaxLink"andifavailablethenbreakloop. try{if(selenium.isElementPresent("link=ajaxLink"))break;}catch(Exceptione){} //Pausefor1second. Thread.sleep(1000); } 这当然不是唯一的解决办法。 Ajax是一个共同的话题,在用户论坛上,查找一下之前的讨论,看看别人是如何做的。 封装Selenium调用 与任何编程一样,你需要使用工具函数来处理在测试代码中重复的函数。 避免重复的方法之一是封装常用的Selenium方法的调用。 例如,测试时经常点击页面上的元素,等待页面加载。 selenium.click(elementLocator); selenium.waitForPageToLoad(waitPeriod); 为了不重复上述代码,你可以写一个包装方法实现这两个功能。 /** *ClicksandWaitsforpagetoload. * *paramelementLocator *paramwaitPeriod */ publicvoidclickAndWait(StringelementLocator,StringwaitPeriod){ selenium.click(elementLocator); selenium.waitForPageToLoad(waitPeriod); } 判断元素存在的“安全操作” 另一种常见的封装Selenium的方法,在执行进一步操作前检查页面上的元素存在性。 这有时被称为“安全操作”。 例如,下面的方法可用于实现一个依赖期望的元素存在的安全操作。 /** *Selenum-RC--Clicksonelementonlyifitisavailableonpage. * *paramelementLocator */ publicvoidsafeClick(StringelementLocator){ if(selenium.isElementPresent(elementLocator)){ selenium.click(elementLocator); }else{ //UsingtheTestNGAPIforlogging Reporter.log("Element: "+elementLocator+",isnotavailableonpage-" +selenium.getLocation()); } } 上述例子使用的是Selenium1.0API,Selenium2.0同样支持安全操作。 /** *Selenium-WebDriver--Clicksonelementonlyifitisavailableonpage. * *paramelementLocator */ publicvoidsafeClick(StringelementLocator){ WebElementwebElement=getDriver().findElement(By.XXXX(elementLocator)); if(webElement! =null){ selenium.click(elementLocator); }else{ //UsingtheTestNGAPIforlogging Reporter.log("Element: "+elementLocator+",isnotavailableonpage-" +getDriver().getUrl()); } } 在第二个例子中,’XXXX’方法是一个占位符,可以用元素定位方法进行替换。 使用安全方法取决于测试开发人员的决定。 因此,如果测试需要继续执行,即使知道页面上一些元素没有发现,这时可以使用安全方法,并发送一条缺少元素的消息到日志文件。 这基本上等于实现了带报告机制的验证,而不是一个失败就终止执行的断言。 但是,如果元素必须在页面上出现,以便能够执行进一步的操作(如一个门户网站主页上的登录按钮),这时安全方法技术不应该被使用。 UI映射 一个UI映射是一种机制,它存储所有的定位器的测试套件在一个地方,方便修改UI元素的路径标识符或改变在AUT。 测试脚本,然后使用UI地图定位以被测试的元件。 基本上,UI地图是一个存储库的测试脚本对象,对应于被测试的应用程序的UI元素。 是什么让一个UI地图有帮助吗? 其主要目的是测试脚本的管理更加容易。 当定位需要编辑,有一个中央位置轻松地找到对象,而不是通过搜索测试脚本代码。 此外,它允许改变的标识符在一个地方,而不是在多个地方,以使更改在测试脚本,或为此事,在多个测试脚本。 总之,一个UI地图有两个显着的优点。 UI对象使用一个集中的位置,而不是让他们分散在整个脚本。 这使得脚本维护更高效。 神秘的HTML标识符和名称可以被赋予了更多的人类可读的名字,提高测试脚本的可读性。 考虑下面很难理解的测试代码(Java语言)。 publicvoidtestNew()throwsException{ selenium.open(); selenium.type("loginForm: tbUsername","xxxxxxxx"); selenium.click("loginForm: btnLogin"); selenium.click("adminHomeForm: _activitynew"); selenium.waitForPageToLoad("30000"); selenium.click("addEditEventForm: _IDcancel"); selenium.waitForPageToLoad("30000"); selenium.click("adminHomeForm: _activityold"); selenium.waitForPageToLoad("30000"); } 该代码很难被那些不熟悉待测应用(AUT)页面源代码的人理解。 即使是待测应用的固定用户可能也很难理解这段脚本代码的作用。 一个更好的脚本可能是: publicvoidtestNew()throwsException{ selenium.open(); selenium.type(admin.username,"xxxxxxxx"); selenium.click(admin.loginbutton); selenium.click(admin.events.createnewevent); selenium.waitForPageToLoad("30000"); selenium.click(admin.events.cancel); selenium.waitForPageToLoad("30000"); selenium.click(admin.events.viewoldevents); selenium.waitForPageToLoad("30000"); } 使用备注和空格换行、再加上UI映射标识,下面的代码更加易读: publicvoidtestNew()throwsException{ //Openappurl. selenium.open(); //Provideadminusername. selenium.type(admin.username,"xxxxxxxx"); //ClickonLoginbutton. selenium.click(admin.loginbutton); //ClickonCreateNewEventbutton. selenium.click(admin.events.createnewevent); selenium.waitForPageToLoad("30000"); //ClickonCancelbutton. selenium.click(admin.events.cancel); selenium.waitForPageToLoad("30000"); //ClickonViewOldEventsbutton. selenium.click(admin.events.viewoldevents); selenium.waitForPageToLoad("30000"); } 有多种方法可以实现UI映射。 可以创建一个类或结构体来存储字符串变量,每个变量存储一个定位信息。 或者,使用一个文本文件来存储键值对。 在Java中,一个包含键值对的属性property文件可能是最好的方法。 考虑如下属性文件prop.properties,为上述代码例子中的UI元素指定了“别名”: admin.username=loginForm: tbUsername admin.loginbutton=loginForm: btnLogin admin.events.createnewevent=adminHomeForm: _activitynew admin.events.cancel=addEditEventForm: _IDcancel admin.events.viewoldevents=adminHomeForm: _activityold 其中定位信息还是指向页面的HTML对象,但我们在测试脚本和UI元素之间引入一层抽象层。 测试类从属性文件中读取定位信息,从而实现UI映射。 页面对象设计模式 页面对象设计模式,可以提高自动化测试脚本的维护性、减少代码重复,越发流行。 页面对象是一个面向对象的类,作为待测应用对外提供的接口。 测试代码在需要和UI页面交互时,使用此页面对象类的方法。 这样做的好处是,如果UI页面发生变化,测试代码本身并不需要改变,只需要改变相应的页面对象的代码。 为适应新UI页面的所有更改,都位于一个地方。 页面对象设计模式具有以下优点: 1、测试代码和页面相关的代码,比如页面元素定位信息(若使用UI映射,也包括定位信息 如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。