selenium 作为现在最主流的UI自动化框架,基本成为了自动化测试必备的技能,本文是笔者在学习的时候做的笔记,也是实战内容。

一、selenium相关配置:

1、官方文档地址:

https://www.selenium.dev/documentation/zh-cn/

2、谷歌各版本下载

http://www.chromedownloads.net/chrome64win/

3、谷歌驱动下载

http://npm.taobao.org/mirrors/chromedriver

4、禁止谷歌浏览器更新

https://jingyan.baidu.com/article/76a7e409f2137afc3b6e15be.html

5、selenium工作流程

● selenium client(Java等语言编写的自动化测试脚本)初始化一个service服务,通过Webdriver启动浏览器驱动程序
● 通过RemoteWebDriver向浏览器驱动程序发送HTTP请求,浏览器驱动程序解析请求,打开浏览器,并获得sessionid,如果再次对浏览器操作需携带此id
● 打开浏览器,绑定特定的端口,把启动后的浏览器作为webdriver的remote server
● 打开浏览器后,所有的selenium的操作(访问地址,查找元素等)均通过RemoteConnection链接到remote server,然后使用execute方法调用_request方法通过urlib3向remote server发送请求
● 浏览器通过请求的内容执行对应动作
● 浏览器再把执行的动作结果通过浏览器驱动程序返回给测试脚本


二、selenium的基本使用

1、添加依赖

依赖地址:https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java

    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>3.141.59</version>
    </dependency>

2、设置驱动

想要使用selenium启动浏览器必须先下载对应版本的浏览器驱动,下载后需要进行设置*

  • 设置驱动有两种方式
  1. 设置环境变量: 将驱动设置成电脑的环境变量
  2. 直接在代码中声明驱动位置:
    System.setProperty("webdriver.chrome.driver", "src/test/resources/chromedriver.exe");
    
    

3、打开网页

		ChromeDriver chromeDriver = new ChromeDriver();
		driver.get("https://www.baidu.com");

三、selenium三大等待

1、硬性等待(不推荐)

// 会一直等到设置的睡眠时间结束,造成时间浪费,一般调试用
Thread.sleep(long millis);

2、隐式等待

在设置的超时时间范围内不断查找元素,直到找到元素或者超时
如:设置等待时间为5秒,在第3秒找到元素,不再继续等待
优点:相对灵活
缺点:
设置是针对全局的,在WebDriver实例整个生命周期有效,但并不是所有的元素都需要等待。
不能适用条件更复杂的情况,如:元素可点击、元素可见
隐式等待是selenium服务器上在等待

driver.manage.timeouts().implicitlyWait(long time, TimeUnit unit);

3、显示等待

显式等待通常是我们自定义的一段代码,用来等待某个条件发生后再继续执行后续
代码(如找到元素、元素可点击、元素已显示等)
优点: 每隔一段时间500ms扫描一次页面,检查元素是否满足等待结果条件,比如查找
元素,则检查元素是否存在,不存在则继续等待,直到找到或超时。
缺点:该方式不是全局设置,因此特定需要等待的元素可以这样处理,推荐优先使用这一种方法。
显示等待是java脚本客户端在等待

// 等待元素可被点击
WebDriverWait wait = new WebDriverWait(driver,5);    
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[text()='官方']"))).click();

显示等待常用等待方法:

方法等待条件
presenceOfElementLocated页面元素在页面中存在
visibilityOfElementLocated页面元素在页面存在并且可见
elementToBeClickable页面元素是否在页面上可用和可被单击
frameToBeAvailableAndSwitchToIt切换到iframe中,返回值为boolean类型

四、元素定位

