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 {

    @Autowired
    private GooglePage googlePage;

    @Lazy // only create the object when needed
    @Autowired
    private ScreenShotUtil screenShotUtil;

    @Test
    public 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 seconds
         Thread.sleep(3000);
        //take screenshot
        this.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 {

    @Autowired
    private SearchComponent searchComponent;

    @Autowired
    private SearchResult searchResult;

    @Value("${application.url}")
    private String url;

    //launch website
    public void goToGooglePage(){
        this.driver.get(url);
    }

    public SearchComponent getSearchComponent() {
        return searchComponent;
    }

    public SearchResult getSearchResult() {
        return searchResult;
    }

    @Override
    public 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 button
        this.searchBtns
                .stream()
                .filter(e -> e.isDisplayed() && e.isEnabled())
                .findFirst()
                .ifPresent(WebElement::click);
    }

    @Override
    public 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 {

    @Autowired
    private 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.png
        if (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();

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

代码仓库

3.测试

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

4.引用

相关推荐
wuminyu6 小时前
JVM规范学习总结:解释器与JIT编译器如何处理JVM字节码
java·linux·c语言·jvm·c++
txxzjmzlh6 小时前
SpringBoot 配置⽂件
java·spring boot·spring
ZhengEnCi6 小时前
模型训练完整流程:从数据准备到模型上线的 10 个关键步骤(全文可跑)
后端·算法
王中阳Go7 小时前
后端转 Agent 岗面试怎么答:8 个高频问题与应答口径
人工智能·后端·python·大语言模型
Wang's Blog7 小时前
Java 项目实战: 交友项目 - 搜索附近的功能概述和分析
java·开发语言·交友
程序猿DD7 小时前
OctaFuse Gateway 2.18.0:MCP 接入支持 OAuth,供应商粘性绑定可视化管理
后端
骑着蜗牛撵大象3277 小时前
大模型 Agent 的沙箱护栏:gVisor 隔离、出口白名单与审计闭环
java·开发语言·jvm·安全·agent沙箱·gvisor·microvm
独泪了无痕7 小时前
Hutool之LocalDateTimeUtil:让时间间隔操作如虎添翼
java
三无少女指南8 小时前
从这里开始:Java 后端与 AI 工程的三条阅读路线
java·学习路线·ai工程
ZhengEnCi8 小时前
Agent 规则管理:让 Memory 做索引、让 Skill 存规则——上下文上限实测与分工方案
后端