• 详解自动化测试之 Selenium


    目录

    1. 什么是自动化

    2.自动化测试的分类

    3. selenium(web 自动化测试工具)

    1)选择 selenium 的原因

    2)环境部署

    3)什么是驱动?

    4. 一个简单的自动化例子

    5.selenium 常用方法

    5.1 查找页面元素(findElement())

    5.2 findElements()方法

    5.3 元素的定位 By 类

    5.4 xpath 路径语言

    6.常见的元素操作

    6.1 输入文本(sendKeys())

    6.2 点击 click

    6.3 提交 submit(通过回车键提交)

    6.4 清除 clear

    6.5 获取文本 (getText())

    6.6 获取属性对应的值 getAttribute

    6.7 获取页面的标题和 URL

    7.窗口

    7.1 窗口的大小设置(manage().window())

    7.2 窗口的切换

    8. 屏幕截图 getScreenshotAs 

    9.等待

    9.1 强制等待

    9.2 隐式等待

    9.3 显示等待

    10.2 浏览器导航

    11. 弹窗

     12.选择框 select

    13.执行脚本 executeScript()

    14.文件上传

    15. 浏览器的参数设置 ChromeOptions


    谷歌浏览器升级到111版本之后,Java版本的selenium和Chrome不兼容

    所以更换浏览器和驱动,使用edge浏览器和edge驱动,因为本篇是在 chrome 浏览器 111 版本之前写的,所以在看到创建 ChromeDriver driver = new ChromeDriver(); 驱动对象的操作,请将这段代码替换为

    1. EdgeOptions options = new EdgeOptions();
    2. options.addArguments("-remote-allow-origins=*");
    3. EdgeDriver driver = new EdgeDriver(options)
    • EdgeOptions 是用于设置 Edge 浏览器的选项的类;
    • options.addArguments("-remote-allow-origins=*") 是设置 Edge 浏览器允许跨域请求的选项,即允许 WebDriver 与浏览器在不同的域之间通信。
    • 如果不使用 EdgeOptions 对象来设置,就无法实现这个功能。而 ChromeDriver 则没有类似的选项需要设置,所以可以直接使用 ChromeDriver driver = new ChromeDriver() 来创建驱动对象但因为版本不兼容就不用 chrome 了。

    我本人使用的是chrome的Version 103.0.5060.134 (Official Build) (64-bit)

    1. 什么是自动化

    作用:通过自动化测试有效减少人力的投入,同时提高了测试的质量和效率

    概念:自动化测试指软件测试的自动化,在预设状态下运行应用程序或者系统,预设条件包括正常和异常,最后评估运行结果。将人为驱动的测试行为转化为机器执行的过程。

    比如,回归测试版本越来越多,版本回归的压力越来越大,仅通过人工测试来回归所有的版本肯定是不现实的,所以我们需要借助自动化测试。

    2.自动化测试的分类

    1. 接口自动化测试
    2. UI自动化测试(界面测试)
    3. 移动端自动化测试
    4. web 端自动化测试

    3. selenium(web 自动化测试工具)

    1)选择 selenium 的原因

    1. 开源免费
    2. 支持多浏览器(Chrome,FireFox,IE浏览器等)
    3. 支持多系统(Linux,Windows,MacOS等等)
    4. 支持多语言(Java,Python,Ruby,JavaScript,Kotlin等等)
    5. selenium 包提供了很多可供选择的API

    2)环境部署

    如果想要使用 selenium 实施 Web 自动化测试,需要的环境是什么:

    Edg浏览器、edg驱动(EdgeDriver)、selenium 工具包

    3)什么是驱动?

    人工测试的情况下,人来手动的打开浏览器,那么驱动就是人力

    对自动化来说,代码不能够直接打开浏览器,需要借助驱动程序才能打开浏览器

    selenium 编写的自动化脚本是如何打开浏览器(selenium Driver 浏览器三者之间的关系)

    驱动要接受 selenium 脚本发送过来的 http 请求并解析 

    4. 一个简单的自动化例子

    首先先导入 selenium 包

    1. org.seleniumhq.selenium
    2. selenium-java
    3. 3.0.0

    简单自动化示例主要包含五个步骤:

    1. 创建驱动实例,创建会话(实例化 ChromeDriver 对象)
    2. 访问网站(对象.get(“网站”)
    3. 查找元素(对象.findElement(By.cssSelector(“#网址元素id”)).sendKeys(“输入内容”)
    4. 操作元素(对象.findElement(By.cssSelector(“#网址元素id”)).click()
    5. 结束会话(对象.quit()
    1. package com.autotest0113;
    2. import org.openqa.selenium.By;
    3. import org.openqa.selenium.WebElement;
    4. import org.openqa.selenium.chrome.ChromeDriver;
    5. import java.util.List;
    6. public class FirstAutotest {
    7. // 在百度网址搜索关键词 “胡歌”
    8. public void yifei() throws InterruptedException {
    9. // 1.打开浏览器
    10. ChromeDriver chromeDriver = new ChromeDriver();
    11. Thread.sleep(3000);
    12. // 2.在浏览器里输入百度网址,访问百度首页
    13. chromeDriver.get("https://www.baidu.com");
    14. Thread.sleep(3000);
    15. // 3.找到百度首页输入框元素,并输入关键词 “胡歌”
    16. chromeDriver.findElement(By.cssSelector("#kw")).sendKeys("刘亦菲");
    17. Thread.sleep(3000);
    18. // 4.找到百度首页 “百度一下” 按钮,并点击一下
    19. chromeDriver.findElement(By.cssSelector("#su")).click();
    20. Thread.sleep(3000);
    21. // 5.结束会话(关闭浏览器)
    22. chromeDriver.quit();
    23. }
    24. }
    1. package com.autotest0113;
    2. import sun.text.normalizer.CharTrie;
    3. public class RunAutoTest {
    4. public static void main(String[] args) throws InterruptedException {
    5. FirstAutotest firstAutotest = new FirstAutotest();
    6. firstAutotest.huge();
    7. }
    8. }

    5.selenium 常用方法

    5.1 查找页面元素(findElement())

    参数:By类(提供通过什么方式来查找元素)

    返回值:webElement

    当元素可以在页面中被正常查找,程序正常退出

    当元素不能在页面中被正常查找,程序执行报错

    5.2 findElements()方法

    参数:By 类(提供通过什么方式来查找元素)

    返回值:List

    1. public void methodTest() {
    2. ChromeDriver driver = new ChromeDriver();
    3. driver.get("https://www.baidu.com");
    4. driver.findElement(By.cssSelector("#kw"));
    5. List elements= driver.findElements(By.className("hotsearch-item"));
    6. for (WebElement element : elements) {
    7. System.out.println(element.getText());
    8. }
    9. driver.findElement(By.cssSelector("#su"));
    10. driver.quit();
    11. }

    5.3 元素的定位 By 类

    5.4 xpath 路径语言

    语法:

    • 层级:/子级 // 跳级
    • 属性:@
    • 函数:contains()....

    自动化里要求元素的定位必须要唯一,但是手动在页面复制 selector 或者 path 元素不一定是唯一的,需要我们进行手动修改到唯一

    6.常见的元素操作

    6.1 输入文本(sendKeys())

    sendKeys,仅适用于文本字段和内容可编辑的元素

    1. driver.get("https://www.baidu.com");
    2. WebElement element = driver.findElement(By.cssSelector("#kw"));
    3. element.sendKeys("豆腐乾净搞方规");
    4. // driver.findElement(By.cssSelector("#kw")).sendKeys("豆腐乾净搞方规");
    5. driver.quit();

    6.2 点击 click

            driver.findElement(By.cssSelector("#su")).click();
    

    6.3 提交 submit(通过回车键提交)

    submit 仅适用于表单元素,selenium 官方不推荐使用 submit,更推荐 click

    1. driver.findElement(By.cssSelector("#kw")).sendKeys("豆腐乾净搞方规");
    2. driver.findElement(By.cssSelector("#su")).submit();
    3. Thread.sleep(2000);
    4. driver.quit();

    6.4 清除 clear

    clear:适用于频繁测试输入是否可以重复输入

    1. // 清除输入框的内容
    2. driver.findElement(By.cssSelector("#kw")).clear();

    6.5 获取文本 (getText())

    1. // 获取文本
    2. String text = driver.findElement(By.cssSelector("#s-top-left > div > a")).getText();
    3. System.out.println("获取到的文本:" + text);

    6.6 获取属性对应的值 getAttribute

    1. // 获取属性的值
    2. String buttonText = driver.findElement(By.cssSelector("#su")).getAttribute("type");
    3. System.out.println("获取到的属性名:" + buttonText);
    4. String buttonText1 = driver.findElement(By.cssSelector("#su")).getAttribute("id");
    5. System.out.println("获取到的属性名:" + buttonText1);
    6. String buttonText2 = driver.findElement(By.cssSelector("#su")).getAttribute("value");
    7. System.out.println("获取到的属性名:" + buttonText2);

    6.7 获取页面的标题和 URL

    1. System.out.println(driver.getTitle());
    2. System.out.println(driver.getCurrentUrl());
    3. driver.findElement(By.cssSelector("#kw")).sendKeys("你好");
    4. driver.findElement(By.cssSelector("#su")).click();
    5. System.out.println(driver.getTitle());
    6. System.out.println(driver.getCurrentUrl());

    7.窗口

    7.1 窗口的大小设置(manage().window())

    最大化,最小化,全屏窗口,手动设置窗口大小

    1. public void windowConTrol() throws InterruptedException {
    2. Thread.sleep(3000);
    3. // 窗口最大化
    4. driver.manage().window().maximize();
    5. Thread.sleep(3000);
    6. // 窗口最小化
    7. driver.manage().window().minimize();
    8. Thread.sleep(3000);
    9. // 全屏
    10. driver.manage().window().fullscreen();
    11. Thread.sleep(3000);
    12. // 手动设置窗口大小
    13. driver.manage().window().setSize(new Dimension(1024,768));
    14. Thread.sleep(2000);
    15. driver.quit();
    16. }

    7.2 窗口的切换

    打开百度首页,点击图片超链接进入到百度图片首页,获取百度图片页面的 “百度一下” 按钮,正常步骤是会报错的

    1. // 窗口切换
    2. driver.get("https://www.baidu.com");
    3. driver.findElement(By.cssSelector("#s-top-left > a:nth-child(6)")).click();
    4. Thread.sleep(3000);
    5. driver.findElement(By.cssSelector("#homeSearchForm > span.s_btn_wr > input"));
    6. driver.quit();

    这是因为虽然我们超过到了百度图片页面,但是当浏览器每次打开一个标签页的时候,会自动的给每个标签页进行标识,这个叫做句柄

    可以通过 getWindowHandles() 获取所有标签页的句柄 Set,然后再通过getWindowHandle() 获取当前页面的句柄,然后遍历所有标签页的句柄,如果当前页的句柄和遍历 Set 中的句柄不同,就通过 switchTo().window() 方法进行窗口切换

    1. public void windowConTrol() throws InterruptedException, IOException {
    2. driver.get("https://www.baidu.com");
    3. driver.findElement(By.cssSelector("#s-top-left > a:nth-child(6)")).click();
    4. Thread.sleep(3000);
    5. // 获取当前页面的句柄
    6. String curHandle = driver.getWindowHandle();
    7. System.out.println("当前页面的句柄:" + curHandle);
    8. // 获取所有标签的句柄
    9. Set handles = driver.getWindowHandles();
    10. for (String handle : handles) {
    11. if(handle != curHandle) {
    12. driver.switchTo().window(handle);
    13. }
    14. }
    15. driver.findElement(By.cssSelector("#homeSearchForm > span.s_btn_wr > input"));
    16. Thread.sleep(3000);
    17. driver.quit();
    18. }

    但是当我们打开了好几个窗口,应该怎么切换?

    自动化基本没有这样的场景,因为当页面多了不会使用这样的页面跳转了,而是直接去访问要测试的页面,所以这里不用考虑太多

    8. 屏幕截图 getScreenshotAs 

    添加 Maven

    1. commons-io
    2. commons-io
    3. 2.6

    需要注意的一点是,当代码执行到查找结果页面元素的时候,页面还没有加载完全,此时程序执行的速度是比,页面渲染的速度更快的,所以要注意在代码中添加等待机制,让页面先渲染一下,再截图。

    1. driver.get("https://www.baidu.com");
    2. driver.findElement(By.cssSelector("#kw")).sendKeys("刘亦菲");
    3. driver.findElement(By.cssSelector("#su")).click();
    4. Thread.sleep(3000);
    5. // 屏幕截图(保存现场)
    6. File srcfile = driver.getScreenshotAs(OutputType.FILE);
    7. // 把屏幕截图好的文件放到指定当前项目的路径下
    8. String filename = "cur.png";
    9. FileUtils.copyFile(srcfile,new File(filename));
    10. driver.findElement(By.cssSelector("#\\31 > div > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > div.title-wrapper_XLSiK > a > div > p > span > span"));
    11. driver.quit();

    9.等待

    • 强制等待
    • 隐式等待
    • 显示等待
    • 流畅等待

    需要注意:显示等待、隐式等待,不能同时使用,同时使用可能会出现意想不到的等待结果

    9.1 强制等待

    程序阻塞进行:Thread.sleep()

    这个就会使 程序阻塞进行,这种方式在自动化测试中会用到,但用的不是特别多,这是因为

    每一个自动化方法就是一个自动化测试用例,比如一个用例需要 10s,100测试用例 1000s,200个用例 2000s,这样耗费时间太多了,只能接受十几秒或几分钟内

    9.2 隐式等待

    隐式等待会作用与 driver 的整个生命周期,隐式等待会一直轮询判断元素算法存在,如果不存在就等待设置好的时间不断的进行轮询,直到元素被找到,在这里设置的是 3s ,在这三秒钟会一直询问是否完成当前行的代码的要求,也就是说每行代码在超过三秒未被执行完全就报错

    1. public class autoTest {
    2. public void waitContro() {
    3. ChromeOptions options = new ChromeOptions();
    4. // 添加隐式等待
    5. driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
    6. driver.get("https://www.baidu.com");
    7. driver.findElement(By.cssSelector("#kw")).sendKeys("刘亦菲");
    8. driver.findElement(By.cssSelector("#su")).click();
    9. driver.findElement(By.cssSelector("#content_left"));
    10. driver.quit();
    11. }
    12. }

    9.3 显示等待

    显示等待会等到设置的命令再进行等待

    1. public class autoTest {
    2. public void webDriverWait(){
    3. ChromeOptions options = new ChromeOptions();
    4. driver.get("https://www.baidu.com");
    5. driver.findElement(By.cssSelector("#kw")).sendKeys("刘亦菲");
    6. driver.findElement(By.cssSelector("#su")).click();
    7. // 添加显示等待
    8. new WebDriverWait(driver,Duration.ofSeconds(5)).until(driver->driver.findElement(By.cssSelector("#content_left")));
    9. driver.quit();
    10. }
    11. }

    10.2 浏览器导航

    浏览器的前进(forward)、后退(back)、刷新(refresh)

    1. public void navigateControl() throws InterruptedException {
    2. ChromeOptions options = new ChromeOptions();
    3. // driver.get("https:///www.baidu.com");
    4. driver.navigate().to("https://www.baidu.com");
    5. Thread.sleep(3000);
    6. // 想要回退到访问百度网址之前的状态
    7. driver.navigate().back();
    8. Thread.sleep(3000);
    9. // 前进,再次进入到百度首页
    10. driver.navigate().forward();
    11. Thread.sleep(3000);
    12. // 刷新一下页面
    13. driver.navigate().refresh();
    14. Thread.sleep(3000);
    15. driver.quit();
    16. }

    11. 弹窗

    弹窗的类型:

    • 警告弹窗
    • 确认弹窗
    • 提示弹窗

     

     处理弹窗的步骤:

    1. 将 driver 作用到弹窗上(切换到弹窗)driver.switchTo.alert()
    2. 选择确认 accept() / 取消 dismiss()(提示弹窗输入文本 sendkeys )
    • 虽然警告弹窗只有确认按钮,但 accept 和 dismiss 都能处理
    • 虽然警告弹窗和确认弹窗都没有输入文本的地方,但如果要执行 alert.sendKeys 代码,也是不会报错的
    1. public void AlertControl() throws InterruptedException {
    2. driver.get("file:///D:/%E6%8F%90%E7%A4%BA%E5%BC%B9%E7%AA%97.html");
    3. Thread.sleep(3000);
    4. driver.findElement(By.cssSelector("body > input[type=button]")).click();//找到选择框元素
    5. Thread.sleep(3000);
    6. // 切换到弹窗进行弹窗处理
    7. Alert alert = driver.switchTo().alert();//创建选择框对象
    8. Thread.sleep(3000);
    9. // 1. 输入
    10. alert.sendKeys("666");
    11. Thread.sleep(3000);
    12. // 2. 点击确认
    13. alert.accept();
    14. Thread.sleep(3000);
    15. // 取消
    16. alert.dismiss();
    17. driver .quit();
    18. }

     12.选择框 select

    选择框的选择方式:

    • 根据文本来选择
    • 根据属性值来选择
    • 根据序号来选择

    1. public void selectControl() throws InterruptedException {
    2. driver.get("file:///D:/%E9%80%89%E6%8B%A9%E6%A1%86.html");
    3. WebElement element = driver.findElement(By.cssSelector("Mathnumber"));
    4. Thread.sleep(3000);
    5. // 1.创建选择框对象
    6. Select select = new Select(element);
    7. Thread.sleep(3000);
    8. //1)根据文本来选择
    9. // select.selectByVisibleText("123");
    10. // //2)根据属性值来选择
    11. // select.selectByValue("234");
    12. // //3)根据序号来选择
    13. // select.selectByIndex(2);
    14. Thread.sleep(3000);
    15. driver.quit();
    16. }

    13.执行脚本 executeScript()

    executeScript(参数:JS)

    1. void scriptControl() throws InterruptedException {
    2. driver.get("https://image.baidu.com/");
    3. Thread.sleep(3000);
    4. // 执行js命令,让页面置底
    5. // driver.executeScript("document.documentElement.scrollTop=500");
    6. // Thread.sleep(3000);
    7. // // 执行js命令,让页面置顶,0 就是顶部
    8. // driver.executeScript("document.documentElement.scrollTop=0");
    9. // Thread.sleep(3000);
    10. driver.executeScript("var ss = document.querySelector(\"#kw\");ss.value = '刘亦菲';");//通过js代码来实现搜索
    11. Thread.sleep(3000);
    12. driver.quit();
    13. }

    14.文件上传

    sendKeys("文件路径+文件")

    1. void fileUploadControll() throws InterruptedException {
    2. driver.get("file:///D:/%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0.html");
    3. driver.findElement(By.cssSelector("#avatar")).sendKeys("D:\\Desktop\\CSDN封面图片\\u=1008366999,1348072899&fm=253&fmt=auto&app=120&f=JPEG.webp");
    4. Thread.sleep(3000);
    5. driver.quit();
    6. }

    15. 浏览器的参数设置 ChromeOptions

    无头模式:在实际工作中,测试人员将自动化部署在机器上自动的执行,测试人员看不到测试过程,而是直接查看自动化执行的结果

    有头模式:就是程序在自动的测试,我们是可以看到执行测试的过程界面

    浏览器的参数设置需要在创建浏览器对象之前

    1. void paramsControl(){
    2. // 百度搜索刘亦菲
    3. // 先创建选项对象,然后再设置浏览器参数
    4. ChromeOptions options = new ChromeOptions();
    5. options.addArguments("-headless");
    6. // options.addArguments("--remote-allow-origins=*");
    7. ChromeDriver driver = new ChromeDriver(options);
    8. driver.get("https://image.baidu.com/");
    9. driver.executeScript("var ss = document.querySelector(\"#kw\");ss.value = '刘亦菲';");
    10. }

  • 相关阅读:
    JUC-3-并发锁
    Linux虚拟机 & Docker 安装 RabbitMQ
    刷题神器!把LeetCode题目生成卡片;苏黎世联邦理工『数据科学数学基础』课程;深度学习实例锦囊(含代码) ;前沿论文 | ShowMeAI资讯日报
    Eureka的使用场景
    II.-递归
    计算机毕业设计选题推荐-大学生班级管理系统-Python项目实战
    postgresql之page分配管理(一)
    视频流远程控制启动教程
    包装机(栈和队列的应用)
    棒球场上的礼仪·野球1号位
  • 原文地址:https://blog.csdn.net/m0_62976995/article/details/134341063