本帖最后由 乐哈哈yoyo 于 2017-7-12 15:21 编辑
这是一篇非常好的总结性文章,实战经验积累,我们会持续更新这篇文章。
在做web项目的自动化端到端测试时主要使用的是 Selenium WebDriver来驱动浏览器。Selenium WebDriver的优点是支持的语言多,支持的浏览器多。主流的浏览器Chrome、Firefox、IE等都支持,手机上的浏览器Android、IPhone等也支持,甚至还支持PhantomJS(由于PhantomJS跑测试时并不需要渲染元素,所以执行速度快)。 webdriver 实用干货 但是我在使用Selenium WebDriver时,遇到了很多坑。这些问题,有的是因为Selenium WebDriver与浏览器不同版本之间兼容性的问题,有的是Selenium WebDriver本身的bug,当然也不乏自己对Selenium WebDriver某些功能理解不透彻。我花时间总结了一下,分享给大家,希望大家以后遇到问题可以避过这些坑,少走弯路。另外也总结了一些使用WebDriver的比较好的实践,也一并分享给大家。 WebDriver每次启动一个Firefox的实例时,会生成一个匿名的profile,并不会使用当前Firefox的profile。这点一定要注意。比如如果访问被测试的web服务需要通过代理,你想直接设置Firefox的代理是行不通的,因为WebDriver启动的Firefox实例并不会使用你这个profile,正确的做法是通过FirefoxProfile来设置。
- <p>CODE:
- 1 public WebDriver create() {
- 2 FirefoxProfile firefoxProfile = new FirefoxProfile();
- 3 firefoxProfile.setPreference("network.proxy.type",1);
- 4 firefoxProfile.setPreference("network.proxy.http",yourProxy);
- 5 firefoxProfile.setPreference("network.proxy.http_port",yourPort);
- 6 firefoxProfile.setPreference("network.proxy.no_proxies_on","");
- 7 return new FirefoxDriver(firefoxProfile);
- 8}</p>
复制代码通过FirefoProfile也可以设置Firefox其它各种配置。如果要默认给Firefox安装插件的话,可以将插件放置到Firefox安装目录下的默认的plugin文件夹中,这样即使是使用一个全新的profile也可以应用此plugin。 使用WebDriver点击界面上Button元素时,如果当前Button元素被界面上其他元素遮住了,或没出现在界面中(比如Button在页面底部,但是屏幕只能显示页面上半部分),使用默认的WebElement.Click()可能会触发不了Click事件。
修正方案是找到该页面元素后直接发送一条Click的JavaScript指令。
- CODE:
- 1((JavascriptExecutor)webDriver).executeScript("arguments[0].click();", webElement);
复制代码当进行了一些操作发生页面跳转时,最好加一个Wait方法等待page load完成再进行后续操作。方法是在某个时间段内判断document.readyState是不是complete。
- CODE:
- 01protected Function<WebDriver, Boolean> isPageLoaded() {
- 02 return new Function<WebDriver, Boolean>() {
- 03 @Override
- 04 public Boolean apply(WebDriver driver) {
- 05 return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
- 06 }
- 07 };
- 08 <font color="#444444"><font style="background-color: rgb(247, 247, 247);"><font face="Tahoma"><span style='text-align: left; color: rgb(0, 0, 0); text-transform: none; text-indent: 0px; letter-spacing: 1px; font-family: Monaco, Consolas, "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; font-size: 14px; font-style: normal; font-weight: normal; word-spacing: 0px; float: none; display: inline !important; white-space: pre; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px;'>}</span>
- 09
- 10 public void waitForPageLoad() {
- 11 WebDriverWait wait = new WebDriverWait(webDriver, 30);
- 12 wait.until(isPageLoaded());
- 13 }</font></font></font>
复制代码如果页面有Ajax操作,需要写一个Wait方法等待Ajax操作完成。方式与上一条中的基本相同。比如一个Ajax操作是用于向DropDownList中填充数据,则写一个方法判断该DropDownList中元素是否多余0个。
- CODE:
- 01private Function<WebDriver, Boolean> haveMoreThanOneOption(final By element) {
- 02 return new Function<WebDriver, Boolean>() {
- 03 @Override
- 04 public Boolean apply(WebDriver driver) {
- 05 WebElement webElement = driver.findElement(element);
- 06 if (webElement == null) {
- 07 return false;
- 08 } else {
- 09 int size = webElement.findElements(By.tagName("option")).size();
- 10 return size >= 1;
- 11 }
- 12 }
- 13 };
- 14 }
- 15
- 16 public void waitForDropDownListLoaded() {
- 17 WebDriverWait wait = new WebDriverWait(webDriver, 30);
- 18 wait.until(isPageLoaded());
- 19 }
复制代码以此类推,我们可以判断某个元素是否呈现、某个class是否append成功等一系列方法来判断ajax是否执行完成。
|