在谷歌浏览器中,可以使用F12在console中用(’#custom-bg-preview’),也可以使用 x ( x p a t h 表 达 式 ) 利 用 x p a t h 进 行 定 位 x(xpath表达式)利用xpath进行定位 x(xpath)xpathx(’//[@title=“搜索主题、帖子、用户或分类”]’)``*`

1、css选择器

常用表达式

参考:https://www.w3school.com.cn/cssref/css_selectors.asp

选择器例子描述
.class.classStyle选中所有class="classStyle"的元素
#id#idname选中所有id="idname"的元素
**选择所有元素
tagNameinput选择所有input元素
ele,elediv,input选择所有div和input元素
ele elediv input选中div内所有的input元素
ele>elediv>input选中父类有div的所有input元素
ele+elediv+input紧接再div后面的inout元素
[attribute][name]选择带有name属性的所有元素
[attribute=value]input[name=“x1”]选择name=x1的所有input元素

2、xPath定位

表达式结果
/从根节点选取
//相对位置选取,不考虑当前位置
//*匹配任意节点
父节点
//*[@id=‘hello’]选取id为hello的元素
/bookstore/book[1]bookstore子元素中的第一个book元素
/bookstore/book[last()]bookstore子元素中的最后一个book元素
/bookstore/book[last()-1]bookstore子元素中的倒数第二个book元素
/bookstore/book[position() < 3]bookstore子元素中的最前面两个book元素
/bookstore/book[price<30]bookstore子元素中price大于30的所有book元素

3、xpath轴定位表达式:

轴名称描述
ancestor选取当前节点的所有祖先节点(包括父节点)
parent选取当前节点的父节点
preceding选取当前节点之前的所有节点
following选取当前节点之后的所有节点
preceding-sibling选取当前节点之前的所有兄弟节点
following-sibling选取当前节点之后的所有兄弟节点

轴定位用法:
/轴名称::节点定位
//div/table//td//preceding::a[@name=‘James’]


五、按键事件(Actions)

常用事件:

按键描述
click鼠标左键单击
clikc_and_hold鼠标左键点击后不松开
context_click鼠标右键点击
double_click鼠标左键双击
drag_and_drop把元素拖拽后松开
move_to_element鼠标移动到某个元素
perform()执行按键动作
release松开鼠标左键
send_keys发送某个键到当前聚焦元素
key_down按下键盘上的某个按键
key_up松开按键

示例

     @Test
    void demo01() throws InterruptedException {
        driver.get("http://sahitest.com/demo/clicks.htm");
        // 创建按键对象
        Actions actions = new Actions(driver);
        // 单击对应按键
        WebElement clickEle = driver.findElement(new By.ByXPath("//input[@value='click me']"));
        actions.click(clickEle);
        // 双击对应按键
        WebElement doubleClickEle = driver.findElement(new By.ByXPath("//input[@value='dbl click me']"));
        actions.doubleClick(doubleClickEle);
        // 右键点击按键
        WebElement rightClickEle = driver.findElement(new By.ByXPath("//input[@value='right click me']"));
        actions.contextClick(rightClickEle);
        // 执行按键操作
        actions.perform();
        Thread.sleep(4000);
    }
    
     @Test
    void demo02() throws InterruptedException {
        driver.get("http://sahitest.com/demo/dragDropMooTools.htm");
        // 实现元素拖动
        /*new Actions(driver).dragAndDrop(driver.findElement(new By.ById("dragger")),
                driver.findElement(new By.ByXPath("//div[text()='Item 2']"))).perform();*/
        // 用moveTo来实现拖动
        new Actions(driver).clickAndHold(driver.findElement(new By.ById("dragger")))
                .moveToElement(driver.findElement(new By.ByXPath("//div[text()='Item 2']")))
                .release().perform();
        Thread.sleep(3000);
    }

六、多窗口和多Frame的切换

1、多窗口切换

        //获取所有窗口句柄
        Set<String> windowHandles = driver.getWindowHandles();
        // 遍历个句柄 找到标题与目标窗口标题一致的窗口句柄
        for (String windowHandle:windowHandles
             ) {
            if(!driver.getTitle().equals("titileName")){
                // 切换到目标窗口
                driver.switchTo().window(windowHandle);
            }
        }
    }

2、多Frame切换 与切换窗口类似

    // 获取到frame的id或name 
    driver.switchTo().frame(iFrameIdOrName);
    // 还可以直接获取到frame元素 进行切换
    driver.switchTo().frame(frameElement);
	// 如果外层没有写明的iframe 则可直接跳到ParentFrame
	driver.switchTo().parentFrame(frameElement);

七、对JavaScript元素进行操作

某些特殊情况下,使用selenium的api无法操作页面元素,可以考虑通过执行js来完成。

  • 使用方式1-不传参
	JavascriptExecutor jsExecutor=(JavascriptExecutor) driver;
	jsExecutor.executeScript("jsScript");
  • 使用方式2-传参:
	WebElement element = driver.findElement(By.id("xx"));
	JavascriptExecutor jsExecutor=(JavascriptExecutor) driver;
	jsExecutor.executeScript("arguments[0]...",element);

1、元素属性操作实例

    @Test
    public void test1() throws InterruptedException {
        driver.get("https://www.12306.cn/index/");
        WebElement timeELe = driver.findElement(By.id("train_date"));
        JavascriptExecutor executor = (JavascriptExecutor) driver;
        // 删除只读属性  进行手动输入日期
        executor.executeScript("arguments[0].removeAttribute('readonly')",timeELe);
        timeELe.clear();
        timeELe.sendKeys("2020-07-18");
        Thread.sleep(5000);
    }

    public void chooseSex(String sex) {
        WebElement chooseSex;
        JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
        // 利用js选中性别
        if (sex.equals("男")) {
            chooseSex = waitElementVisible(male);
        } else {
            chooseSex = waitElementVisible(female);
        }
        jsExecutor.executeScript("arguments[0].checked=true", chooseSex);
    }

2、滚动屏幕找到目标元素

