Java + Seleium4.X + TestNG自动化技术

系列文章目录


文章目录

  • 系列文章目录
  • 前言
  • [一、 Java版Selenium自动化测试框架介绍和原理](#一、 Java版Selenium自动化测试框架介绍和原理)
    • [1.1 什么是Seleium](#1.1 什么是Seleium)
    • [1.2 特点](#1.2 特点)
    • [1.3 注意点](#1.3 注意点)
  • [二、安装Seleium+Chrome环境 + 创建Maven项目](#二、安装Seleium+Chrome环境 + 创建Maven项目)
    • [2.1 安装Seleium + Chrome环境](#2.1 安装Seleium + Chrome环境)
    • [2.2 Maven环境](#2.2 Maven环境)
  • [三、Selenium4.X UI元素定位实战](#三、Selenium4.X UI元素定位实战)
    • [3.1 ID选择器](#3.1 ID选择器)
    • [3.2 Name选择器](#3.2 Name选择器)
    • [3.3 linkText选择器](#3.3 linkText选择器)
    • [3.4 partialLinkText选择器](#3.4 partialLinkText选择器)
    • [3.5 Class选择器](#3.5 Class选择器)
    • [3.6 CSS选择器](#3.6 CSS选择器)
    • [3.7 TagName选择器](#3.7 TagName选择器)
    • [3.8 XPath选择器](#3.8 XPath选择器)
  • [四、 WebDriver基础操作](#四、 WebDriver基础操作)
    • [4.1 WebDriver对象API操作](#4.1 WebDriver对象API操作)
    • [4.2 WebElement对象API操作](#4.2 WebElement对象API操作)
    • [4.3 浏览器API操作](#4.3 浏览器API操作)
    • [4.4 鼠标事件操作](#4.4 鼠标事件操作)
    • [4.5 模拟键盘输入操作](#4.5 模拟键盘输入操作)
    • [4.6 显示等待和隐式等待](#4.6 显示等待和隐式等待)
  • 五、Selenium4.X窗口、下拉框操作
    • [5.1 Selenium4.X的窗口切换实战](#5.1 Selenium4.X的窗口切换实战)
    • [5.2 项目实战](#5.2 项目实战)
    • [5.3 Selenium4.X的快照截图](#5.3 Selenium4.X的快照截图)
    • [5.4 下拉框Select处理](#5.4 下拉框Select处理)
    • [5.5 弹窗Alert处理](#5.5 弹窗Alert处理)
  • 六、Selenium4.X自动化测试多案例实战
    • [6.1 UI自动化测试用例编写](#6.1 UI自动化测试用例编写)
    • [6.2 豆瓣网自动化测试实战](#6.2 豆瓣网自动化测试实战)

前言

  • Selenium是最受欢迎的Web应用程序自动化测试工具之一。
  • 通过学习Selenium,可以编写自动化测试脚本,用于自动执行各种任务,例如验证功能、测试用户界面、模拟用户交互
  • 大大提高测试效率,减少手动测试的工作量

一、 Java版Selenium自动化测试框架介绍和原理

1.1 什么是Seleium

Selenium自动化测试框架

  • 是一个用于Web应用程序测试的自动化测试工具

  • 支持多种浏览器(如Chrome、Firefox、Safari等)和操作系统(如Windows、Linux、macOS等),

  • 提供了一个丰富的API,允许用户模拟真实用户的交互行为,如点击、输入、提交等

  • 官网:https://www.selenium.dev

1.2 特点

  • 跨平台与多浏览器支持:Selenium可以在不同的操作系统和浏览器上运行,提供了广泛的兼容性
  • 开源与免费:Selenium是一个开源项目,用户可以免费地使用其中的工具和库
  • 强大的API:Selenium提供了丰富的API,允许用户进行复杂的页面操作和验证
  • 支持自动化测试:Selenium可以模拟真实用户的交互行为,从而进行自动化测试,提高测试效率
  • 集成与扩展性:可以与其他测试工具(如Jenkins)和编程语言(如Python、Java等)集成,提供了很好的扩展性

1.3 注意点

  • 环境搭建浏览器版本和驱动版本对应关系
    • 安装Selenium库,不同语言采用不同依赖包安装
    • 下载与浏览器对应的WebDriver,如ChromeDriver或GeckoDriver,并确保它们与浏览器版本匹配
    • 浏览器版本一定要和驱动版本一一对应,不然存在不兼容问题

二、安装Seleium+Chrome环境 + 创建Maven项目

2.1 安装Seleium + Chrome环境

前置:环境使用的JDK21版本+Maven3.8 +IDEA旗舰版

  • 驱动相关注意事项(如果驱动版本太新,可以降低版本验证)

    • 浏览器版本(保证驱动版本和浏览器版本前三位相同 134.0.6998.XXX

2.2 Maven环境

配置环境不多说,如下参考文档
手把手教你配置Maven环境并用IDEA创建一个Maven工程

  • 添加依赖
java 复制代码
  <dependencies>
        <!-- Selenium -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.10.0</version>
        </dependency>
   </dependencies>

添加之后爆红可以刷新加载

三、Selenium4.X UI元素定位实战

主程序入口,前置步骤,后续案例都在这里调用

java 复制代码
public class Main {
    public static void main(String[] args) throws Exception {
        //指定驱动路径
        System.setProperty("webdriver.chrome.driver","D:\\developer_tools\\Broswer_Driver\\Chromedriver\\chromedriver-win64\\chromedriver.exe");
        // 谷歌驱动
        ChromeOptions options = new ChromeOptions();
        // 允许所有请求
        options.addArguments("--remote-allow-origins=*");
        WebDriver webDriver = new ChromeDriver(options);
		//窗口最大化
        webDriver.manage().window().maximize();
        }

3.1 ID选择器

元素定位方法说明

  • 在使用webdriver进行元素定位时,通常用findElementfindElements方法结合By类返回元素句柄来定位元素

  • findElement() 方法返回一个元素, 如果没有找到,会抛出一个异常 NoElementFindException()

  • findElements()方法返回多个元素, 如果没有找到,会返回空数组, 不会抛出异常

  • ID元素定位

    • HTML中的每个元素都可以设置一个唯一的ID属性。通过该属性 可以精确地定位到页面上的某个元素
    • 在Selenium中,使用findElement(By.id("id的值"));方法可以根据元素的ID进行定位
  • 注意事项

    • ID应该是唯一的,因此在页面上不应该有两个或更多的元素具有相同的ID
    • 如果元素的ID发生了改变,或者页面上没有该ID的元素,那么定位会失败
java 复制代码
public static void idTest(WebDriver webDriver) throws InterruptedException {
        webDriver.get("https://www.baidu.com");

        TimeUnit.SECONDS.sleep(2);

        WebElement element = webDriver.findElement(By.id("kw"));
        element.sendKeys("csdn");
    }

3.2 Name选择器

  • Name元素定位

    • 在HTML中,某些元素(如<input>, <button>, <select>等)可以设置一个Name属性
    • 虽然Name属性不必唯一,但在某些情况下,它可以用于定位特定的元素
    • 在Selenium中,使用findElement(By.name("name的值"));方法可以根据元素的Name属性进行定位
  • 注意事项

    • Name属性不必唯一,可能存在多个元素具有相同的Name,默认只会返回第一个匹配的元素
    • 如果页面上的元素没有设置Name属性,或者Name属性的值发生了改变,那么定位会失败
java 复制代码
public static void nameTest(WebDriver webDriver) throws InterruptedException {
        webDriver.get("https://www.baidu.com");

        TimeUnit.SECONDS.sleep(2);

        WebElement element = webDriver.findElement(By.name("wd"));
        element.sendKeys("csdn");

    }

3.3 linkText选择器

Selenium4元素定位之链接方式

  • 通过超链接上的文字信息来定位元素,包括通过链接的全部文字和部分文字进行定位

  • 链接的全部文字定位

    • 当链接的完整文本是唯一的,想要定位这个链接时,可以使用By.linkText方法
    • By.linkText("完整的链接文本")用于查找页面上文字完全匹配的链接
java 复制代码
 public static void LinkTest(WebDriver webDriver) throws InterruptedException {
        webDriver.get("https://www.baidu.com");

        TimeUnit.SECONDS.sleep(2);
        WebElement element = webDriver.findElement(By.linkText("新闻"));
        String text = element.getText();
        System.out.println(text);

        element.click();
    }

3.4 partialLinkText选择器

链接的部分文字定位

  • 当链接的文本不是唯一的,想基于部分文本来定位链接时,可以使用By.partialLinkText方法
  • By.partialLinkText("部分链接文本")用于查找页面上文字包含指定文本的链接
java 复制代码
 public static void partialLinkTest(WebDriver webDriver) throws InterruptedException {
        webDriver.get("https://www.baidu.com");

        TimeUnit.SECONDS.sleep(2);

        WebElement element = webDriver.findElement(By.partialLinkText("贴吧"));
        element.click();

    }

3.5 Class选择器

  • Class方式
    • 通过属性class定位元素,查找一个或一组显示效果相同的页面元素
    • driver.findElement(By.className('class属性'));
java 复制代码
 public static void classTest(WebDriver webDriver) throws InterruptedException {
        webDriver.get("https://www.baidu.com");

        TimeUnit.SECONDS.sleep(2);

        List<WebElement> elements = webDriver.findElements(By.className("title-content-title"));
        System.out.println("size ===="  + elements.size());

        for (WebElement element : elements) {
            String text = element.getText();
            System.out.println(text);
        }
    }

3.6 CSS选择器

Selenium4元素定位之CSS选择器方式

  • selenium中的css定位,是通过css选择器来定位到具体元素,css选择器来自于css语法
  • css相较与xpath选择元素:表达式更加简洁,一般情况css的运行速度是优于xpath的
  • 常见的选择器包括:
    • 标签:直接使用标签名,如下列:p
    • 类(class):"."(英文句号)+class值
    • id:"#"+id值*
    • 通配符:意为匹配所有元素, 用"*"表示

使用CSS选择器定位元素案例说明

java 复制代码
// 通过类名定位  
WebElement elementByClassName = driver.findElement(By.cssSelector(".class-name"));  
// 通过ID定位(虽然通常使用By.id更直接)  
WebElement elementById = driver.findElement(By.cssSelector("#element-id"));  
// 通过标签名定位  
WebElement elementByTagName = driver.findElement(By.cssSelector("div"));  
// 通过属性定位  
WebElement elementByAttribute = driver.findElement(By.cssSelector("input[name='input-name']")); 

案例

java 复制代码
public static void cssTest(WebDriver webDriver) throws InterruptedException {
        webDriver.get("https://www.baidu.com");

        TimeUnit.SECONDS.sleep(2);

        List<WebElement> elements = webDriver.findElements(By.cssSelector("#s-hotsearch-wrapper > div > a.hot-title > div"));
        System.out.println("size ===" + elements.size());

        for (WebElement element : elements) {
            String text = element.getText();
            System.out.println(text);
        }
    }

3.7 TagName选择器

Selenium4元素定位之TagName选择器方式

  • 标签名定位方式主要用于匹配多个页面元素的情况,将找到的页面元素对象进行计数、遍历

  • HTML的本质就是通过tag来定义实现不同的功能,每一个元素本质上也是一个tag

  • 通过方法driver.findElement(By.tagName("标签名称")); 进行操作

java 复制代码
public static void tarNameTest(WebDriver webDriver) throws InterruptedException {
        webDriver.get("https://www.baidu.com");
        TimeUnit.SECONDS.sleep(2);

        List<WebElement> elements = webDriver.findElements(By.tagName("a"));
        for (WebElement element : elements) {
            String text = element.getText();
            String href = element.getAttribute("href");
            System.out.println(text);
        }
    }

3.8 XPath选择器

Selenium4.X元素定位之XPath案例实操**

  • 什么是XPath

    • XPath(XML Path Language)是一种在XML文档中查找信息的语言,也可以用于HTML
    • XPath提供了非常强大的定位能力,可以定位到几乎任何元素

1.路径

1). 绝对路径:

语法:以单斜杠开头逐级开始编写,不能跳级。如:/html/body/div/p[1]/input

2). 相对路径

语法:以双斜杠开头,双斜杠后边跟元素名称,不知元素名称可以使用*代替。

如: //input 与 // *

路径结合属性

语法:在Xpath中,所有的属性必须使用@符号修饰 如://[@id='id值']
路径结合逻辑(多个属性)
语法://
[@id="id值" and @属性='属性值']

路径结合层级

语法://*[@id='父级id属性值']/input

java 复制代码
 public static void xpathTest(WebDriver webDriver) throws InterruptedException {
        webDriver.get("https://www.baidu.com");
        TimeUnit.SECONDS.sleep(2);
        List<WebElement> elements = webDriver.findElements(By.xpath("//*[@id=\"head\"]"));
        for (WebElement element : elements) {
            String text = element.getText();
            System.out.println(text);
        }
    }

四、 WebDriver基础操作

4.1 WebDriver对象API操作

方法 描述
get(String url) 访问目标 url 地址,打开网页
getCurrentUrl() 获取当前页面 url 地址
getTitle() 获取页面标题
getPageSource() 获取页面源代码
close() 关闭浏览器当前打开的窗口
quit() 关闭浏览器所有的窗口
findElement(by) 查找单个元素
findElements(by) 查到元素列表,返回一个集合
getWindowHandle() 获取当前窗口句柄
getWindowHandles() 获取所有窗口的句柄
java 复制代码
 public static void webdriverTest(WebDriver webDriver) throws InterruptedException {
        webDriver.get("https://www.baidu.com");
        TimeUnit.SECONDS.sleep(2);
        String currentUrl = webDriver.getCurrentUrl();
        System.out.println(currentUrl);

        String title = webDriver.getTitle();
        System.out.println("title: " + title);

        String pageSource = webDriver.getPageSource();
        System.out.println(pageSource);

        TimeUnit.SECONDS.sleep(2);
        webDriver.close();
        webDriver.quit();

        webDriver.findElement(By.id("kw")).sendKeys("csdn");

        Set<String> windowHandles = webDriver.getWindowHandles();
        for (String handle : windowHandles) {
            System.out.println("窗口句柄" + handle);
        }
    }

4.2 WebElement对象API操作

元素对象API操作语法

  • WebElement对象常用API
方法 说明
click 点击对象
sendKeys 在对象上模拟按键输入
clear 清除对象输入的文本内容
submit 提交,比如表单对象
getAttribute 获取元素的指定属性
getText 用于获取元素的文本信息
java 复制代码
 public static void webElementTest(WebDriver webDriver) throws InterruptedException {
        webDriver.get("https://www.baidu.com");
        TimeUnit.SECONDS.sleep(2);

        webDriver.findElement(By.id("kw")).sendKeys("博客园");
        TimeUnit.SECONDS.sleep(2);

        webDriver.findElement(By.id("kw")).clear();
        TimeUnit.SECONDS.sleep(2);

        webDriver.findElement(By.id("kw")).sendKeys("csdn");
        TimeUnit.SECONDS.sleep(2);
        webDriver.findElement(By.id("su")).click();

    }

4.3 浏览器API操作

  • 需求

    • 浏览器操作网页,有前进、后退,不同网页直接切换,窗口最大化、刷新等
    • 通过Selenium的api完成上述的操作案例
  • 浏览器案例

    • API语法
    方法 说明
    back 模拟浏览器后退按钮
    forward 模拟浏览器前进按钮
    refresh 刷新页面(F5)
    maximize 浏览器最大化
    setSize 浏览器宽高
    manage( ).window( ).setSize( ) 设置浏览器的大小
java 复制代码
public static void browserTest(WebDriver webDriver) throws InterruptedException {
        webDriver.get("https://www.baidu.com");
        TimeUnit.SECONDS.sleep(2);

        webDriver.findElement(By.id("kw")).sendKeys("博客园");

        webDriver.findElement(By.id("su")).click();
        TimeUnit.SECONDS.sleep(2);

        WebDriver.Navigation navigate = webDriver.navigate();
        navigate.refresh();
        TimeUnit.SECONDS.sleep(2);
        navigate.back();

        TimeUnit.SECONDS.sleep(2);
        navigate.forward();

4.4 鼠标事件操作

  • Selenium的鼠标事件

    • 鼠标操作主要是通过Actions类来实现的,该类提供了一系列模拟鼠标操作的方法
    • 包括有 右击、双击、悬停、拖动等
  • 鼠标案例API语法

    方法 说明
    contextClick( ) 右击
    clickAndHold( ) 鼠标点击并控制
    doubleClick( ) 双击
    dragAndDrop( ) 拖动
    release( ) 释放鼠标
    perform( ) 执行所有Actions中存储的行为
java 复制代码
  public static void mouseTest(WebDriver webDriver) throws InterruptedException {
        webDriver.get("https://www.baidu.com");
        TimeUnit.SECONDS.sleep(2);

        webDriver.findElement(By.cssSelector("#kw")).sendKeys("csdn");
        TimeUnit.SECONDS.sleep(2);
        webDriver.findElement(By.cssSelector("#su")).click();
        TimeUnit.SECONDS.sleep(2);

        WebElement element = webDriver.findElement(By.cssSelector("#s_tab_inner > a.s-tab-item.s-tab-item_1CwH-.s-tab-note_2zG_i.s-tab-note > span"));
        TimeUnit.SECONDS.sleep(2);
        //鼠标右键
        Actions action = new Actions(webDriver);
        action.moveToElement(element).contextClick().perform();
    }

4.5 模拟键盘输入操作

什么是模拟键盘

  • 利用ActionsKeys类来模拟键盘操作,包括文本输入、按键和组合键序列,增强自动化脚本的用户交互能力

  • Keys枚举提供了方便的表示键盘上按键的方法,而Actions类则用于构建复杂的交互序列

  • 这两者结合,允许在Web自动测试中模拟几乎任何类型的键盘操作

发送特殊字符

  • sendKeys 使用Keys类中的常量,可以发送特殊字符或按键事件,sendKeys接收可变参数

sendKeys(Keys.BACK_SPACE) 回格键(BackSpace)、sendKeys(Keys.SPACE) 空格键 (Space)

sendKeys(Keys.TAB) 制表键 (Tab)、sendKeys(Keys.ESCAPE) 回退键(Esc)

sendKeys(Keys.ENTER) 回车键(Enter)、sendKeys(Keys.F1) 键盘 F1

sendKeys(Keys.CONTROL,'a') 全选(Ctrl+A)、sendKeys(Keys.CONTROL,'c') 复制(Ctrl+C)

sendKeys(Keys.CONTROL,'x') 剪切(Ctrl+X)、sendKeys(Keys.CONTROL,'v') 粘贴(Ctrl+V)

java 复制代码
 public static void keyboardTest(WebDriver webDriver) throws InterruptedException {
        webDriver.get("https://www.baidu.com");
        TimeUnit.SECONDS.sleep(2);

        WebElement element = webDriver.findElement(By.cssSelector("#kw"));
        element.sendKeys("csdny");
        TimeUnit.SECONDS.sleep(2);

        //删除一个字符
        element.sendKeys(Keys.BACK_SPACE);
        TimeUnit.SECONDS.sleep(2);

        element.sendKeys(Keys.SPACE);
        element.sendKeys("博客");

        element.sendKeys(Keys.ENTER);


    }

4.6 显示等待和隐式等待

  • 需求

    • Web应用通常通过异步加载(如Ajax)来动态更新页面内容,页面元素可能不是立即可用的

    • 当自动化测试脚本尝试访问或操作这些元素时,如果没有等待机制,可能会遇到定位失败、元素状态不正确等异常

    • Selenium4等待主要解决以下问题:

      • 元素加载延迟

        • 当页面上的某些元素是通过异步请求(如Ajax)加载的,这些元素可能不会立即出现在DOM中
        • 网络波动或服务器响应延迟,页面上的某些内容可能需要一些时间才能加载
        • 如果没有等待机制,测试脚本可能会在元素实际可用之前访问它,导致定位失败
      • 依赖关系

        • 测试脚本中的操作可能依赖于前一步的结果或内容
        • 例如,一个表单提交后,可能需要等待新页面加载完成才能继续执行后续操作
      • 页面更新

        • JavaScript可能会动态更改页面内容,如添加、删除或修改元素

        • 如果没有等待,测试脚本可能会错过这些变化,导致测试失败

  • Selenium 等待元素出现的方式有以下三种

    • 强制等待
      • 即线程休眠,在代码中强制当前正在执行的线程休眠(暂停执行)不管元素有没出现都固定时间 TimeUnit.SECONDS.sleep(2);
    • 显式等待(Explicit Wait)
      • 通俗说就是死等,不灵活的等待,在指定的时间内一定要等到某个元素的出现或可操作的状态
      • 如果等不到,就一直等,直到在规定的时间之内都要操作的元素仍没找到,就抛出异常
      • 可以针对特定的元素或一组元素进行等待,提供了更灵活的等待机制,可以等待复杂的条件
    • 隐式等待 (Implicit Wait)
      • 设置全局等待时间,全部查找都会生效,驱动初始化后就可以配置,在指定时间内轮询DOM,直到找到元素或超时
      • 一旦设置,在整个WebDriver对象实例的生命周期内都有效
      • 适用于等待整个页面加载完毕

隐式等待案例

java 复制代码
 public static void impwaitTest(WebDriver webDriver){
        webDriver.get("https://www.baidu.com");

        //隐式等待
        webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
        //使用一个不存在的元素id
        WebElement element = webDriver.findElement(By.id("sd"));
        element.sendKeys("csdn");
    }

显示等待案例

java 复制代码
public static void waitTest(WebDriver webDriver){
        webDriver.get("https://www.baidu.com");

        //显示等待
        WebDriverWait wait = new WebDriverWait(webDriver, Duration.ofSeconds(10));

        wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("kw")));

        WebElement element = webDriver.findElement(By.id("kw"));
        element.sendKeys("csdn");

    }

五、Selenium4.X窗口、下拉框操作

5.1 Selenium4.X的窗口切换实战

  • 需求

    • 自动化测试过程中会有打开不同网页的操作
    • 网页操作时会打开新窗口,不同窗口需要如何进行切换?
  • 不同窗口的切换

    • 自动化脚本通过识别浏览器窗口的属性用句柄handle来识别不同窗口
    • 窗口句柄handle是窗口的唯一标识,是窗口的唯一ID
    • 通过 webDriver.getWindowHandles() 获取窗口全部具柄
    • 默认是第一个打开窗口,通过 webDriver.switchTo().window() 传入某个窗口句柄,切换到对应窗口
java 复制代码
public static void windowTest(WebDriver webDriver)throws  InterruptedException {
        webDriver.get("https://www.baidu.com");
        //隐式等待
        webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));

        webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
        //获取全部窗口的句柄
        Set<String> windowHandles = webDriver.getWindowHandles();
        String newHandle = "";
        for (String windowhandle : windowHandles) {
            System.out.println("windowhandle: " + windowhandle);
            //记录最后一个句柄
            newHandle = windowhandle;
        }
        //切换窗口  如果没调用切换 则对应的页面操作会失败
        webDriver.switchTo().window(newHandle);

        String text = webDriver.findElement(By.cssSelector("#headline-tabs > ul > li > a")).getText();
        System.out.println("text: " + text);

    }

5.2 项目实战

什么是 iframe

  • iframe(Inline Frame)是HTML文档中的一个元素,允许在当前HTML页面中嵌入另一个HTML页面

  • 其基本的用途是将另一个HTML文档嵌入到主文档中

  • 就是一个网页可以嵌套到另一个网页中,可以嵌套很多层

  • 使用selenium 操作浏览器时,如果需要操作iframe中的元素,首先需要切换到对应的内联框架中

  • Selenium 给提供了三个重载的方法,进行操作iframe
java 复制代码
// 方法一:通过 iframe的索引值,在页面中的位置
webDriver.switchTo().frame(index);
// 方法二:通过 iframe 的name 或者id
webDriver.switchTo().frame(nameOrId);
// 方法三:通过iframe 对应的webElement        
webDriver.switchTo().frame(frameElement);
java 复制代码
public static void iframeTest(WebDriver webDriver)throws InterruptedException {
        webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));

        webDriver.get("https://www.126.com");
        WebElement element = webDriver.findElement(By.xpath("//div[@class='g-bd cnt-box-include']/div[@class='g-bd']/div[@class='m-cnt']"));

        webDriver.switchTo().frame(element);

        //定位账号输入框
        webDriver.findElement(By.xpath("//div[@class='u-input box']/input[@name='email']")).sendKeys("lao123");
        webDriver.findElement(By.xpath("//div[@class='inputbox']/div[@class='u-input box']/input[@name='password']")).sendKeys("123456");

    }

5.3 Selenium4.X的快照截图

  • 什么是Selenium的快照截图

    • 自动化测试的时候,没有人工进行观看,用例执行失败如何进行发现?
    • 如果遇到有错误信息等,如何保存当前页面的截图,方便后续排查?
    • 快照截图功能是指Selenium自动化测试工具在测试过程中捕获浏览器窗口当前显示内容的图像
    • 是Selenium在测试或调试过程中,为了保存当前浏览器窗口的可见内容而提供的一种功能
    • 通常用于分析页面布局、验证页面元素的存在或状态,在测试失败时捕获页面状态以供后续分析
  • 网页快照截图

    • 通过API (TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE)
java 复制代码
 public static void screenTest(WebDriver webDriver)throws Exception {
        webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));

        webDriver.get("https://www.baidu.com");
        webDriver.findElement(By.id("kw")).sendKeys("博客园");

        //点击搜索
        webDriver.findElement(By.cssSelector("#su")).click();
        TimeUnit.SECONDS.sleep(5);
        File file = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);

        //存储本地
        String filPath = "C:\\Users\\岳不群\\Desktop\\class\\screen.png";
        File target = new File(filPath);

        //保存到本地
        try(FileOutputStream out = new FileOutputStream(target);
            FileInputStream inp = new FileInputStream(file);){
            byte[] buffer = new byte[1024];
            int total = 0;
            while ((total = inp.read(buffer))!=-1){
                out.write(buffer,0,total);
            }

    }
        }

5.4 下拉框Select处理

自动化测试里面的下拉框操作

  • 在网页设计中,下拉框(也被称作下拉列表或者选择框)是一种用户界面控件

  • 下拉框通常在被点击时显示其包含的所有选项列表,在用户选择某一选项后,列表会收回,只显示用户所选择的那个选项

  • 如果一个页面元素是一个下拉框(select),对应下拉框的操作,selenium有专门的类 Select 进行处理

  • 其中包含了单选和多选下拉框的各种操作,如获得所有的选项、选择某一项、取消选中某一项、是否是多选下拉框等

  • 构造函数:
    • Select(WebElement element): 创建一个新的 Select 对象,用于操作指定的 元素
  • 选择选项的方法:
    • void selectByIndex(int index): 根据索引选择选项(索引从 0 开始)
    • void selectByValue(String value): 根据选项的 value 属性值选择选项
    • void selectByVisibleText(String text): 根据选项的可见文本选择选项
  • 取消选择选项的方法 (适用于多选下拉框):
    • void deselectAll(): 取消选择所有已选中的选项
    • void deselectByIndex(int index): 根据索引取消选择选项
    • void deselectByValue(String value): 根据选项的 value 属性值取消选择选项
    • void deselectByVisibleText(String text): 根据选项的可见文本取消选择选项
  • 获取选项的方法:
    • List getOptions(): 获取下拉框中的所有选项。
    • List getAllSelectedOptions(): 获取下拉框中所有已选中的选项
    • WebElement getFirstSelectedOption(): 获取下拉框中第一个已选中的选项
  • 检查是否为多选下拉框:
    • boolean isMultiple(): 返回下拉框是否支持多选
java 复制代码
public static void selectTest(WebDriver webDriver) throws InterruptedException {
        webDriver.get("file:///C:/Users/%E5%B2%B3%E4%B8%8D%E7%BE%A4/Desktop/select.html");

        //创建一个显示等待
        WebDriverWait wait = new WebDriverWait(webDriver, Duration.ofSeconds(10));
        wait.until(ExpectedConditions.elementToBeClickable(By.id("mySelect")));

        //找到元素再点击
        WebElement element = webDriver.findElement(By.id("mySelect"));
        element.click();

        Select select = new Select(element);
        List<WebElement> options = select.getOptions();
        for (WebElement option : options) {
            System.out.println(option.getText());
        }

        TimeUnit.SECONDS.sleep(2);

        //根据选项的所见文本进行选择
        select.selectByVisibleText("csdn");

        //根据索引位置选择
        select.selectByIndex(1);

        TimeUnit.SECONDS.sleep(2);

        select.selectByValue("5");

        System.out.println(select.isMultiple());

    }

5.5 弹窗Alert处理

什么是Alert

  • 操作alert、confirm弹出框,可以通过Alert 对象来进行操作,Alert类包含了确认、取消、输入和获取弹出窗内容。
  • Alert对应属性和方法
方法 描述
alert.getText() 获取弹出框内容
alert.accept() 接受弹窗的提示,相当于点击确认按钮
alert.dismiss() 取消提示窗
alert.sendKeys(String s) 给弹窗输入内容

网页中常用的弹出框有三种:

  • alert 警告框
  • confirm 确认框
  • prompt 提示框

同弹窗使用流程

  • 触发弹出框

    • 弹出框是由页面上的某些操作触发的,比如点击一个按钮或执行某些JavaScript代码。
    • 需要确保在执行下一步之前弹出框已经显示
  • 切换到弹出框

    • 使用WebDriverswitchTo().alert()方法来切换到弹出框
    • 返回一个Alert对象,可以通过这个对象与弹出框进行交互

Alert alert = driver.switchTo().alert();

处理alert弹出框

  • alert弹出框通常只包含一条消息和一个"确定"按钮,可以使用alert.accept()方法来点击"确定"按钮

alert.accept();

处理confirm弹出框

  • confirm弹出框包含一个消息、一个"确定"按钮和一个"取消"按钮
  • 可以使用alert.accept()来点击"确定"按钮,或者使用alert.dismiss()来点击"取消"按钮
java 复制代码
// 点击"确定"按钮  
alert.accept();  
  
// 或者点击"取消"按钮  
alert.dismiss();
java 复制代码
 public static void alertTest(WebDriver webDriver) throws InterruptedException {
        webDriver.get("file:///C:/Users/%E5%B2%B3%E4%B8%8D%E7%BE%A4/Desktop/select.html");

        //创建显示等待
        WebDriverWait wait = new WebDriverWait(webDriver, Duration.ofSeconds(2));
        wait.until(ExpectedConditions.elementToBeClickable(By.id("alert_btn"))).click();

        //处理alert
        Alert alert = webDriver.switchTo().alert();
        System.out.println(alert.getText());

        TimeUnit.SECONDS.sleep(2);
        alert.accept();

        //处理confirm
        webDriver.findElement(By.id("confirm_btn")).click();
        //切换
        Alert confirm = webDriver.switchTo().alert();
        TimeUnit.SECONDS.sleep(2);
        confirm.dismiss();

    }

六、Selenium4.X自动化测试多案例实战

6.1 UI自动化测试用例编写

UI自动化测试用例编写规范

  • 一个脚本对应一个完整场景
    • 每个自动化测试脚本应覆盖一个完整的用户场景,例如从用户登录到退出系统的整个过程。
  • 单一功能点验证
    • 每个脚本应专注于验证一个特定的功能点,避免在一个脚本中验证多个功能。
  • 正向逻辑验证为主
    • 优先验证功能的正向逻辑,避免过度考虑逆向逻辑的验证,以减少脚本的复杂性和脆弱性。
  • 脚本独立性
    • 确保每个脚本都是独立的,不依赖于或影响其他脚本的执行。
  • 数据还原
    • 如果测试过程中修改了数据,测试结束后应对数据进行还原,保持测试环境的清洁。
  • 验证点明确
    • 在脚本中只针对明确的验证点进行验证,避免对整个脚本的每一步都进行验证。
  • POM(Page Object Model)结构
    • 设计遵循POM结构,将用例层、业务逻辑层和Page层明确分离。
  • 页面设计规则
    • 每个页面一个类,类名以Page结尾;页面辅助控件和逻辑设计为接口,并提供默认实现。
  • 参数封装
    • 除简单逻辑外,业务逻辑的参数使用Java Bean和枚举封装,以适应产品设计的变化。
  • 状态码和文案
    • 使用枚举定义状态码、产品特定文案等,以规范入参

6.2 豆瓣网自动化测试实战

  • 测试用例一:用户登录功能

    • 测试目标:验证用户登录功能的正确性。
    • 前置条件:豆瓣网已注册用户,存在有效账号和密码。
    • 测试步骤
      • 打开豆瓣网首页。
      • 点击登录按钮,进入登录页面。
      • 输入正确的用户名和密码。
      • 点击登录按钮。
    • 预期结果
      • 成功登录后,跳转到用户主页或上次访问的页面。
      • 页面右上角显示登录用户的信息。
    • 实际结果:记录实际登录后的页面跳转情况和用户信息显示情况。
  • 测试用例二:电影搜索功能

    • 测试目标:验证电影搜索功能的正确性。
    • 前置条件:豆瓣网存在电影搜索功能。
    • 测试步骤
      • 打开豆瓣网首页。
      • 进入电影搜索页面。
      • 输入电影名称或关键词。
      • 点击搜索按钮。
    • 预期结果
      • 搜索结果页面显示与输入关键词相关的电影列表。
      • 电影列表包含电影标题、评分、导演、主演等信息。
    • 实际结果:记录实际搜索结果页面的内容和展示情况。
  • 测试用例三:电影评论功能

    • 测试目标:验证电影评论功能的正确性。
    • 前置条件:已登录豆瓣网账号,选择一部电影进入详情页面。
    • 测试步骤
      • 进入电影详情页面。
      • 滚动到评论区域,查看已有评论。
      • 点击写评论按钮,输入评论内容。
      • 点击提交按钮。
    • 预期结果
      • 评论成功提交后,在页面上能够看到新添加的评论。
      • 新评论包含评论者头像、昵称、评论内容、时间等信息。
    • 实际结果:记录评论提交后的页面显示情况和新评论的展示情况。
  • 测试用例四:豆瓣读书模块功能

    • 测试目标:验证豆瓣读书模块功能的正确性。
    • 前置条件:豆瓣网存在读书模块,包含书籍搜索、书籍详情、书评等功能。
    • 测试步骤 (以书籍搜索为例):
      • 进入豆瓣读书页面。
      • 在搜索框中输入书籍名称或关键词。
      • 点击搜索按钮。
    • 预期结果
      • 搜索结果页面显示与输入关键词相关的书籍列表。
      • 书籍列表包含书籍封面、标题、作者、评分等信息。
    • 实际结果:记录实际搜索结果页面的内容和展示情况。
  • 测试用例五:豆瓣同城活动功能

    • 测试目标:验证豆瓣同城活动功能的正确性。
    • 前置条件:豆瓣网存在同城活动模块,包含活动搜索、活动详情、报名等功能。
    • 测试步骤 (以活动搜索为例):
      • 进入豆瓣同城页面。
      • 在搜索框中输入活动类型或关键词。
      • 点击搜索按钮。
    • 预期结果
      • 搜索结果页面显示与输入关键词相关的活动列表。
      • 活动列表包含活动名称、时间、地点、参与人数等信息。
    • 实际结果:记录实际搜索结果页面的内容和展示情况。

组件代码封装

java 复制代码
package net.xdclass;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class SeleiumBase {

    protected WebDriver webDriver;

    //初始化方法
    public void setUp() {
        //指定驱动路径
        System.setProperty("webdriver.chrome.driver","D:\\developer_tools\\Broswer_Driver\\Chromedriver\\chromedriver-win64\\chromedriver.exe");
        // 谷歌驱动
        ChromeOptions options = new ChromeOptions();
        // 允许所有请求
        options.addArguments("--remote-allow-origins=*");
        webDriver = new ChromeDriver(options);

        webDriver.manage().window().maximize();

    }

    /**
     * 退出浏览器
     */
    public void tearDown() {
        if (webDriver != null) {
            webDriver.quit();
        }

    }
}

用例编写

java 复制代码
package net.xdclass;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.time.Duration;

public class TestReadBookPage extends SeleiumBase{


    /**
     * 在所有测试执行前进行初始化操作。
     * 初始化浏览器驱动,设置隐式等待时间,并导航到豆瓣首页。
     */
    @BeforeClass
    public void setupClass(){
        setUp();
        webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
        webDriver.get("https://www.douban.com/");
    }

    /**
     * 在所有测试执行后进行清理操作。
     * 主要是为了调用父类的清理方法,确保资源正确释放。
     */
    @AfterClass
    public void tearDownClass(){
        tearDown();
    }

    /**
     * 测试豆瓣首页的标题是否包含"豆瓣"。
     * 该测试优先级为1,确保在其他测试之前执行。
     */
    @Test(priority=1)
    public void testHomePageTitle(){
        String title = webDriver.getTitle();
        System.out.println(title);
        Assert.assertTrue(title.contains("豆瓣"),"标题不包括豆瓣");
    }

    /**
     * 从首页点击进入读书页面,验证是否成功进入豆瓣读书页面。
     * 该测试依赖于testHomePageTitle测试,只有在首页标题测试通过后才会执行。
     */
    @Test(priority=2)
    public void testEnterBookPage(){

        webDriver.findElement(By.xpath("//*[@id=\"anony-nav\"]/div[1]/ul/li[1]/a")).click();

        //切换窗口
        webDriver.getWindowHandles().forEach(window -> webDriver.switchTo().window(window));
        String currentUrl = webDriver.getCurrentUrl();
        System.out.println("currentUrl: " + currentUrl);
        Assert.assertTrue(currentUrl.contains("book.douban.com"), "没有进入到豆瓣读书页面");

    }


    /**
     * 测试搜索功能,搜索关键词"斗破苍穹",验证是否进入搜索结果页面。
     * 该测试优先级为3,旨在测试搜索功能的基本可用性。
     */
    @Test(priority=3)
    public void testSerarchPage(){

        webDriver.findElement(By.id("inp-query")).sendKeys("斗破苍穹");
        webDriver.findElement(By.xpath("//*[@id=\"db-nav-book\"]/div[1]/div/div[2]/form/fieldset/div[2]/input")).click();

        String title = webDriver.getTitle();
        System.out.println(title);
        Assert.assertTrue(title.contains("斗破苍穹"),AssertMessage.ERROR_TITLE_MESSAGE);
    }


    /**
     * 验证搜索结果中是否包含"斗破苍穹"这本书。
     * 该测试依赖于testSearchPage,确保搜索功能正常后验证搜索结果。
     */
    @Test(priority=4)
    public void testSearchResult(){
        WebElement element = webDriver.findElement(By.xpath("//*[@id=\"root\"]/div/div[2]/div[1]/div[1]/div[3]/div/div/div[1]"));
        String text = element.getText();
        Assert.assertTrue(text.contains("斗破苍穹"),"标题不对");
    }
}
相关推荐
编程毕设9 分钟前
【含文档+PPT+源码】基于SpringBoot电脑DIY装机教程网站的设计与实现
java·spring boot·后端
API小爬虫18 分钟前
利用 Python 爬虫按关键字搜索 1688 商品详情:实战指南
开发语言·爬虫·python
不当菜虚困18 分钟前
JAVA设计模式——(九)工厂模式
java·开发语言·设计模式
暖苏19 分钟前
Spring中bean的生命周期(笔记)
java·spring boot·spring·spring cloud·mvc·bean生命周期·springbean
柴郡猫乐园21 分钟前
智能指针之设计模式5
开发语言·设计模式·智能指针
IT技术员23 分钟前
【Java学习】Java的CGLIB动态代理:通俗解释与使用指南
java·开发语言·学习
IvanCodes33 分钟前
Java 基础--流程控制语句
java·开发语言
白总Server41 分钟前
智能座舱架构中芯片算力评估
linux·运维·服务器·开发语言·ai·架构·bash
caimouse42 分钟前
C#里创建一个TCP客户端连接类
java·网络·tcp/ip
Sunniering1 小时前
Springboot整合阿里云腾讯云发送短信验证码 可随时切换短信运营商
java·阿里云·云计算·腾讯云·springboot·短信