自动化测试的定位方法

1.id--标签中id 的值

如果开发人员编程规范,页面的元素id 不重复的且不是动态生成的id时,使用id 定位非常容易。

//<select style="width: 33%" id="CityCode" name="CityCode" class="form-control lopicker">
//使用id定位元素
WebElement element =  driver.findElement(By.id("CityCode"));

2.name--标签中name的值

 
  1. //<select style="width: 33%" id="CityCode" name="CityCode" class="form-control lopicker">

  2.  
  3. //使用name定位元素

WebElement cityelement = driver.findElement(By.name("CityCode"));

3.className--标签中class属性的值

 
  1. //<select style="width: 33%" id="ProvinceCode" name="ProvinceCode" class="form-control lopicker">

  2. //使用className定位

  3.  
  4. WebElement element = driver.findElement(By.className("form-control"));

4.tagName--标签名

 
  1. //<select style="width: 33%" id="ProvinceCode" name="ProvinceCode" class="form-control lopicker">

  2. //使用标签名定位元素

  3.  
  4. WebElement element = driver.findElement(By.tagName("select"));

5.linkText--a标签中全部的文本值

 
  1. //<a href="/Competition/Detail/c05a5ae3-32c6-4b81-b042-646ad8de275a" title="寻宝机器人赛" class="link item_title">寻宝机器人赛</a>

  2. WebElement comElement = driver.findElement(By.linkText("寻宝机器人赛"));

6.partialLinkText--a标签中部分的文本值

 
  1. //<a href="/Competition/Detail/c05a5ae3-32c6-4b81-b042-646ad8de275a" title="寻宝机器人赛" class="link item_title">寻宝机器人赛</a>

  2. WebElement comElement = driver.findElement(By.partialLinkText("寻宝"));

7.CSSSelector--css选择器(非常重要)

 
  1. //<select style="width: 33%" id="ProvinceCode" name="ProvinceCode" class="form-control lopicker">

  2. WebElement element = driver.findElement(By.cssSelector(".form-control"));

  3. WebElement element1= driver.findElement(By.cssSelector("select.form-control"));

复制代码

 
  1. /**

  2. * (有属性的标签)非常常用CssSelector:标签名[属性名='属性值'][属性名='属性值'][属性名='属性值'][属性名='属性值']

  3. */

  4. //<select style="width: 33%" id="CityCode" name="CityCode" class="form-control lopicker">

  5. WebElement cityelement = driver.findElement(By.cssSelector("select#CityCode"));

  6. WebElement cityelement1 = driver.findElement(By.cssSelector("#CityCode"));

  7. WebElement cityelement2 = driver.findElement(By.cssSelector("select[name='CityCode']"));

  8. WebElement cityelement3 = driver.findElement(By.cssSelector("select[class='form-control lopicker'][name='CityCode']"));

复制代码

8.xpath--相对路径/绝对路径

使用chrome自带或者火狐的xpath的插件可以获得元素的相对或者绝对路径。

chrome:

 

fireFox:

 
  1. //<select style="width: 33%" id="AreaCode" name="AreaCode" class="form-control lopicker">

  2. //通过单个属性定位

  3. WebElement areaElement = driver.findElement(By.xpath("//*[@id=\"AreaCode\"]"));

  4. //通过多个属性定位

  5. WebElement areaElement1 = driver.findElement(By.xpath("//select[@style='width: 33%' and @name='AreaCode']"));

 

复制代码

 
  1. //<a href="/Competition/Detail/c05a5ae3-32c6-4b81-b042-646ad8de275a" title="寻宝机器人赛" class="link item_title">寻宝机器人赛</a>

  2. //通过contains表达式

  3. WebElement comElement1 = driver.findElement(By.xpath("//a[@class='link item_title' and contains(text(),'机器人赛')]"));

  4. //通过startsWith表达式

  5. WebElement comElement2 = driver.findElement(By.xpath("//a[@class='link item_title' and starts-with(text(),'寻宝')]"));

  6. //如果读者的谷歌版本只支持xpath1.0,所以ends-with不能使用

  7. // WebElement comElement3 = driver.findElement(By.xpath("//a[@class='link item_title' and ends-with(text(),'机器人赛')]"));

  8. //如果ends-with不支持,可以使用下面方式代替

  9. WebElement comElement4 = driver.findElement(By.xpath("//a[substring(text(), string-length(text()) - string-length('人赛') +1) = '人赛']"));

