Selenium自动化测试函数全解析(二)

❄️目录❄️

等待

强制等待

智能等待

隐式等待

显示等待

不能混合使用,可以配合使用

浏览器导航

打开网站

前进后退刷新

弹窗

上传文件

浏览器参数设置

1、无头模式

2、浏览器加载策略


出现了找不到页面元素的问题,可能的原因有哪些?
1、元素复制错了

比如复制的元素是#s-hotsearch-wrapper > div,但是在粘贴的时候不小心多打了两个v成了#s-hotsearch-wrapper > divvv,页面没有这个元素就报错

2、元素定位方式使用错误,使用cssSelector却复制的xpath或者使用xpath却复制的是cssSelector。

cssSelector-->xpath, xpath-->cssSelector

3、自动化打开的页面和手工打开的页面不一样

4、动态元素

5、代码执行的速度比页面加载的速度要快。

也就是说我们查找的元素在页面中还没有加载出来的时候,代码却执行到了这一步,那么也会出现找不到页面元素的问题。

比如,我们在百度首页搜索"鞠婧祎"后点击这个"百度百科":

java 复制代码
public class RunTest {
    public static void main(String[] args) throws InterruptedException, IOException {
          test_2026_01_06 test = new test_2026_01_06();
          test.test01();
    }
}
java 复制代码
public class test_2026_01_06 {
    public void test01() throws InterruptedException, IOException {
        // 自动管理Chrome驱动,驱动程序下载驱动
        // WebDriverManager.chromedriver().setup();
        ChromeOptions options = new ChromeOptions();

        //运行访问所有链接
        options.addArguments("--remote-allow-origins=*");

        //打开Chrome浏览器
        WebDriver driver = new ChromeDriver(options);
        //输入百度网址
        driver.get("https://www.baidu.com");

        //输入鞠婧祎并点击搜索
        driver.findElement(By.cssSelector("#chat-textarea")).sendKeys("鞠婧祎");
        driver.findElement(By.cssSelector("#chat-submit-button")).click();
        //没有等待
        // Thread.sleep(3000);
        //点击百度百科
        driver.findElement(By.cssSelector("#\\31  > div > div > div > div > div > div.new-tag_4ozgi.new-text-link_3k9GD > div > div.flex-wrapper-top_3ucFS > div.flex-col-left_3trtY.baike-wrapper_6AORN.cu-pt-xs-lg.baike-wrapper-pc_26R04.cu-pt-xl.baike-wrapper-left-pc_5eYY8.cos-space-pb-sm > div > div > p > span:nth-child(1) > span")).click();
        driver.quit();
    }
}

我们可以看到程序报错,找不到我们复制的"百度百科"cssSelector,这就是因为页面元素还没有加载出来。

我们可以通过等待来解决这个问题。

等待

通常代码执行的速度比页面渲染的速度要快,如果避免因为渲染过慢出现的自动化误报的问题呢?可以使用selenium中提供的三种等待方法

强制等待

**Thread.sleep()**参数毫秒

针对上面的问题,当我们搜索"鞠婧祎"后我们强制等待页面元素加载3秒,再来看看是否报错:

java 复制代码
public class test_2026_01_06 {
    public void test01() throws InterruptedException, IOException {
        // 自动管理Chrome驱动,驱动程序下载驱动
        // WebDriverManager.chromedriver().setup();
        ChromeOptions options = new ChromeOptions();

        //运行访问所有链接
        options.addArguments("--remote-allow-origins=*");
        //options.addArguments("--start-maximized");
        //options.addArguments("--no-sandbox");

        //打开Chrome浏览器
        WebDriver driver = new ChromeDriver(options);
        //输入百度网址
        driver.get("https://www.baidu.com");

        //输入鞠婧祎并点击搜索
        driver.findElement(By.cssSelector("#chat-textarea")).sendKeys("鞠婧祎");
        driver.findElement(By.cssSelector("#chat-submit-button")).click();
        //等待3秒
        Thread.sleep(3000);
        //点击百度百科
        driver.findElement(By.cssSelector("#\\31  > div > div > div > div > div > div.new-tag_4ozgi.new-text-link_3k9GD > div > div.flex-wrapper-top_3ucFS > div.flex-col-left_3trtY.baike-wrapper_6AORN.cu-pt-xs-lg.baike-wrapper-pc_26R04.cu-pt-xl.baike-wrapper-left-pc_5eYY8.cos-space-pb-sm > div > div > p > span:nth-child(1) > span")).click();

        driver.quit();
    }
}

