当前位置: 首页 > news >正文

Spring Boot集成selenium实现自动化测试

1.什么是selenium?

Selenium 是支持web 浏览器自动化的一系列工具和 库的综合项目。 它提供了扩展来模拟用户与浏览器的交互,用于扩展浏览器分配的分发 服务器, 以及用于实现W3C WebDriver 规范 的基础结构, 该规范允许您为所有主要Web 浏览器编写可互换的代码。 Selenium 不仅仅是一个工具或 API, 它还包含许多工具.

WebDriver

如果您开始使用桌面网站测试自动化, 那么您将使用 WebDriver APIs. WebDriver 使用浏览器供应商提供的浏览器自动化 API 来控制浏览器和运行测试. 这就像真正的用户正在操作浏览器一样. 由于 WebDriver 不要求使用应用程序代码编译其 API, 因此它本质上不具有侵入性. 因此, 您测试的应用程序与实时推送的应用程序相同.

Selenium IDE

Selenium IDE (Integrated Development Environment 集成 开发环境) 是用来开发 Selenium 测试用例的工具. 这是一个易于使用的 Chrome 和 Firefox 浏览器扩展, 通常是开发测试用例最有效率的方式. 它使用现有的 Selenium 命令记录用户在浏览器中的操作, 参数由元素的上下文确定. 这不仅节省了开发时间, 而且是学习 Selenium 脚本语法的一种很好的方法.

Grid

Selenium Grid允许您在不同平台的不同机器上运行测试用例. 可以本地控制测试用例的操作, 当测试用例被触发时, 它们由远端自动执行. 当开发完WebDriver测试之后, 您可能需要在多个浏览器和操作系统的组合上运行测试. 这就是 Grid 的用途所在.

2.代码工程

实验目标

  1. 打开chrome,自动输入Google网页并进行搜索
  2. 对搜索结果截图并保存
  3. 关闭浏览器

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springboot-demo</artifactId><groupId>com.et</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>Selenium</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><selenium.version>3.141.59</selenium.version><webdrivermanager.version>4.3.1</webdrivermanager.version><testng.version>7.4.0</testng.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java --><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>${selenium.version}</version></dependency><!-- https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager --><!--            https://github.com/bonigarcia/webdrivermanager--><dependency><groupId>io.github.bonigarcia</groupId><artifactId>webdrivermanager</artifactId><version>${webdrivermanager.version}</version></dependency><!-- https://mvnrepository.com/artifact/org.testng/testng --><dependency><groupId>org.testng</groupId><artifactId>testng</artifactId><version>${testng.version}</version><scope>test</scope></dependency></dependencies>
</project>

测试主类

package com.et.selenium;import com.et.selenium.page.google.GooglePage;
import com.et.selenium.util.ScreenShotUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.testng.Assert;
import org.testng.annotations.Test;import java.io.IOException;public class GoogleSearch1Test extends SpringBaseTestNGTest {@Autowiredprivate GooglePage googlePage;@Lazy // only create the object when needed@Autowiredprivate ScreenShotUtil screenShotUtil;@Testpublic void GoogleTest() throws IOException, InterruptedException {this.googlePage.goToGooglePage();Assert.assertTrue(this.googlePage.isAt());this.googlePage.getSearchComponent().search("spring boot");Assert.assertTrue(this.googlePage.getSearchResult().isAt());Assert.assertTrue(this.googlePage.getSearchResult().getCount() > 2);System.out.println("Number of Results: " + this.googlePage.getSearchResult().getCount());// wait 3 secondsThread.sleep(3000);//take screenshotthis.screenShotUtil.takeScreenShot("Test.png");this.googlePage.close();}
}

打开google网页

package com.et.selenium.page.google;import com.et.selenium.annotation.Page;
import com.et.selenium.page.Base;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;// this is the main page class that uses search componet and search results componet
@Page // using custom annotation created; src/main/java/com/demo/seleniumspring/annotation/Page.java
public class GooglePage extends Base {@Autowiredprivate SearchComponent searchComponent;@Autowiredprivate SearchResult searchResult;@Value("${application.url}")private String url;//launch websitepublic void goToGooglePage(){this.driver.get(url);}public SearchComponent getSearchComponent() {return searchComponent;}public SearchResult getSearchResult() {return searchResult;}@Overridepublic boolean isAt() {return this.searchComponent.isAt();}public void close(){this.driver.quit();}
}

搜索“ Spring Boot”关键字