复制代码

 

上面总结了8种定位元素的方法。

下面说明一些特殊情况:

1.id是动态生成的。

这种情况下,可以选择其他的定位方式。如cssSelector xPath等

如,生成的id总是以register字符串结尾:

<input id="m.f0.menu.f2.volumeTabs.BLOCK_COMMON.tcw.form.register" name="m.f0.menu.f2.volumeTabs.BLOCK_COMMON.tcw.form.register" class="aranea-checkbox" type="checkbox"> </td>

此时,可以通过xpath的方式来查找

driver.findElement(By.xpath("//input[ends-with(@id,'register')]"));

如果这个动态id有规律可循的话,也可以通过id来定位元素。具体就不举例了。

 

2.可以将查找元素封装成相应的方法,直接调用。方便添加日志信息。

复制代码

 
  1. /**

  2. * 查找元素的方法 element

  3. */

  4. public WebElement findElementBy(By by) {

  5. return driver.findElement(by);

  6. }

  7.  
  8. /**

  9. * 查找多个元素的方法 elements

  10. */

  11. public List<WebElement> findElementsBy(By by) {

  12. return driver.findElements(by);

  13. }

  14.  
  15. /**

  16. * 查找到多个元素后,继续向下查找(定位出一个元素这是一堆相同的elements中 选择 其中方的 一个 然后在这个选定的中 继续定位)

  17.   */

  18. public WebElement getOneElement(By bys, By by, int index) {

  19.     return findElementsBy(bys).get(index).findElement(by);

  20. }

复制代码

 

3.在查找元素的时候,会考虑到该元素资源是否已经加载完成。

下面给大家总结一下,关于自动化测试中的“等待”:

1.硬性等待---封装成方法,方便调用。