可以看到程序正常运行完毕没有报错。

优点:使用简单,调试的时候比较有效

缺点:影响运行效率,浪费大量的时间。

智能等待

隐式等待

隐式等待是一种智能等待,在查找元素时,会在指定时间内不断查找,如果找到就继续执行后续代码,如果超时没有找到才会报错。

复制代码
//隐式等待3秒
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));

implicitlyWait()参数是Duration类中提供的毫秒、秒、分钟等方法。

隐式等待会作用在页面的所有元素上 ,所以当写了隐式等待后,后续查找元素 (findElement(),findElements())时都会在指定时间内查找元素。只要driver对象没有被释放掉,那么隐式等待会一直生效。

但是隐式等待无法等待非页面元素,比如导航栏的前进、后退、刷新、弹窗......这些需要用显示等待。

显示等待

显示等待也是一种智能等待,在指定超时时间范围内满足操作的条件就能继续执行后续代码。

new WebDriverWait(driver, Duration.ofSeconds(3)).until($express)

返回值是boolean类型。

$express是操作的条件,涉及到selenium.support.ui.ExpectedConditions包下的ExpectedConditions类。

ExpectedConditions预定义方法的一些示例:

• elementToBeClickable(By locator) ‒ 用于检查元素的期望是可见的 并已启用,以便我们可以单击它

• presenceOfElementLocated(Bylocator) ‒ 检查页面的 DOM 上是否存在元素 。(存在,但不保证元素是可见或者可点击的

• textToBe(Bylocator,String str) -检查元素的文本内容完全匹配指定字符串。

• urlToBe(java.lang.String url) ‒ 检查当前页面的URL是一个特定的 URL

java 复制代码
public class test_2026_01_06 {
    public void test01() throws InterruptedException, IOException {
        // 自动管理Chrome驱动,驱动程序下载驱动
        // WebDriverManager.chromedriver().setup();
        ChromeOptions options = new ChromeOptions();

        //运行访问所有链接
        options.addArguments("--remote-allow-origins=*");

        //打开Chrome浏览器
        WebDriver driver = new ChromeDriver(options);
        //输入百度网址
        driver.get("https://www.baidu.com");

        //输入鞠婧祎并点击搜索
        driver.findElement(By.cssSelector("#chat-textarea")).sendKeys("鞠婧祎");
        driver.findElement(By.cssSelector("#chat-submit-button")).click();
        //强制等待3秒
        //Thread.sleep(3000);
        //隐式等待3秒
        //driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
        //点击百度百科
        //driver.findElement(By.cssSelector("#\\31  > div > div > div > div > div > div.new-tag_4ozgi.new-text-link_3k9GD > div > div.flex-wrapper-top_3ucFS > div.flex-col-left_3trtY.baike-wrapper_6AORN.cu-pt-xs-lg.baike-wrapper-pc_26R04.cu-pt-xl.baike-wrapper-left-pc_5eYY8.cos-space-pb-sm > div > div > p > span:nth-child(1) > span")).click();

        //显示等待3秒,然后点击百度百科
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
        wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#\\31  > div > div > div > div > div > div.new-tag_4ozgi.new-text-link_3k9GD > div > div.flex-wrapper-top_3ucFS > div.flex-col-left_3trtY.baike-wrapper_6AORN.cu-pt-xs-lg.baike-wrapper-pc_26R04.cu-pt-xl.baike-wrapper-left-pc_5eYY8.cos-space-pb-sm > div > div > p > span:nth-child(1) > span")));

        driver.quit();
    }
}

如果在规定时间内没有等待成功,则报错:

不能混合使用,可以配合使用

如果我们把隐式等待和显示等待混合使用会怎么样?

java 复制代码
public class test_2026_01_06 {
    public void test02() throws InterruptedException, IOException {
        // 自动管理Chrome驱动,驱动程序下载驱动
        // WebDriverManager.chromedriver().setup();
        ChromeOptions options = new ChromeOptions();

        //运行访问所有链接
        options.addArguments("--remote-allow-origins=*");

        //打开Chrome浏览器
        WebDriver driver = new ChromeDriver(options);
        //输入百度网址
        driver.get("https://www.baidu.com");

        //输入鞠婧祎并点击搜索
        driver.findElement(By.cssSelector("#chat-textarea")).sendKeys("鞠婧祎");
        driver.findElement(By.cssSelector("#chat-submit-button")).click();

        SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS");
        System.out.println("开始等待前的时间:" + sim.format(System.currentTimeMillis()));

        //隐式等待5秒
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));

        //显示等待10s
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        //等待一个不存在的元素
        try {
            wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#\\3111111")));
        } catch (Exception e) {
            System.out.println("NoSuchElement!");
        }
        System.out.println("等待结束的时间:" + sim.format(System.currentTimeMillis()));
        driver.quit();
    }
}
public class RunTest {
    public static void main(String[] args) throws InterruptedException, IOException {
          test_2026_01_06 test = new test_2026_01_06();
          test.test02();
    }
}