页面会分为懒加载和非懒加载方式 两种方式滚动处理不同

    // 从页面顶部滚动到页面底部方法
    executor.executeScript("window.scrollTo(0, document.body.scrollHeight)");
	executor.executeScript("window.scrollBy(0, document.body.scrollHeight)");

    /**
     * 懒加载 循环滚动找到目标元素
     * @throws InterruptedException
     */
    @Test
    public void test1 () throws InterruptedException {
        driver.get("https://sj.qq.com/myapp/category.htm?orgame=1");
        // 懒加载页面 滚动获取页面元素
        // 循环滚动页面  找到需要的元素则停止 或者到了页面底部则不再滚动
        while (true){
            if(driver.getPageSource().contains("抖音短视频")){
                // 找到则点击该元素并退出循环
                System.out.println("找到元素了");
                driver.findElement(By.xpath("//a[text()='抖音短视频']")).click();
                Thread.sleep(6000);
                break;
            }
            // 没找到则继续滚动页面
            // 先获取滚动页面之前的页面数据
            String beforeSource = driver.getPageSource();
            // 进行页面的滚动
            JavascriptExecutor executor = (JavascriptExecutor) driver;
            executor.executeScript("window.scrollTo(0, document.body.scrollHeight)");
            Thread.sleep(5000);
            // 获取滚动页面后的元素
            String afterSource = driver.getPageSource();
            // 查看滚动前和滚动后的页面元素是否一样  一样则代表到达页面底部了  退出循环
            if(beforeSource.equals(afterSource)){
                System.out.println("元素未找到");
                break;
            }
        }

    }
    // 非懒加载无需循环滚动可直接滚动到目标元素位置
    // 滚动到目标元素
    executor.executeScript("arguments[0].scrollIntoViewIfNeeded(true)", targetEle);

    /**
     * 非懒加载  找到指定元素
     */
    @Test
    public void test2() throws InterruptedException {
        driver.get("https://ke.qq.com/");
        WebDriverWait wait = new WebDriverWait(driver,5);
        WebElement targetEle = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[text()='设计·创作']")));
        JavascriptExecutor executor = (JavascriptExecutor) driver;
        // 滚动到目标元素
        executor.executeScript("arguments[0].scrollIntoViewIfNeeded(true)", targetEle);
        Thread.sleep(6000);
    }

八、文件上传

1、input元素可直接用element.sendKey()输入地址方式

	WebElement ele = driver.getElement(By.id("imagUpload"));
	ele.sendKey(filePath);

2、Selenium+Autolt上传文件

某些元素上传文件无法使用sendKey方式进行文件上传需要用到Autolt工具进行上传参考:https://blog.csdn.net/qq_32897143/article/details/82014603

九 弹框处理

弹框的话主要分为3中 alert、confirm确认框和Prompt,下面介绍一下三种弹框的处理

// alert对话框
 public void testAlert() {
     //获取alert对话框
     Alert alert = driver.switchTo().alert();
     //获取对话框文本
     String text = alert.getText();
     //打印警告对话框内容
     System.out.println(text);
     //alert对话框属于警告对话框,我们这里只能接受弹窗
     alert.accept();
 }

// confirm确认框
public void testConfirm() {
    //获取confirm对话框
    Alert alert = driver.switchTo().alert();
    //获取对话框的内容
    String text = alert.getText();
    //打印对话框的内容
    System.out.println(text);
    //点击“确认”按钮
    alert.accept();
    // 点击“取消”按钮
    alert.dismiss();
}

// Prompt
public void testPrompt() {
    //获取prompt对话框
    Alert alert = driver.switchTo().alert();
    //获取对话框的内容
    String text = alert.getText();
    //打印对话框的内容
    System.out.println(text);
    //在弹框内输入信息
    alert.sendKeys("软件测试");
    //点击“确认”按钮,提交输入的内容
    alert.accept();
}

十、除谷歌外的驱动设置

1、火狐浏览器

驱动:
https://github.com/mozilla/geckodriver/releases
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

	WebDriver driver = new FirefoxDriver();
	System.setProperty("webdriver.gecko.driver", "/path/to/geckodriver");

2、Edge

驱动:
https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;

WebDriver driver = new EdgeDriver();
System.setProperty("webdriver.edge.driver", "C:/path/to/MicrosoftWebDriver.exe");

3、IE浏览器

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;

WebDriver driver = new InternetExplorerDriver();
System.setProperty("webdriver.ie.driver", "C:/path/to/IEDriver.exe");

4、safari

● 先在终端运行
safaridriver --enable
● 允许远程自动化
/usr/bin/safaridriver -p 1337</
● 开启驱动

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.safari.SafariDriver;

WebDriver driver = new SafariDriver();

以上就是本人selenium一些基础实战内容,自动化入门的话已经足够了,当然了想要更加深入的进行UI自动化还需要学习pageObject框架、数据驱动等内容。这个后续我也会讲到

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