/**
* 硬性等待,等待时间为:sleepTime。
*/
public void Wait(int sleepTime) {
if (sleepTime <= 0) {
return;
}
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

 

2.隐式等待---这个等待是全局的,是针对当前driver的。一旦设置之后,只要该driver执行findElement或者findElements方法,首先回去找元素,如果没找到,会在设置的时间内一直轮询查找,直到timeOut.由于是全局性的,有些元素不需要等待,所以会造成时间的浪费。因为浏览器是自上而下渲染的,如果元素1在元素2的上面,当你第一次查找过元素2,之后再查找元素1的时候,是不需要等待的。但是设置了该全局参数之后,还是会去等待。

driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

3.显示等待(推荐使用)

复制代码

 
  1. /**

  2. * 对外提供智能等待 查找元素的方法

  3. * @param driver

  4. * @param time

  5. * 元素的超时等待时间

  6. * @param by

  7. * @return

  8. */

  9. public static WebElement waitElement(WebDriver driver,int time,By by) {

  10. WebElement element=null;

  11.  
  12. WebDriverWait wait = new WebDriverWait(driver, time);

  13.  
  14. try {

  15. element = wait.until(new ExpectedCondition<WebElement>() {

  16.  
  17. public WebElement apply(WebDriver driver) {

  18. WebElement element = driver.findElement(by);

  19. return element;

  20. }

  21. });

  22. } catch (TimeoutException e) {

  23. System.out.println("元素"+by.toString()+" "+time+"S内未能找到");

  24. logger.info("元素未找到");

  25. }

  26.  
  27.  
  28. return element;

  29.  
  30. }

  31.  
  32. /**

  33. * 对外提供智能等待 查找元素的方法,固定的等待超时时间为5S

  34. * @param by

  35. * @return

  36. */

  37. public static WebElement waitElement(By by) {

  38.  
  39. WebDriver driver= GetDriverUtil.getDriver();

  40. return waitElement(driver, 5, by);

  41. /*WebElement element = null;

  42. try {

  43. element = (new WebDriverWait(driver, 5)).until(new ExpectedCondition<WebElement>() {

  44.  
  45. @Override

  46. public WebElement apply(WebDriver driver) {

  47.  
  48. return driver.findElement(by);

  49. }

  50.  
  51.  
  52. });

  53. } catch (Exception e) {

  54. System.out.println("元素"+by.toString()+" "+"5S内未能找到");

  55. e.printStackTrace();

  56. }

  57.  
  58. return element;*/

  59. }

复制代码

 上面的ExpectedCondition是我们自己编写的,实际上,在selenium的ExpectedConditions类中,已经封装了各种元素等待条件。有兴趣可以去了解下

可以去看一下源码,内部也是使用的匿名内部类new ExpectedCondition{},下面是拿出一个来举例:

判断一个元素是否可点击:

1.该元素在dom中存在

2.该元素可见

3.该元素为enabled

 

复制代码

 
  1. /**

  2. * An expectation for checking an element is visible and enabled such that you can click it.

  3. *

  4. * @param locator used to find the element

  5. * @return the WebElement once it is located and clickable (visible and enabled)

  6. */

  7. public static ExpectedCondition<WebElement> elementToBeClickable(final By locator) {

  8. //匿名内部类

  9. return new ExpectedCondition<WebElement>() {

  10. @Override

  11. public WebElement apply(WebDriver driver) {

  12. //判断元素是否可见

  13. WebElement element = visibilityOfElementLocated(locator).apply(driver);

  14. try {

  15. //如果元素可见并且元素生效的话则返回元素

  16. if (element != null && element.isEnabled()) {

  17. return element;

  18. }

  19. return null;

  20. } catch (StaleElementReferenceException e) {

  21. return null;

  22. }

  23. }

  24.  
  25. @Override

  26. public String toString() {

  27. return "element to be clickable: " + locator;

  28. }

  29. };

  30. }

复制代码

 

上面总结的是元素的等待,自动化测试用,还有:等待页面加载的超时时间测试

a.等待页面加载,设置超时时间。超时之后,不再等待,直接去定位某元素。(需要执行js脚本)

复制代码

 
  1. /**

  2. *等待页面加载,设置页面加载的超时时间,如果规定时间内还未加载完成,则停止加载,并定位指定元素

  3. * @param driver

  4. * @param timeout

  5. * @param by

  6. */

  7.  
  8. public static void pageLoad(WebDriver driver,int timeout,String url) {

  9. try {

  10. //设置页面加载超时时间

  11. driver.manage().timeouts().pageLoadTimeout(timeout, TimeUnit.SECONDS);

  12. driver.get(url);

  13. } catch (Exception e) {

  14. ((JavascriptExecutor)driver).executeScript("window.stop()");

  15. }

  16.  
  17. driver.findElement(By.id("user[login]")).sendKeys("feifeifei");

  18.  
  19. }

复制代码

b.有时加载页面超时,需要刷新一次,并输出页面的加载状态。(需要执行js脚本)

复制代码

 
  1. /***

  2. * 启动浏览器并打开页面

  3. */

  4. public void launchBrowser(String webUrl, int timeOut) {

  5. //getDriver()就是上一篇博客中讲的 封装获取driver的方法

  6. driver = GetDriverUtil.getDriver();

  7. try {

  8. //最大化浏览器窗口(已经封装成方法)

  9. maxWindow();

  10. //设置等待页面加载的时间(已经封装成方法)

  11. waitForPageLoading(timeOut);

  12. //打开浏览器指定页面(已经封装成方法)

  13. get(webUrl);

  14. } catch (TimeoutException e) {

  15. logger.warn("页面没有完全加载出来,刷新重试");

  16. //刷新页面

  17. refresh();

  18. //创建js脚本执行器

  19. JavascriptExecutor js = (JavascriptExecutor) driver;

  20. //执行脚本,描述了文档的加载状态. 状态分为

  21. //loading document 仍在加载

  22. //interactive / 互动 文档已经完成加载,文档已被解析,但是诸如图像,样式表和框架之类的子资源仍在加载

  23. //complete / 完成 T文档和所有子资源已完成加载。状态表示 load 事件即将被触发。

  24.  
  25. String status = (String) js.executeScript("return document.readyState");

  26. //将返回的状态通过日志打印出来

  27. logger.info("打印状态:" + status);

  28. }

  29.  
  30. }

复制代码

 

 
  1. 在自动化测试过程中,还经常遇到异步请求的情况,如下图:

  2.  
  3.  
  4. 当需要进行异步请求元素的定位时,则需要等待异步脚本执行完成并返回结果。这时需要设置异步脚本的超时时间。

 
  1. /** setScriptTimeout。异步脚本的超时时间。(封装成方法,方便调用)webdriver可以异步执行脚本,这个是设置异步执行脚本脚本返回结果的超时时间 */

  2. public void setScriptTimeout(int timeOut) {

  3. driver.manage().timeouts().setScriptTimeout(timeOut, TimeUnit.SECONDS);

  4. }

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值