掌握Selenium中元素缓存技巧,提高测试效率!

一、前言 / INTRODUCTION

图片

本篇文章我们再来看下如何在Selenium中使用缓存

页面对象模型是UI自动化测试中的一种很好的设计模式,我们使用@FindBy@FindAll注释来标记Page Object中的WebElement

本次要讲的@CacheLookup是一个非常重要但被忽视的注释,它可以帮助我们使测试运行得更快。

Selenium中,CacheLookup是一个注解,用于标记页面对象模型(Page Object Model)中的元素。当使用CacheLookup注解时,Selenium会在第一次查找元素时将其缓存起来,以便后续的查找操作可以直接使用缓存的元素,而不需要再次查找页面上的元素。

二、举个常规的例子 / EXAMPLE

图片

首先让我们了解一下SeleniumPageObject模型中什么时候调用FindElement。每当使用页面对象中的WebElement执行某些操作时,都会触发FindElement从网页中查找WebElement的最新版本。这个查找基本上是一个FindElement REST请求到浏览器的Web驱动程序。这个查找是代码中最耗时的部分之一。

我们用Page Object模式来创建一个demo

import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;

/**
 * 类说明:PO
 */
public class TesterRoadPO {
    @FindBy(how = How.NAME, using = "firstname")
    public WebElement firsName;

    @FindBy(how = How.NAME, using = "lastname")
    public WebElement lastName;

}
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.PageFactory;
import org.testng.annotations.Test;

/**
 * 类说明:demo
 */
public class TesterRoadDemo {

    @Test
    public void testerRoadDemo() {

        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.addArguments("--remote-allow-origins=*");
        // 为了理解使用PageObjects对web元素的操作是如何工作的,
        // 我们将保存chrome驱动的所有日志。下面的语句对我们有所帮助
        // 将所有日志保存在名为TesterRoadLog.txt的文件中
        System.setProperty("webdriver.chrome.logfile", "src/main/resources/TesterRoadLog.txt");
        WebDriverManager.chromedriver().setup();
        WebDriver driver = new ChromeDriver(chromeOptions);
        driver.get("http://127.0.0.1:8080/");

        // 初始化Page object
        TesterRoadPO pageObject = PageFactory.initElements(driver, TesterRoadPO.class);

        pageObject.firsName.sendKeys("Road");
        pageObject.lastName.sendKeys("Tester");

        pageObject.firsName.getText();
        pageObject.lastName.getText();

        driver.close();
        driver.quit();
    }
}

在上述代码中,调用了四次FindBy,查找元素和获取文本,我们来看下日志文件

[12.654][INFO]: COMMAND FindElement {
   "using": "name",
   "value": "firstname"
}
[12.654][INFO]: Waiting for pending navigations...
[12.717][INFO]: Done waiting for pending navigations. Status: ok
[12.851][INFO]: Waiting for pending navigations...
[12.854][INFO]: Done waiting for pending navigations. Status: ok
[12.854][INFO]: RESPONSE FindElement {
   "ELEMENT": "0.8984444413515806-1"
}

[12.860][INFO]: COMMAND TypeElement {
   "id": "0.8984444413515806-1",
   "value": [ "Road" ]
}
[12.860][INFO]: Waiting for pending navigations...
[12.861][INFO]: Done waiting for pending navigations. Status: ok
[13.045][INFO]: Waiting for pending navigations...
[13.050][INFO]: Done waiting for pending navigations. Status: ok
[13.050][INFO]: RESPONSE TypeElement

[13.053][INFO]: COMMAND FindElement {
   "using": "name",
   "value": "lastname"
}
[13.053][INFO]: Waiting for pending navigations...
[13.054][INFO]: Done waiting for pending navigations. Status: ok
[13.074][INFO]: Waiting for pending navigations...
[13.082][INFO]: Done waiting for pending navigations. Status: ok
[13.082][INFO]: RESPONSE FindElement {
   "ELEMENT": "0.8984444413515806-2"
}
[13.086][INFO]: COMMAND TypeElement {
   "id": "0.8984444413515806-2",
   "value": [ "Tester" ]
}

在日志中,我们可以看到对于每个语句都有对FindElementTypeElement调用。对日志文件的进一步调查将显示,对于每个getText调用,都将有一个FindElementGetElementText调用。

我们在WebElement上执行的每一个操作都会进行调用,那么无疑将会花费更多的时间。那么我们如何才能使的测试更快,花费更少的时间?

现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:310357728【暗号:csdn999】

三、CacheLookup 注解/ @CacheLookup

图片

@CacheLookup可以帮助我们控制何时缓存WebElement,何时不缓存。当这个注释应用于WebElement时,它会让Selenium保留WebElement的缓存,而不是每次都从网页中搜索WebElement。可以节省大量的时间。

import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;

/**
 * 类说明:PO中使用CacheLookup缓存元素
 */
public class TesterRoadPO {
    @FindBy(how = How.NAME, using = "firstname")
    public WebElement firsName;

