zoukankan      html  css  js  c++  java
  • 第三章 Webdriver API简介(中)

         ------Web自动化测试之Webdriver(python)--从零到熟练(系列)

    3.2.3  Xpath定位方法深入探讨

    相比cssSelectorxpath是我比较常用的一种定位元素的方式,因为它很方便,缺点是,消耗系统性能。如果Xpath使用的比较好,几乎可以定位到任何页面元素,而且受页面变化影响较小。

    1)常用的Xpath定位方法及其特点

    Ø 使用绝对路径定位元素。

    例如:driver.find_element_by_xpath ("/html/body/div/form/input")

    特点:这个路径是从网页起始标签开始一直到要定位的元素的路径,如果要定位的元素在页面最下面,则这个Xpath路径会非常长。如果在要定位的元素与页面开始之间的元素有任何增减,元素定位就会失败。

    Ø 使用相对路径定位元素。

    例如:driver.find_element_by_xpath ("//input")   返回查找到的第一个符合条件的元素。

    特点:相对路径一般只会包含与被定位元素最近的几层元素有关,相对路径写的好的话,页面变动影响最小,而且定位准确。

    Ø 使用索引定位元素,索引的初始值为1,注意与数组等区分开。

    例如:driver.find_element_by_xpath ("//input[2]") 返回查找到的第二个符合条件的元素。

    特点:如果一个页面中有多个相似的元素,或是一个层下面有多个同样的元素的时候,需要用索引的方法来定位,否则无法区分。

    Ø 结合属性值来定位元素

      例如:driver. find_element_by_xpath ("//input[@id='username']");

    driver. find_element_by_xpath ("//img[@alt='flowr']");

    特点:属性定位也是比较常用的方法,如果元素中没有常见的id,name,class等直接有方法可调用的属性,也可以查找元素中是否有其他能唯一标识元素的属性,如果有,就可以用此方法定位。

    Ø 使用逻辑运算符,结合属性值定位元素,andor

    例如:driver. find_element_by_xpath ("//input[@id='username' and @name='userID']");

    特点:多个属性值联合定位,更能准确定位到元素。并且如果多个相同标签的元素,如果其包含的属性值有不同的,也可以用这个方法区分开来。

    Ø 使用属性名来定位元素。

    例如:driver. find_element_by_xpath ("//input[@button]")

    特点:此方法可以区分同一种标签,含有不同属性名的元素。定位相对简单一些儿,但也同样存在着无法区分同种标签含有同种属性名的多个元素,这个时候要配合索引定位才行。

    Ø 类似于cssSlector,使用部分属性值匹配元素.

    例如:

    astarts-with()   

    driver. find_element_by_xpath ("//input[stars-with(@id,'user')]")

    bends-with()       

    driver. find_element_by_xpath ("//input[ends-with(@id,'name')]")

    ccontains()       

    例如:driver. find_element_by_xpath ("//input[contains(@id,"ernam")]")

      特点:此方法更加灵活,可以定位属性值不太规律,或是部分变动,中间有空格的情况。注:如果属性值中间包含空格,Webdriver定位的时候容易出错,时而能定位到时而定位不到,所以应该避免用含用空格的属性值定位。可以采用此方法,进行部分属性值定位。

    Ø 使用任意属性值匹配元素

    例如:driver. find_element_by_xpath ("//input[@*='username']")

    特点:此方法相当于模糊查询,只要欲定位的标签,如input中任何属性值等于‘username,就能匹配成功。缺点,可能会匹配含有这个属性值的其他元素,所以我们在定位的时候要查看一下这个元素值在页面中是否唯一。

    2)运用Xpath定位元素的思路

    当我们在做自动化测试的时候,欲对一个页面元素定位,通过上面我们讲到的选择定位方法筛选后,决定用Xpath定位了,此时我们应该怎么写Xpath呢?请按以下步骤来分析:

    a)先看一个这个元素是否有明显的,唯一的属性值。如果有,我们就用相对路径加属性值定位,这是最简单准确的定位方法。如://input[@alog-alias=’search’]

    b)如果要定位的元素,不符合上面的特症,元素属性要么是动态的,要么就是不能区分这个元素的,还有就是属性值中间有空格的情况,都无法定位。所以从此元素开始,向他的上一层查找。

    c)当遇到了一个符合条件的元素时,对其写Xpath,然后在Selenium IDE中验证是否能定位到该元素。如://div[@type=’good’],Selenium IDE中验证能定位到这个div

    d)然后从这个元素开始,一级级往下写,真到要定位的元素为止。如果你比较肯定写的是正确的,可以写完后再验证,如果不肯定,就写一层,用Selenium IDE验证一下,以确保安全。如://div[@type=’good’]/div/input

    e)当Selenium IDE定位成功后,再放到测试用例中去调试运行。虽然Selenium IDE能定位到的代码也能定位到,不过还有因为延迟,操作顺序等会影响代码定位的因素存在。 

    3.2.4 元素定位不到的原因及解决办法

    在我们编写自动化测试用例的过程中,经常会遇到元素定位不到的现象,有的时候我们用Selenium IDE检查的时候也能在Firebug中看到,可是运行代码的时候,总是提示元素找不到。经过我以往和经验和大家在网上的讨论,我总结了以下几种情况:

    (1)定位属性值是动态变化的情况

    现象:在我们定位元素的时候,发现有id,name或其他的属性存在,于是就用相应的定位方法去定位。可是运行的时候提示定位不到,然后我们再去查看元素的时候,发现属性值和我们写代码的时候不一样了。

    原因:通常产生这种情况的原因就是你使用的属性值是动态变化的,主要表现有属性值是一串数据,或是字符加一串数据等情况。页面加载一次变化一次,每次都不相同。

    解决办法:我们应尽量避免用这样的属性值去定位,而采用这个元素下的其他固定不变的属性值。或是向上层查找,采用Xpath定位。

    (2)Iframe中的元素定位出错的情况

    现象:我们在定位元素的时候,查看网页源码,发现有iframe存在。可是我们没有做特殊处理,而是直接用通用的定位方法,name ,id,  xpath或者CSS来定位。用Selenium IDE验证能查找到元素,可是运行测试用例的时候,总是元素找不到。

    原因:在我们运行测试脚本的时候,代码获取的是页面的句柄,而iframe在句柄中是当成一个元素来处理的。脚本是没有办法自己去iframe中去定位元素的,所以当搜索完页面时,发现找不到要定位的元素,就当错误处理。

    解决办法:当需要定位iframe中的元素的时候,先将句柄切换到iframe中(driver.switchTo().frame("framename");),然后再去定位,就能定位到要测试的元素。

    (3)不同页面或iframe切换时元素定位情况

    现象:当我们在编写测试用例的时候,会遇到打开一个新页面,或是切换到一个新的iframe中,然后再去定位元素进行操作。但是我们的定位方法写的没有问题,而且在Selenium IDE中也验证通过,可是代码运行的时候还是会提示找不到元素。

    原因:其实这个和定位iframe中元素的情况是一样的,在打开一个页面或是切换到一个iframe的时候,driver获取的是当前页面或是iframe的句柄。当你的操作切换到新的页面或是iframe的时候,如果代码不去做相应的切换,查找元素的时候还会在原来的句柄下查找,当然会出现查找不到的情况。

    解决办法:当操作切换页面或是iframe的时候,我们的测试脚本也要做相应的切换,选择新打开的页面或是切换到新的iframe下。然后再去定位的时候,就会在新页面或是iframe下定位了。

    (4)Xpath编写出错的情况

    现象:如果我们对一个元素编写了对应的Xpath,然后在没有通过Selenium IDE进行验证的情况吧,就去编写代码执行测试用例。会出现查找不到元素的情况,或是页面发生了变化,导致Xpath路径有了变化,也会查找不到元素。

    原因:主要的问题就是Xpath编写出错了,或是页面有改动。不管是增加了新的模块或是隐藏的div,都会影响Xpath路径的。

    解决办法:将代码中的Xpath拷出来,放到Selenium IDE中进行验证。如果出错了,就做相应的修改。这个也是代码维护中当遇到的问题,被测试对象变化,导致测试用例的修改。

    (5)操作速度过快,被定位的元素没有加载出来的情况

    现象:在测试用例运行过程中,会出现被定位的元素有的时候能定位的到,有的时候却定位不到的现象。而我们去页面上验证我们的定位方法的时候,没有一点儿问题,显示不是定位方法写错了。

    原因:这种情况多半是因为测试用例执行到代码的时候,被定位元素没有加载出来造成的。网速原因,执行代码的机器原因,都会造成加载比程序执行的慢的情况。

    解决办法:在我们定位元素之前,评估一下页面的加载情况,如果有加载慢的地方,需要添加一定等待时间self.sleep(5000),等上几秒后再去定位操作。

    (6)定位页面嵌入式元素的情况

    现象:在页面中会有一些儿嵌入式元素,如object,播放器等。这个时候,我们对其操作的时候,是无法定位到上面的元素的。

    原因:嵌入式元素对webdriver来说是一个元素,不管里面包含多少元素,都无法操作。对于object对象,网上有说要对相应的Flash重新编译,添加相应的代码或是控件才能定位。但这样一样又不安全了,所以嵌入式对象一直是自动化测试的盲区。

    解决办法:嵌入式对象如果是简单的单击操作,可是用模拟鼠标单击相应的区域,就能完成操作。如果是输入操作,我们可以先模拟点击输入区,然后模拟键盘进行输入。除此之外,好像也没有什么好的办法。

    (7)firefox安全性报错的情况

    现象:firefox安全性强,不允许跨域调用出现报错,错误描述:uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMNSHTMLDocument.execCommand]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location:

    原因:这是因为firefox安全性强,不允许跨域调用。

    解决办法:Firefox 要取消XMLHttpRequest的跨域限制的话,第一

    是从 about:config 里设置 signed.applets.codebase_principal_support = true (地址栏输入about:config 即可进行firefox设置)。

    第二就是在open的代码函数前加入类似如下的代码:

    try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");

    }

    catch (e)

     {

    alert("Permission UniversalBrowserRead denied.");

     }

    对错误进行处理。

  • 相关阅读:
    windows的80端口被占用时的处理方法
    Ansible自动化运维工具安装与使用实例
    Tomcat的测试网页换成自己项目首页
    LeetCode 219. Contains Duplicate II
    LeetCode Contest 177
    LeetCode 217. Contains Duplicate
    LeetCode 216. Combination Sum III(DFS)
    LeetCode 215. Kth Largest Element in an Array(排序)
    Contest 176 LeetCode 1354. Construct Target Array With Multiple Sums(优先队列,递推)
    Contest 176
  • 原文地址:https://www.cnblogs.com/eagleking0318/p/6520894.html
Copyright © 2011-2022 走看看