【简码短链】使用Selenium实现UI自动化测试

news2024/11/26 6:13:01

1.环境准备

Chrome浏览器 版本为版本 129.0.6668.90(正式版本) (64 位)
在这里插入图片描述

129版本的Chrome浏览器的驱动,将webdriver放到jdk所在的bin目录下
在命令行中输入:chromedriver验证是否成功
在这里插入图片描述
打开IDEA,创建Maven项目,在pom.xml导入所需要的依赖包

    <dependencies>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.22.0</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.16.1</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.10.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-suite</artifactId>
            <version>1.8.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

在这里插入图片描述
创建common包用于存在公共的类/方法
Tests目录下用来存放测试用例

对每个页面进行测试时都需要先创建浏览器驱动对象,因此可以把创建浏览器驱动的方法放到common下面,并使用单例模式保证浏览器驱动只被创建一次
添加隐式等待,确保页面元素能够渲染出来

public class AutoTestUtils {
    public ChromeDriver driver;
    // 获取驱动对象
    public ChromeDriver getChromeDriver(){
        if (driver == null){
            driver = new ChromeDriver();
            driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
        }
        return driver;
    }
}

添加屏幕截图功能

    public static List<String> getTime(){
        SimpleDateFormat sim1 = new SimpleDateFormat("yyyyMMdd-HHmmssSS");
        String filename = sim1.format(System.currentTimeMillis());

        SimpleDateFormat sim2 = new SimpleDateFormat("yyyyMMdd");
        String dirname = sim2.format(System.currentTimeMillis());
        List<String> list = new ArrayList<>();
        list.add(dirname);
        list.add(filename);
        return list;
    }
    public static void getScreenShor(String str) throws IOException {
        List<String> list = getTime();
        String filename = "./src/test/java/com/hyacinth/shortlinkAutoTest/"+list.get(0)+"/"+str+"_"+list.get(1)+".png";
        File srcfile = driver.getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(srcfile,new File(filename));
    }

登录页面

测试用例页面如下:
在这里插入图片描述
首先在登录页面测试类中定义一个浏览器驱动对象,用来获取浏览器驱动

    public static ChromeDriver driver = getChromeDriver();

因为每次都需要打开登录页面,因此定义一个方法打开登录页面,并使用@BeforeAll注解,让测试每次开始前都打开登录页面,通过调用get方法,可以导航到网页,为接下来的测试准备页面环境。

    @BeforeAll
    static void baseContor(){
        driver.get("http://www.shorturl.cloud/login");
    }

正常登录的测试:

     @ParameterizedTest
     @CsvSource({"test,test1234","admin,admin123456"})
    void loginSuccess(String username,String password) throws InterruptedException {
         driver.findElement(By.xpath("//*[@id=\"el-id-7439-8\"]")).clear();
         driver.findElement(By.xpath("//*[@id=\"el-id-7439-8\"]")).sendKeys(username);

         driver.findElement(By.xpath("//*[@id=\"el-id-7439-9\"]")).clear();
         driver.findElement(By.xpath("//*[@id=\"el-id-7439-9\"]")).sendKeys(password);
         driver.findElement(By.cssSelector("#app > div.login-page > div.login-box > div.logon > form > div.btn-gourp > div:nth-child(2) > button > span")).click();
         // 对登录结果进行检测
        driver.findElement(By.xpath("//*[@id=\"app\"]/div/section/main/div/div/div[1]/div[1]/div[1]"));
        driver.navigate().back();
    }

异常登录测试:

    @ParameterizedTest
    @CsvSource({"admin,123123123","user","admin123456",",admin123456","admin,"})
    void loginFail(String username,String password){
        driver.findElement(By.xpath("//*[@id=\"el-id-7439-8\"]")).clear();
        driver.findElement(By.xpath("//*[@id=\"el-id-7439-8\"]")).sendKeys(username);

        driver.findElement(By.xpath("//*[@id=\"el-id-7439-9\"]")).clear();
        driver.findElement(By.xpath("//*[@id=\"el-id-7439-9\"]")).sendKeys(password);
        driver.findElement(By.cssSelector("#app > div.login-page > div.login-box > div.logon > form > div.btn-gourp > div:nth-child(2) > button > span")).click();
        // 对登录结果进行检测
        driver.findElement(By.cssSelector("#app > div.login-page > div.login-box > div.logon > form > div.btn-gourp > div:nth-child(2) > button > span"));
        driver.navigate().refresh();
    }