package com.et.selenium.page.google;import com.et.selenium.annotation.PageFragment;
import com.et.selenium.page.Base;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;import java.util.List;@PageFragment// using custom annotation created; src/main/java/com/demo/seleniumspring/annotation/PageFragment.java
public class SearchComponent extends Base {@FindBy(name = "q")private WebElement searchBox;@FindBy(name="btnK")private List<WebElement> searchBtns;public void search(final String keyword) {this.searchBox.sendKeys(keyword);this.searchBox.sendKeys(Keys.TAB);// CLICK first search buttonthis.searchBtns.stream().filter(e -> e.isDisplayed() && e.isEnabled()).findFirst().ifPresent(WebElement::click);}@Overridepublic boolean isAt() {return this.wait.until(driver1 -> this.searchBox.isDisplayed());}
}

搜索结果截图

package com.et.selenium.util;import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.FileCopyUtils;import java.io.File;
import java.io.IOException;
import java.nio.file.Path;@Lazy
@Component
public class ScreenShotUtil {@Autowiredprivate TakesScreenshot driver;// location of screenshot file@Value("${screenshot.path}")private String path;public void takeScreenShot(final String imgName) throws IOException {// takes screenshot as saves to path in app properties file using given imgName ex. test.pngif (System.getenv("CLOUD_RUN_FLAG") == null) {try {File sourceFile = this.driver.getScreenshotAs(OutputType.FILE);File  targetfile = new File(path+"/"+imgName);FileCopyUtils.copy(sourceFile, targetfile);System.out.println("Saving screenshot to " + path);} catch (Exception e) {System.out.println("Something went wrong with screenshot capture" + e);}}}
}

关闭chrome浏览器

this.googlePage.close();

以上只是一些关键代码,所有代码请参见下面代码仓 库

代码仓库

  • GitHub - Harries/springboot-demo: a simple springboot demo with some components for example: redis,solr,rockmq and so on.(selenium)

3.测试

启动测试方法GoogleTest,效果如下面动图

selenium

4.引用