    @FindBy(how = How.NAME, using = "firstname")
    @CacheLookup
    public WebElement firsNameCached;
}

import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.PageFactory;
import org.testng.annotations.Test;

/**
 * 类说明:未使用CacheLookup和使用CacheLookup对比
 */
public class TesterRoadDemo {

    @Test
    public void testerRoadDemo() {

        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.addArguments("--remote-allow-origins=*");
        // 为了理解使用PageObjects对web元素的操作是如何工作的,
        // 我们将保存chrome驱动的所有日志。下面的语句对我们有所帮助
        // 将所有日志保存在名为TesterRoadLog.txt的文件中
        System.setProperty("webdriver.chrome.logfile", "src/main/resources/TesterRoadLog.txt");
        WebDriverManager.chromedriver().setup();
        WebDriver driver = new ChromeDriver(chromeOptions);
        driver.get("http://127.0.0.1:8080/");

        // 初始化Page object
        TesterRoadPO pageObject = PageFactory.initElements(driver, TesterRoadPO.class);

        pageObject.firsName.sendKeys("TesterRoad");
        // 首先尝试从未缓存的WebElement获取文本。
        // 查看执行1000个getText操作的时间
        long withoutCacheStartTime = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            pageObject.firsName.getText();
        }
        long withoutCacheEndTime = System.currentTimeMillis();
        System.out.println("未使用缓存花费的时间: " + ((withoutCacheEndTime - withoutCacheStartTime) / 1000));

        // 现在我们在缓存的元素上重复同样的操作
        // 查看执行相同操作1000次所需的时间
        long withCacheStartTime = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            pageObject.firsNameCached.getText();
        }
        long withCacheEndTime = System.currentTimeMillis();
        System.out.println("使用缓存花费的时间: " + ((withCacheEndTime - withCacheStartTime) / 1000));

        driver.close();
        driver.quit();
    }
}

图片

在输出中,我们可以清楚地看到,与非缓存版本相比,缓存版本的WebElement执行相同操作的时间减少了50%

四、写在后面 / WRITE LATER

图片

既然使用CacheLookup可以提高50%的效率,那么我们在项目中全部使用CacheLookup岂不美哉,NONONO,那到不尽然,比如像动态元素(像id之类,很多都是动态的)就不要使用CacheLookup了,我们要在合适的场景下去合理使用CacheLookup

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走!

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
 

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/242520.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux查看端口使用情况

1、netstat命令 netstat命令用于显示与网络相关的信息&#xff0c;包括正在使用的端口。 netstat -tuln 其中&#xff0c;-t选项表示显示TCP连接&#xff0c;-u选项表示显示UDP连接&#xff0c;-l选项表示仅显示监听状态的连接&#xff0c;-n选项表示显示数字格式的IP地址和端口…

K8s中pod詳解

目录 Yaml语法解析 Pod pod是如何被创建的 1.创建一个pod 2.创建一个多容器pod 进入容器 3.配置节点标签 4.Pod容器的交互 4.1创建pod&#xff0c;并做本地解析 4.2pod共享进程 4.3pod共享宿主机namespace 5.钩子函数lifecycle 基础指令 # 查看对应资源: 状态 $ kubectl…

程序员的养生之道:延寿健康的十大秘诀(上)

目录 1. 了解程序员健康问题 1.1 程序员健康问题概述 1.2 长时间坐姿对身体的影响 1.3 眼睛健康与程序员 1.4 压力管理与心理健康 2. 合理安排工作与休息时间 2.1 工作与休息的平衡 2.2 时间管理技巧 2.3 活动间隙的小窍门 2.4 养成良好的睡眠习惯 3. 均衡饮食&a…

【算法题】密钥格式化 (js)