注册页面

注册页面测试用例如下:
在这里插入图片描述

注册页面同样要先进入登录页面,使用@BeforeAll注解,让测试每次开始前都打开登录页面,通过调用get方法,为接下来的测试准备页面环境。

    @BeforeAll
    static void baseContor(){
        driver.get("http://www.shorturl.cloud");
    }

检查注册页面正常显示

    @Test
    void loginPageLoadRight() throws InterruptedException {
        // 检查 简码短链标题
        driver.findElement(By.xpath("//*[@id=\"app\"]/div[1]/h1"));
        // 检查 用户注册文本
        driver.findElement(By.cssSelector("#app > div.login-page > div.login-box > div.register > h2"));
        // 检查 登录按钮
        driver.findElement(By.cssSelector("#app > div.login-page > div.login-box > div.register > form > div.btn-gourp > div:nth-child(2) > button"));
    }

正常注册

    @ParameterizedTest
    @CsvSource({"user1,user1@qq.com,13453498765,user1,123123123","user2,user2@qq.com,13456498765,,123123123"})
    void registerSuccessTest(String username, String email, String phone, String name, String password){
        driver.findElement(By.cssSelector("#app > div.login-page > div.login-box > div.register > form > div.el-form-item.is-error.is-required.asterisk-left > div > div.el-input.el-input-group.el-input-group--prepend.el-input--suffix > div.el-input__wrapper")).sendKeys(username);
        driver.findElement(By.cssSelector("#email")).clear();
        driver.findElement(By.cssSelector("#email")).sendKeys(email);

        driver.findElement(By.cssSelector("#phone")).clear();
        driver.findElement(By.cssSelector("#phone")).sendKeys(phone);

        driver.findElement(By.cssSelector("#name")).clear();
        driver.findElement(By.cssSelector("#name")).sendKeys(name);

        driver.findElement(By.cssSelector("#phone")).clear();
        driver.findElement(By.cssSelector("#phone")).sendKeys(phone);
        // 点击注册
        driver.findElement(By.cssSelector("#app > div.login-page > div.login-box > div.register > form > div.btn-gourp > div:nth-child(2) > button")).click();
        // 验证注册是否成功
        driver.findElement(By.xpath("//*[@id=\"app\"]/div/section/main/div/div/div[2]/div/div[1]/div/button[1]"));
        // 返回
        driver.navigate().back();
    }

异常注册
由于这里测试的数据比较多,可以使用csv文件存放测试数据,使用@CsvFileSource注解来读取文件中的内容

    @ParameterizedTest
    @CsvFileSource(files = "C:\\Users\\wqe\\Desktop\\example.csv")
    void registerLoginFailTest(String username, String email, String phone, String name, String password){
        driver.findElement(By.cssSelector("#app > div.login-page > div.login-box > div.register > form > div.el-form-item.is-error.is-required.asterisk-left > div > div.el-input.el-input-group.el-input-group--prepend.el-input--suffix > div.el-input__wrapper")).sendKeys(username);
        driver.findElement(By.cssSelector("#email")).clear();
        driver.findElement(By.cssSelector("#email")).sendKeys(email);

        driver.findElement(By.cssSelector("#phone")).clear();
        driver.findElement(By.cssSelector("#phone")).sendKeys(phone);

        driver.findElement(By.cssSelector("#name")).clear();
        driver.findElement(By.cssSelector("#name")).sendKeys(name);

        driver.findElement(By.cssSelector("#phone")).clear();
        driver.findElement(By.cssSelector("#phone")).sendKeys(phone);
        // 点击注册
        driver.findElement(By.cssSelector("#app > div.login-page > div.login-box > div.register > form > div.btn-gourp > div:nth-child(2) > button")).click();
        // 验证注册是否成功
        driver.findElement(By.cssSelector("#app > div.login-page > div.login-box > div.register > h2"));
    }