  • Spring Boot集成selenium实现自动化测试 | Harries Blog™
  • Selenium

相关文章:

Spring Boot集成selenium实现自动化测试

1.什么是selenium&#xff1f; Selenium 是支持web 浏览器自动化的一系列工具和 库的综合项目。 它提供了扩展来模拟用户与浏览器的交互&#xff0c;用于扩展浏览器分配的分发 服务器&#xff0c; 以及用于实现W3C WebDriver 规范 的基础结构&#xff0c; 该规范允许您为所有主…...

基于phpstudy对cmseasy5.5进行漏洞复现

目录&#xff1a; 漏洞复现的cmseasy5.5百度网盘链接 安装cmseasy&#xff1a; 1.在phpstudy上安装cmseasy 2.设置mysql密码为phpstudy内置mysql的密码并检查安装环境 3.安装后查看mysql内cmseasy是否有内容 获取用户名和密码过程&#xff1a; 1.查看源码发现有个remotelo…...

【c++】 C语言的输入与输出C++的IO流STL空间配置器

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;c_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.C语言的输入与输出 2.流是什么 3.CIO流 3.1 C标准IO流 3.2 C文件IO流 4.stringstream的简单介绍 5.什么是空间配置器 6.为什么需要…...

基于Faster-RCNN的停车场空位检测,支持图像和视频检测(pytorch框架)【python源码+UI界面+功能源码详解】

功能演示&#xff1a; 基于Faster-RCNN的停车场空位检测系统&#xff0c;支持图像检测和视频检测&#xff08;pytorch框架&#xff09;_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于Faster-RCNN的停车场空位检测系统是在pytorch框架下实现的&#xff0c;这是一个…...

Vue3从零开始——带你轻松掌握组件的基本操作

文章目录 1. Vue 组件的基础概念1.1 什么是组件&#xff1f;1.2 组件的作用1.3 组件的分类&#xff08;全局组件 vs 局部组件&#xff09; 2. 创建和注册组件2.1 单文件组件&#xff08;SFC&#xff09;2.2 全局组件注册2.3 局部组件注册 3. 组件命名格式4. ref获取DOM元素4.1 …...

【MySQL 03】库的操作 (带思维导图)

文章目录 &#x1f308; 一、创建数据库&#x1f308; 二、查看数据库&#x1f308; 三、使用数据库&#x1f308; 四、修改数据库&#x1f308; 五、删除数据库&#x1f308; 六、备份数据库&#x1f308; 七、恢复数据库&#x1f308; 八、字符集和校验规则⭐ 1. 查看系统默认…...

SpringBoot-读取配置文件内容

目录 前言 主页&#xff08;端口号默认8080&#xff09; 1 Value 注解 引用变量的使用 2 Environment 对象 3 ConfigurationProperties &#xff08;配置内容和对象&#xff0c;进行相互绑定&#xff09; 前言 读取配置文件有3 种方式 (1) Value注解 (2) Environm…...

springboot整合springmvc

1、创建springboot项目&#xff0c;勾选Spring web 当前springboot选择的是2.6.13版本&#xff0c;jdk1.8尽量选2.几的springboot 2、在pom.xml中导入相应的坐标 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-…...

el-cascader多选的父子关联和父子不关联功能

公用html&#xff1a; <el-cascader v-model"data" :options"optionsData" :props"props" clearable> </el-cascader> 公用js变量&#xff1a; data () {return {// 绑定的数组data: [],// 绑定的选项数据optionsData: []} }, 公…...

#Datawhale AI夏令营第4期#多模态大模型Task2

赛事进阶解读 关于赛事介绍&#xff1a; Better Synth 是一项以数据为中心的挑战赛&#xff0c;考察如何合成与清洗图文数据以在多模态大模型上取得更优的图片理解能力。 本次比赛基于 Mini-Gemini 模型进行训练&#xff0c;只关注于预训练&#xff08;模态间对齐&#xff09…...

LeetCode 热题100-1

两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任…...

表现良好的最长时间段(LeetCode)

题目 给你一份工作时间表 hours&#xff0c;上面记录着某一位员工每天的工作小时数。 我们认为当员工一天中的工作小时数大于 8 小时的时候&#xff0c;那么这一天就是「劳累的一天」。 所谓「表现良好的时间段」&#xff0c;意味在这段时间内&#xff0c;「劳累的天数」是严格…...

【性能优化】DNS解析优化

前言 DNS解析过程消耗时间DNS有本地缓存 比如首次访问某站点&#xff0c;会耗费很多时间进行DNS解析&#xff0c;但解析结束后会将ip地址存入本地设备&#xff0c;后续再访问此域名时就会直接从缓存中取。 首次访问页面时&#xff0c;本页面的DNS解析是无法优化的&#xff0…...

【剑指 offer】合并链表

目 录 描述&#xff1a; 输入两个递增的链表&#xff0c;单个链表的长度为 n&#xff0c;合并这两个链表并使新链表中的节点仍然是递增排序的。 思路&#xff1a; 定义一个新链表&#xff0c;先进行我们的原俩链表判断&#xff0c;然后比较俩链表的每个节点大小&#xff0c;然…...

红酒与节日装饰:打造节日氛围的需备品

随着节日的脚步渐渐临近&#xff0c;节日的氛围也愈发浓厚。在这个特殊的时刻&#xff0c;红酒与节日装饰无疑成为了营造节日氛围的需备品。洒派红酒&#xff08;Bold & Generous&#xff09;作为定制红酒的品牌&#xff0c;其不同的韵味与节日装饰的精致整合&#xff0c;共…...

Element Plus的el-carousel走马灯平铺多张图片

效果 <template><div class"system-banner"><el-carousel height"320px" indicator-position"outside" :autoplay"false"><el-carousel-item v-for"(item, index) in govList" :key"index"…...

【promise】Promise的几个关键问题 (三)

Ⅰ-如何改变 promise 的状态? (1) resolve(value): 如果当前是 pending 就会变为 resolved (2) reject(reason): 如果当前是 pending 就会变为 rejected (3) 抛出异常: 如果当前是 pending 就会变为 rejected Ⅱ-一个 promise 指定多个成功/失败回调函数, 都会调用吗? 当 pro…...

利用ZXing.Net Bindings for EmguCV识别条形码及绘制条形码边框17(C#)

上一篇博文&#xff1a;绘制条形码的效果不是很好&#xff1a;利用Emgucv绘制条形码边框16(C#)-CSDN博客 测试环境&#xff1a; win11 64位操作系统 visual studio 2022 ZXing.Net.Bindings.EmguCV 0.16.4 测试步骤如下&#xff1a; 1 新建.net framework 4.8的控制台项目…...

IP代理如何增强网络安全性?

在当今的数字时代&#xff0c;网络安全已成为一个关键问题&#xff0c;而使用 IP 代理可以成为增强网络安全的有效方法。根据请求信息的安全性&#xff0c;IP 代理服务器可分为三类&#xff1a;高级匿名代理、普通匿名代理和透明代理。此外&#xff0c;根据使用的用途&#xff…...

NDP(Neighbor Discovery Protocol)简介

定义 邻居发现协议NDP&#xff08;Neighbor Discovery Protocol&#xff09;是IPv6协议体系中一个重要的基础协议。邻居发现协议替代了IPv4的ARP&#xff08;Address Resolution Protocol&#xff09;和ICMP路由设备发现&#xff08;Router Discovery&#xff09;&#xff0c;…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...