51Testing软件测试论坛

标题: selenium总结 [打印本页]

作者: 阿蛮的开心姐    时间: 2018-3-26 14:48
标题: selenium总结
简述前端自动化测试

测试是完善研发体系中不可或缺的一环。在合理的时间以合理的方式引入自动化测试能有效减少人工维护成本。

自动化的收益 = 迭代次数 * 全手动执行成本 - 首次自动化成本 - 维护次数 * 维护成本

单元测试维护成本较高,而且没法满足前端测试的所有需求。

前端自动化测试方向:

界面回归测试、功能测试、性能测试、页面特征检测

测试组成:

类库单元测试自动化

UI组件测试自动化

2.Selenium+webdriver简介

Selenium可以让浏览器自动执行各种Web应用。它目前主要用于Web端的自动化测试,但它并不仅仅局限于
此。它还可以用于自动化管理基于Web的各种无聊费时的任务。

Selenium目前被一些使用广泛的浏览器厂商所支持,并作为功能的一部分加入到了浏览器中。它也是无数其
他测试工具、API和框架的核心技术支撑。

Selenuim2集成了WebDriver API,而且目前基本上主流浏览器(Chrome/Firefox/Opera/IE)都支持WebDriver
API,并且提供了相应的WebDriver工具,所以“Selenium目前被一些使用广泛的浏览器厂商所支持”还是很有
说服力的。

WebDriver的目的是提供一个使用简单、逻辑简洁的编程接口。它是一个远程的控制接口,可以通过它控制
我们的代理。它提供的是一个平台化的、独立于任何语言的线路协议(自行翻译的),可以通过这个协议
远程控制Web浏览器的行为。它提供了一系列的接口可以用于发现和操作我们的Web文档中的DOM元素,
从而控制用户代理(浏览器)的行为。

所以可以认为WebDriver提供了一套可以远程控制浏览器行为的线路协议(wire protocol),简单粗暴点
就是遵循这个协议可以让浏览器运行测试脚本。

WebDriver有几种实现,分别是HtmlUnitDrvier、FirefoxDriver、InternetExplorerDriver、ChromeDriver、
OperaDriver,除了 InternetExplorerDriver只能在Windows平台运行,其他WebDriver均能跨平台。

Browser Driver一般是一个EXE(可执行)程序,或者浏览器的一个扩展程序,它使用HTTP Server持续监
听Selenium2 Commands。

具体的执行步骤如下:

1. 每个Selenium命令,这里指的是所谓的基础操作,例如,点击、输入等,都会创建一条HTTP请求,发送
给Browser WebDriver

2. Browser WebDriver使用一个HTTP Server监听和接收HTTP请求

3. HTTP Server根据协议规则定义这些Selenium命令对应的浏览器具体操作

4. 浏览器执行这些操作

5. 浏览器将执行状态返回给HTTP Server

6. HTTP Server再将这些状态信息返回给自动化脚本