!](https://img-blog.csdnimg.cn/direct/bf9a3d781a8043c997593260c0a8306f.png) 第一部分的字符可以少于… const str "5F3Z-2e-9w"; const str1 "2-5g-3-J"; function solution(num, str) {const arr str.split("-");const head arr[0];…

658. 找到 K 个最接近的元素

658. 找到 K 个最接近的元素 Java代码&#xff1a;滑窗 class Solution {public List<Integer> findClosestElements(int[] arr, int k, int x) {List<Integer> list new ArrayList<>();for (int i 0; i < arr.length; i) {arr[i] arr[i] - x;}for(i…

Unity 通过鼠标控制模拟人物移动和旋转视角

要通过鼠标控制并模拟人物移动和转换视角&#xff0c;将会使用射线检测、鼠标点击和鼠标水平移动&#xff0c;配合物体旋转和移动方法共同实现。 首先搭建个由一个Plane地板和若干cube组成的简单场景&#xff1a; 其次创建一个Capsule作为移动物体&#xff0c;并把摄像头拉到该…

thinkphp6入门(13)-- 一对多关联模型

定义一对一关联&#xff0c;例如&#xff0c;一个用户都有多个工作经历。 一、两表 1.用户表:user 2.工作经验表&#xff1a;work_experience user表的id关联work_experience表的user_id。 注意看&#xff0c;user_id1的有2条工作经验 二、数据模型 主表模型&#xff1a;…

多边形的裁剪:一种基于有效边表的有效多边形裁剪算法的分析

我们可以考虑有下面的多边形 黑色边框就是区域就是裁剪下来的多边形区域&#xff0c;我们可以将裁剪区域与多边形区域的端点看作有效边表&#xff0c;显然对于左边界来说我们是要选取边界x值大的点作为新的多边形的边界&#xff0c;对于右边界我们是要选择x值小的点作为多边形的…

通过fpmarkets与自媒体导师学习经验,避免踩坑

举一个例子&#xff0c;从fpmarkets与自媒体导师学习的负面经验&#xff0c;避免各位投资者踩坑。这个要从fpmarkets刚踏入外汇交易市场的第二年说起&#xff0c;偶然的一次&#xff0c;当fpmarkets看到一个可以不用花钱就可以学习交易培训课程时&#xff0c;就如同中了大奖一样…

Windows内存管理机制

文章目录 Windows内存管理机制Windows基本架构物理地址和虚拟地址内存空间布局物理内存和虚拟内存基本概念分页机制 总结从内存中获取数据的过程 Windows内存管理机制 Windows基本架构 在了解Window内存管理机制之前&#xff0c;先简单了解一下Windows的内核权限以及基本的架…

经典基本电路

USB电路 USB差分走线的阻抗为90欧:差分对10mil宽的走线以及5mil的间距,两边包地15/20mil以上厚度(SI9000计算阻抗) USB2.0接口电路&#xff1a; USB3.0接口电路&#xff1a; USB HUB电路: HDMI电路 HDMI差分走线的阻抗为100欧:差分对6mil宽的走线以及5mil的间距,两边包地15/20…

你都那么老了,还在每天写博客吗?

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 白色便民网&#xff1a;我想多开一个公司会不会被税局查? 事件背景&#xff1a; 松松已创业9年&#xff0c;自媒体14年&#xff0c;经历过从0开公司、项目失败、赚钱等各种高光时刻。所以对于小微企业经营还是…

为什么QLC NAND才是ZNS SSD最大的赢家?-part3

在ZNS SSD设计中&#xff0c;也有很多的挑战&#xff1a; Open Zones 对写入缓冲区的需求&#xff1a;保持大量的 open zones&#xff08;例如 1K&#xff09;会增加对带宽的需求&#xff0c;并要求控制器提供足够的缓冲空间来管理并发写入请求。这需要较大的高带宽写入缓冲区以…

DENet:用于可见水印去除的Disentangled Embedding网络笔记

1 Title DENet: Disentangled Embedding Network for Visible Watermark Removal&#xff08;Ruizhou Sun、Yukun Su、Qingyao Wu&#xff09;[AAAI2023 Oral] 2 Conclusion This paper propose a novel contrastive learning mechanism to disentangle the high-level embedd…

ELK简单介绍一

任务背景 运维人员需要对系统和业务日志进行精准把控&#xff0c;便于分析系统和业务状态。日志分布在不同的服务器上&#xff0c;传统的使用传统的方法依次登录每台服务器查看日志&#xff0c;既繁琐又效率低下。所以我们需要集中化的日志管理工具将位于不同服务器上的日志收…

前端反向代理的神奇世界:加速、安全与缓存的秘密(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

3D Font

在游戏中使用3D文本 只需添加预制件并立即生成您的文本。 特点: *真实3D字母&#xff0c;可用作游戏对象*移动友好低聚 *VR兼容 *WebGL兼容 *30种以上不同字体 *材料和颜色可定制 WebGL演示 https://indiechest.itch.io/3d-font-engine 下载&#xff1a; ​​Unity资源商店链…

【lesson13】MySQL表的基本操作之create(创建),update(更新)和replace(替换)

文章目录 表的增删查改create测试建表基础测试 update测试建表基础测试 replace&#xff08;替换&#xff09;测试建表基础测试 表的增删查改 CRUD : Create(创建), Retrieve(读取)&#xff0c;Update(更新)&#xff0c;Delete&#xff08;删除&#xff09; create 测试 建表…

opencl.dll如何修复?快速解决opencl.dll缺失总共有5种方案

在计算机使用过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“opencl.dll缺失”。OpenCL&#xff08;Open Computing Language&#xff09;是一种开放的并行计算框架&#xff0c;用于编写高性能的并行程序。当opencl.dll文件丢失或损坏时&#xff0c;可…

Simple Water Caustic Pattern In Unity ShaderGpaph

shadertoy上有各种神奇的效果&#xff0c;以我的见识根本想象不到这些是怎么弄出来的。 不过不会做至少可以先会用。 这篇文章抓取一个shadertoy的示例以制作一个测试效果。 参考这篇shadertoy&#xff0c;使用自定义节点装填hlsl的noise代码 Shader - Shadertoy BETA 首先使…