主页面测试

因为进入主页需要登录,所以这里的测试用例执行要在登录之后.
每次测试前都要进行主页之后,和前面一样使用@BeforeAll注解进行设置

    public static ChromeDriver driver = getChromeDriver();
    @BeforeAll
    static void baseContor(){
        driver.get("http://shorturl.cloud/home/space");
    }

主页正常显示:

    @Test
    void HomePageLoadRight(){
        driver.findElement(By.cssSelector("#app > div > section > header > div > div.logo"));
        driver.findElement(By.xpath("//*[@id=\"app\"]/div/section/main/div/div/div[1]/div[1]/div[1]"));
        driver.findElement(By.xpath("//*[@id=\"app\"]/div/section/main/div/div/div[1]/div[2]/div"));
    }

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Gridview配置数据源--信任服务器证书

目录 背景过程Gridview配置数据源GridView与数据源&#xff1a;数据库连接与安全&#xff1a;信任服务器证书&#xff1a;配置信任服务器证书&#xff1a;注意事项&#xff1a; 生成连接字符串程序运行报错问题解决 总结 背景 Gridview配置数据源之后&#xff0c;程序报错 过…

前端编程艺术(4)---JavaScript进阶(vue前置知识)

目录 1.变量和常量 2.模版字符串 3.对象 4.解构赋值 1.数组的解构 2.对象的解构 5.箭头函数 6.数组和对象的方法 7.扩展运算符 8.Web存储 9.Promise 10.AsyncAwait 11.模块化 1.变量和常量 JavaScript 中的变量和常量是用于存储数据的标识符。变量可以被重新赋值&am…

[Linux] Linux 初识进程地址空间 (进程地址空间第一弹)

标题&#xff1a;[Linux] Linux初识进程地址空间 个人主页水墨不写bug &#xff08;图片来源于AI&#xff09; 目录 一、什么是进程地址空间 二、为什么父子进程相同地址的变量的值不同 三、初识虚拟地址、页表 一、什么是进程地址空间 其实&#xff0c;在很久之前&#xf…

数据结构之树(3)

一、森林和树的转换 重要&#xff01; 树->二叉树 由于孩子兄弟链式存储和二叉树链式存储本质相同&#xff0c;故树可转换为二叉树。 森林->二叉树 森林&#xff1a;m棵互不相交的树的集合 森林->树 树->二叉树 森林中各个树的根节点之间视为兄弟关系 二、树…

ORB-SLAM复现时遇到的问题(复现失败,切莫当做教程)

背景 本人的环境&#xff1a;使用ubuntu20.04&#xff0c;opencv4 问题 进行Build DBoW2. Go into Thirdparty/DBoW2/ and execute:时&#xff0c;运行make时出错 我安装的opencv4&#xff0c;在 OpenCV 3 和更高版本中&#xff0c;头文件的路径可能已更改。例如&#xff0…

科普篇--- 什么是硬件在环测试?

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消耗你的人和事&#xff0c;多看一眼都是你的不…

线程安全的单例模式 | 可重入 | 线程安全 |死锁(理论)

&#x1f308;个人主页&#xff1a; 南桥几晴秋 &#x1f308;C专栏&#xff1a; 南桥谈C &#x1f308;C语言专栏&#xff1a; C语言学习系列 &#x1f308;Linux学习专栏&#xff1a; 南桥谈Linux &#x1f308;数据结构学习专栏&#xff1a; 数据结构杂谈 &#x1f308;数据…

业务封装与映射 -- OTUk/ODUk/OPUk比特速率和容量

介绍OTUk&#xff0c;ODUk&#xff0c;OPUk&#xff0c;OTUCn&#xff0c;ODUCn&#xff0c;OPUCn的比特速率和容量。 OTN支持超100 Gbit/s&#xff0c;100 Gbit/s&#xff0c;40 Gbit/s&#xff0c;10 Gbit/s&#xff0c;2.5 Gbit/s&#xff0c;1.25 Gbit/s等多种线路速率。 …