PS:上述的所有操作都在同一个Session(定义在这里https://www.w3.org/TR/webdriver/#sessions)中进
行的;协议规则指的是之前提到的WebDriver;通过Browser Driver执行,Browser Driver执行Selenium
Command调用的是浏览器内置的自动化支持功能。自动化脚本中的每一个Selenium Command都会创建一
个带有Path的HTTP request。 当自动化脚本执行的时候,第一个HTTP request会创建一个新的Session,
接下来对浏览器的操作将通过这个Session来执行。 创建的Session ID将用于标识后续的自动化脚本都在同
一个Session中执行。(了解这些很重要!)

  1. selenium 常用命令

  2. 3.搭建selenium环境

  3. 1.加入Maven依赖

  4. <!--引入selenium依赖 -->

  5. <dependency>

  6. <groupId>org.seleniumhq.selenium</groupId>

  7. <artifactId>selenium-java</artifactId>

  8. <version>3.0.1</version>

  9. </dependency>  

  10. <!--引入junit依赖 -->

  11. <dependency>

  12. <groupId>junit</groupId>

  13. <artifactId>junit</artifactId>

  14. <version>4.12</version>

  15. <scope>test</scope>

  16. </dependency>

  17. 2.Demo工程

  18. import org.junit.Test;
  19. import org.openqa.selenium.*;
  20. import org.openqa.selenium.chrome.ChromeDriver;
  21. public class Demo {
  22.      public static WebDriver getWebDriver(){

  23.   //设置chromedriver.exe 路径
  24.            System.setProperty("webdriver.chrome.driver", "D:/work/DirectHtmlUnit/AdapterTest/res/chromedriver.exe");
  25.            WebDriver driver = new ChromeDriver();
  26.            return driver;
  27.         }
  28.      @Test
  29.     public void test(){
  30.            WebDriver webDriver = getWebDriver();
  31.             webDriver.get("http://www.baidu.com");
  32.             WebElement wd = webDriver.findElement(By.id("kw"));
  33.             wd.clear();
  34.             wd.sendKeys("selenium");
  35.             wd.sendKeys(Keys.ENTER);
  36.             webDriver.quit();
  37.      }
  38. }
复制代码



4.开发必备

1.选择元素

用Selenium实现自动化测试的过程中,如果选择页面上的元素并且对之进行各种操作,是一个常见的任务。
Selenium提供了多种定位方法

· id:最有效、最方便的方法

· name:跟id类似的

· class name:对某些具有相同类的元素一网打尽的好方法

· link text 和 partial link text: 用在定位超链接上比较多

· tag name:与class name有点类似

· css selector:如果你试用jQuery,这个一定是你喜欢的方法

· xpath:。。。 /html/body/div/div[2]/div[2]/div[2]/div[5]/div/p[2]

2.Xpath

XPath在Selenium测试中有好些缺点:

* 性能差,定位元素的性能比起大多数其他方法要差;

* 不够健壮,XPath会随着页面元素布局的改变而改变;

* 兼容性不好,在不同的浏览器下对XPath的实现是不一样的。

Xpath要在正确的前提下,正确地使用。

XPath通常会在如下场景:一个写自动化测试的人,发现他想要操作的元素不能通过id, name, link text等比较
方便有效的方法来进行定位,苦逼的他没能说服开发这个页面的人把他想要的id加上,他开始用所谓的XPath
来定位元素,代码中充满了各种让人摸不着头脑的XPath(/html/body/div/div[3]/div[2]/div[4]/p[2]),在我
看来这样的代码跟录制出来的脚本没有任何区别。可读性差,几乎不能维护。XPath理论上可以这样使用,
但是实际上应该避免这样的使用。

假如说那个苦逼的人想定位到页面上的一个提交按钮,这个按钮不能通过id或者name来定位。这个时候他
要做的事情不是打开Firebug定位提交按钮右击鼠标再点“Copy XPath”。而是应该是找开发把id或者name加
上。如果不行,解决思路可以是:1. 找到该按钮的特征,例如按钮的文字是 submit;2. 用XPath定位,可
以这样写://button[@value=’submit’]。

如果可能的话,尽可能使用id或者name。



3.在WebDriver中运行JavaScript

使用JavaScript编写测试

WebDriver提供了方法来同步/异步执行JavaScript代码,这是因为javascript可以完成一些WebDriver本身所
不能完成的功能,从而让WebDriver更加灵活和强大。

  1. JavascriptExecutor jsExe = (JavascriptExecutor) webDriver;
  2. jsExe.executeAsyncScript("alert(\"Hello World!\");");//异步
  3. jsExe.executeScript("alert(\"Hello World!\");");//同步

  4. 等待页面加载完成

  5. while (jsExe.executeScript("return document.readyState" ).equals ("complete")){
  6.      try {
  7.          Thread.sleep(500);
  8.     } catch (InterruptedException e) {
  9.         e.printStackTrace();
  10.     }
  11. }

  12. 判断页面元素是否存在

  13. String js =" if(document.getElementById('kw')){ return true; } else{ return false; }";
  14. Object result = ((JavascriptExecutor)webDriver).executeScript(js);

  15. 滚动页面

  16. JavascriptExecutor scroll = (JavascriptExecutor) webDriver;
  17. scroll.executeScript("arguments[0].scrollIntoView();", element);

  18. ...

  19. 可以执行一切JavaScript代码

  20. javascriptExecutor.executeScript("arguments[0], arguments[1], arguments[2]", arg0,arg1,arg2);

  21. ···还可以执行很多复杂的操作

  22. 拖动元素

  23. Actions actions = new Actions(webDriver);
  24. actions.moveToElement(element).clickAndHold().moveByOffset(Xoffset, Yoffset).perform();
  25. actions.release().perform();

  26. 屏幕截图

  27. TakesScreenshot takesScreenshot = (TakesScreenshot) webDriver;
  28. File scrFile = takesScreenshot.getScreenshotAs(OutputType.FILE);
复制代码



5.踩过的坑

1.默认的WebElement.Click()可能触发不了Click事件

使用WebDriver点击界面上Button元素时,如果当前Button元素被界面上其他元素遮住了,或没出现在界面
中(比如Button在页面底部,但是屏幕只能显示页面上半部分)

public static void jsClick(WebDriver driver, WebElement element) {
    JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
    jsExecutor.executeScript("arguments[0].click()", element);
}

2.经常出现no such element

可能原因,页面没加载完成。可以设置等待

直接等待

Thread.sleep(1000);  

隐式等待
  1. public boolean isByElementDisplayed(By by, int time,WebDriver webDriver) {

  2.         boolean status = true;

  3.         while(!isPresent(chrome, by)){

  4.             webDriver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);

  5.         }

  6.         return status;      

  7.     }

  8.     public boolean isPresent(WebDriver webDriver, By by){

  9.         boolean display = false;

  10.         try{

  11.             webDriver.findElement(by).isDisplayed();

  12.             return display= true;

  13.         }catch(NoSuchElementException e){

  14.             return display;

  15.         }

  16.     }  

  17. 显示等待

  18.     WebElement e = (new WebDriverWait( webDriver, 10)) .until(
  19.         new ExpectedCondition< WebElement>(){
  20.             @Override
  21.             public WebElement apply(WebDriver driver) {
  22.                 return driver.findElement( By.id("id"));
  23.             }
  24.         });
复制代码

3.No session

可能的原因,如前面描述selenium与webdriver通过session建立httpServer连接,当批量运行测试时,产生过
多会话,机器性能原因可能导致失败。

关闭窗口方法 webDriver.close() 和webDriver.quit() 。Close只是关闭当前窗口,webdriver进程仍存在;Quit
是关闭当前进程,释放资源。

4.单独执行测试可以通过,批量测试就报错

或者调试执行可以,直接运行就报错。或者换台机器就不能通过了...

可能的原因,归结为运行环境的不确定造成的,和上面第二种原因是一样的,页面加载渲染的不确定性。

···

其实selenium还是挺稳定的,一切bug都是有原因的


作者: baijh    时间: 2018-3-28 20:00
感谢楼主分享




欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2