多次执行看到总的等待时间不是5+10s,

所以我们不要混合使用隐式等待和显示等待,否则可能会导致等待时间不可预测。

但是我们可以配合两者使用,隐式等待只能作用在页面元素上不能等待非页面元素,而显示等待。

所以配合使用即隐式等待作用页面元素,显示等待作用在非页面元素上。

浏览器导航

打开网站

我们之前一直通过driver.get(url)来打开网站的,这是一种简洁的方式。

还有一种:driver.navigate().to(url)

前进后退刷新

复制代码
//后退
driver.navigate().back();
//前进
driver.navigate().forward();
//刷新
driver.navigate().refresh();

弹窗

弹窗有3种,

警告弹窗

确认弹窗

提示弹窗

我们对弹窗的主要操作有点击确认、取消、输入文本信息、获取弹窗的文本信息

但是弹窗在页面是找不到元素的,常规的selenium元素定位方法(xpath, cssSelector)失效,所以我们要通过selenim的Alert接口来操作弹窗

java 复制代码
public class test_2026_01_06 {
    /**
     * 弹窗
     */
    public void testAlert() throws InterruptedException {
        // 自动管理Chrome驱动,驱动程序下载驱动
        // WebDriverManager.chromedriver().setup();
        ChromeOptions options = new ChromeOptions();

        //运行访问所有链接
        options.addArguments("--remote-allow-origins=*");

        //打开Chrome浏览器
        WebDriver driver = new ChromeDriver(options);


        //打开含警告弹窗的页面
        driver.get("file:///D:/My%20Professional%20Class/%E6%AF%94%E7%89%B9/%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/selenium-html/selenium-html/alert.html#");
        Thread.sleep(3000);
        //点击,出现弹窗
        driver.findElement(By.cssSelector("#tooltip")).click();

        Thread.sleep(3000);
        Alert alert = driver.switchTo().alert();
        alert.accept();
        Thread.sleep(3000);

        driver.quit();
    }
  
}

警告弹窗只要一个"确定"按钮,所以无论用accept()还是dismiss()都能达到关闭弹窗的作用。

自动化操作提示弹框输入文本内容时,界面上看不到输入效果,但实际上输入了文本信息。

java 复制代码
public class test_2026_01_06 {
    /**
     * 弹窗
     */
    public void testAlert() throws InterruptedException {
        // 自动管理Chrome驱动,驱动程序下载驱动
        // WebDriverManager.chromedriver().setup();
        ChromeOptions options = new ChromeOptions();

        //运行访问所有链接
        options.addArguments("--remote-allow-origins=*");

        //打开Chrome浏览器
        WebDriver driver = new ChromeDriver(options);

        //打开含 提示弹窗 的页面
        driver.get("file:///D:/My%20Professional%20Class/%E6%AF%94%E7%89%B9/%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/selenium-html/selenium-html/Prompt.html");
        Thread.sleep(3000);
        //点击,出现弹窗
        driver.findElement(By.cssSelector("body > input[type=button]")).click();
        Thread.sleep(1000);
        Alert alert = driver.switchTo().alert();
        //取消
        alert.dismiss();
        Thread.sleep(1000);
        //点击,出现弹窗
        driver.findElement(By.cssSelector("body > input[type=button]")).click();
        //输入内容
        alert.sendKeys("自动化测试");
        Thread.sleep(1000);
        //确定
        alert.accept();
        Thread.sleep(3000);
        driver.quit();
    }
    
}