SAP MM学习笔记 - 豆知识10 - OMSY 初期化会计期间,ABAP调用MMPV/MMRV来批量更新会计期间(TODO)

之前用MMRV&#xff0c;MMPV来一次一个月来修改会计期间。 如果是老的测试机&#xff0c;可能是10几年前的&#xff0c;一次1个月&#xff0c;更新到当前期间&#xff0c;搞个100多次&#xff0c;手都抖。 SAP MM学习笔记 - 错误 M7053 - Posting only possible in periods 2…

Python水循环标准化对比算法实现

&#x1f3af;要点 算法区分不同水循环数据类型&#xff1a;地下水、河水、降水、气温和其他&#xff0c;并使用相应标准化降水指数、标准化地下水指数、标准化河流水位指数和标准化降水蒸散指数。绘制和计算特定的时间序列比较统计学相关性。使用相关矩阵可视化集水区和显示空…

每日OJ题_牛客_最长无重复子数组_滑动窗口_C++_Java

目录 牛客_最长无重复子数组_滑动窗口 题目解析 C代码1暴力 C代码2滑动窗口 Java代码滑动窗口 牛客_最长无重复子数组_滑动窗口 最长无重复子数组_牛客题霸_牛客网 (nowcoder.com) 描述&#xff1a; 给定一个长度为n的数组arr&#xff0c;返回arr的最长无重复元素子数组…

【Linux】Ubuntu20.04上使用RabbitVCS的图形化SVN

文章目录 1、RabbitVCS1.1、RabbitVCS 介绍1.2、RabbitVCS 主要功能1.3、Ubuntu下 TortoiseSVN 替代者 2、安装2.1、命令安装2.2、安装使用2.3、使用权限 3、解决SVN无法保存密码问题3.1、问题描述3.2、解决方法 1、RabbitVCS 1.1、RabbitVCS 介绍 它是一款Linux系统下的图形…

jsencrypt实现js加密的另外一种方式(使用node-jsencrypt库)

在上一篇文章中&#xff0c;实现了使用jsencrypt模块RSA加密实现。 参考链接&#xff1a;记录使用crypto-js、jsencrypt实现js加密的方法-CSDN博客 在实现的过程中&#xff0c;会提示出错&#xff1a;ReferenceError: window is not defined &#xff0c;而且需要修改jsencry…

网站建设开发方法

在这个充满激烈竞争的网络世界&#xff0c;如何通过网站建设开发&#xff0c;打造一个引人注目、功能强大的在线空间&#xff0c;成为了许多人关注的焦点。 1. 初衷与定位&#xff1a; 在进行网站建设开发之前&#xff0c;首先需要明确网站的初衷和定位。是作为企业的官方展示…

AcWing 662:点的坐标 ← 结构体 or 三目运算符

【题目来源】https://www.acwing.com/problem/content/664/【题目描述】 给定两个保留一位小数的浮点数 X,Y&#xff0c;用来表示一个点的横纵坐标。 请你判断该点在坐标系中的位置。 【输入格式】 共一行&#xff0c;包含两个浮点数 X,Y&#xff0c;表示点的横纵坐标。【输出格…

ElasticSearch备考 -- Async search

一、题目 通过异步方式查询earthquakes索引下Magnitude大于5的数据 二、思考 正常的查询大家可能会用的多一点&#xff0c;这种异步查询为数据量比较大的查询在后台执行&#xff0c;不用同步等待结果&#xff0c;待执行完成在获取结果。 三、解题 Step 1、准备基础数据 # D…

【CV】带你跑通过线检测项目unbox_yolov5_deepsort_counting

文章目录 &#x1f315;运行结果&#x1f315;我的配置&#x1f315;下载项目&#x1f315;安装依赖&#x1f319;创建激活虚拟环境&#x1f319;pip install -r requirements.txt &#x1f315;确保有参数ckpt.t7和测试数据集test.mp4&#x1f315;运行&#x1f319;出现报错T…

Leecode热题100-560.和为k的子数组

给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2示例 2&#xff1a; 输入&#xff1a;nums [1,2,3], k…