另外,调起弹窗后必须将弹窗关闭才能对页面其它元素进行操作。

上传文件

点击文件上传的场景一般会弹出系统窗口让我们选择文件

但是selenium无法识别非web的控件,上传文件窗口为系统自带,无法识别窗口元素但是可以使用sendkeys来上传指定路径的文件,达到的效果是⼀样的

java 复制代码
public class test_2026_01_06 {
    /**
     * 弹窗
     */
    public void testAlert() throws InterruptedException {
        // 自动管理Chrome驱动,驱动程序下载驱动
        // WebDriverManager.chromedriver().setup();
        ChromeOptions options = new ChromeOptions();

        //运行访问所有链接
        options.addArguments("--remote-allow-origins=*");

        //打开Chrome浏览器
        WebDriver driver = new ChromeDriver(options);

        //打开本地含 上传文件 的页面
        driver.get("file:///D:/My%20Professional%20Class/%E6%AF%94%E7%89%B9/%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/selenium-html/selenium-html/upload.html");
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
        //找到选择文件元素并上传
        driver.findElement(By.xpath("/html/body/div/div/input")).sendKeys("D:\\wangw\\Pictures\\Saved Pictures\\绿萝.jpg");
        Thread.sleep(2000);



        driver.quit();
    }
    
}

可以看到我们手动上传和自动化上传文件的效果是一样的。

浏览器参数设置

1、无头模式

默认情况下是有头模式,写了这行代码就是无头模式:

//设置无头模式

options.addArguments("-headless");

那么什么是无头模式?

无头模式是一种浏览器运行模式,不显示图形用户界面(GUI),所有操作在后台静默执行。

所以无头模式下我们看不到任何前端运行效果。

实际在工作中,自动化在编写完成交付之后,每次执行的时候不会真的安排人一直肉眼盯着自动化的执行效果,一般自动化在实际运行中设置的都是无头模式,通过自动化执行的结果去分析。

2、浏览器加载策略

若页面资源比较多,通过driver.get方法去请求页面需要请求很长时间,因此就存在这样的要求:

页面主要框架加载完了就继续往下执行,而不是等待所有的资源加载完成。

Selenium 通过 PageLoadStrategy控制浏览器在何时认为页面已加载完成,从而决定是否继续执行后续操作。

该策略直接影响测试的速度稳定性,尤其在资源较多的页面中尤为重要

options.setPageLoadStrategy();

有3个参数可以设置,默认是 PageLoadStrategy.NORMAL,表示等待页面所有资源加载完成才往下执行。

EAGER表示DOM访问准备就绪,但是还存在其它资源还在加载(注入图像等)

NONE表示完全不阻塞webDriver,仅等待初始html文档加载完成。

因此在速度NONE>EAGER>NORMAL。速度越快,对页面完整性的保证越低。

相关推荐
shark-chili3 小时前
从操作系统底层浅谈程序栈的高效性
java
不知疲倦的仄仄3 小时前
第二天:深入理解 Selector:单线程高效管理多个 Channel
java·nio
期待のcode3 小时前
Java虚拟机栈
java·开发语言·jvm
珂朵莉MM3 小时前
全球校园人工智能算法精英大赛-产业命题赛-算法巅峰赛 2025年度画像
java·人工智能·算法·机器人
芒克芒克3 小时前
本地部署SpringBoot项目
java·spring boot·spring
cute_ming4 小时前
关于基于nodeMap重构DOM的最佳实践
java·javascript·重构
sww_10264 小时前
Netty原理分析
java·网络
小突突突4 小时前
Spring框架中的单例bean是线程安全的吗?
java·后端·spring
Mr.Entropy5 小时前
JdbcTemplate 性能好,但 Hibernate 生产力高。 如何选择?
java·后端·hibernate