【软件测试】基于博客系统的自动化测试

目录

1.我的博客系统链接

2.使用selenium对博客系统进行自动化测试

1.引入依赖

2.创建公共类

3.创建测试套件类

4.测试登陆界面

5. 测试博客列表页

6.测试写博客页面

7.测试删除博客

8.最终运行结果


1.我的博客系统链接

用户登录

2.使用selenium对博客系统进行自动化测试

1.引入依赖

创建一个maven项目,在pop.xml中引入以下依赖

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.141.59</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.9.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-params -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>5.9.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-suite -->
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-suite</artifactId>
            <version>1.9.1</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-suite -->
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-suite</artifactId>
            <version>1.9.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.9.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

2.创建公共类

因为对每一个页面进行测试都需要创建浏览器驱动,所以我们可以把他提取出来并设置成静态的,就可以让创建和销毁驱动的操作只实现一次,其他类都继承这个类即可

package org.example.common;

import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;
import java.util.concurrent.TimeUnit;

public class AutotestUtils {

    private static ChromeDriver driver;

    public static ChromeDriver createDrive() {
        if (driver == null) {
            driver = new ChromeDriver();
            // 显示等待, 渲染页面, 防止找不到页面元素
            driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
        }
        return driver;
    }
}

3.创建测试套件类

创建一个类,通过@Suite注解识别该类为测试套件类,使用@SelectClasses来注解声明我们要运行哪些类

package org.example.tests;

import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;

@Suite
@SelectClasses({loginTest.class, BlogListTest.class, BlogEditTest.class})
public class RunSuite {

}

4.测试登陆界面

创建一个类继承AutTestUtils类得到浏览器驱动,然后开始测试

package org.example.tests;


import org.example.common.AutotestUtils;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;

import static java.lang.Thread.sleep;


@TestMethodOrder(MethodOrderer.OrderAnnotation.class)// 按顺序执行
public class loginTest extends AutotestUtils {
    public static ChromeDriver driver = createDrive();

    /**
     * 打开网页
     */
    @Test
    @BeforeAll
    static void init() {
        // 跳转到登陆界面
        driver.get("http://8.130.122.250:8080/blog/blog_login.html");
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
    }

    /**
     * 检测登陆页面是否正常打开
     */
    @Test
    @Order(1)
    void loginPageTest() {
        // 显示等待
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 用断言判断用户登陆是否显示正确
        String expect = "用户登录";
        String actual = driver.findElement(By.cssSelector("body > div.login-container > form > div > div.title")).getText();
        Assertions.assertEquals(expect, actual);
        // 检查提交按钮是否存在
        driver.findElement(By.cssSelector("#btn_login_submit"));
    }

    /**
     * 异常登陆测试
     */
    @Order(2)
    @ParameterizedTest
    @CsvSource({"张三, 12346","李四, 1236"})
    public void loginAbnormal(String username, String password) throws InterruptedException {
        driver.get("http://8.130.122.250:8080/blog/blog_login.html");
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        //清空用户名和密码框
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        // 输入账号和密码
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        driver.findElement(By.cssSelector("#password")).sendKeys(password);
        driver.findElement(By.cssSelector("#btn_login_submit")).click();
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        // 与期望结果对比
        String expect = "用户名或密码不正确";
        // 强制等待
        sleep(2000);
        // 获取弹窗文本
        String actual = driver.switchTo().alert().getText();
        // 点击弹窗确认按钮
        driver.switchTo().alert().accept();
        Assertions.assertEquals(expect, actual);
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
    }

    /**
     * 正常登陆测试
     */
    @Order(3)
    @ParameterizedTest
    @CsvSource({"张三, 123456","李四, 123456"})
    public void loginNormalTest(String username, String password) {
        driver.get("http://8.130.122.250:8080/blog/blog_login.html");
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        //清空用户名和密码框
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        // 输入账号和密码
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        driver.findElement(By.cssSelector("#password")).sendKeys(password);
        driver.findElement(By.cssSelector("#btn_login_submit")).click();
        driver.navigate().back();
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
    }
}

5. 测试博客列表页

步骤同上

package org.example.tests;

import org.example.common.AutotestUtils;
import org.junit.jupiter.api.*;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.concurrent.TimeUnit;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogListTest extends AutotestUtils {

    // 获取驱动
    private static ChromeDriver driver = createDrive();

    /**
     * 打开网页
     */
    @BeforeAll
    public static void openWeb() {
        driver.get("http://8.130.122.250:8080/blog/blog_list.html");
    }

    /**
     * 测试博客列表显示是否正常
     */
    @Order(1)
    @Test
    void elementAppear() {
        driver.get("http://8.130.122.250:8080/blog/blog_list.html");
        // 判断登录用户为李四
        String actualUsername = driver.findElement(By.cssSelector("#h_list_username")).getText();
        String username = "李四";
        Assertions.assertEquals(actualUsername, username);
        // 判断标题不为空
        String title = driver.findElement(By.cssSelector("body > div.container > div.container-right > div:nth-child(1) > div.blog-title")).getText();
        Assertions.assertNotNull(title);
        // 判断登录url
        String url = "http://8.130.122.250:8080/blog/blog_list.html";
        String actualUrl = driver.getCurrentUrl();
        Assertions.assertEquals(url, actualUrl);
    }

    /**
     * 测试按钮
     */
    @Test
    @Order(2)
    public void buttonTest() {
        // 查看全文按钮测试
        driver.findElement(By.cssSelector("body > div.container > div.container-right > div:nth-child(1) > div.aEl > a")).click();
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        driver.navigate().back();

    }
}

6.测试写博客页面

注释中有详细步骤

package org.example.tests;

import org.example.common.AutotestUtils;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.concurrent.TimeUnit;

import static java.lang.Thread.sleep;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogEditTest extends AutotestUtils {


    static ChromeDriver driver = createDrive();
    /**
     * 打开博客编辑页
     */
    @BeforeAll
    static void openWeb() {
        driver.get("http://8.130.122.250:8080/blog/blog_eidt.html");
    }

    /**
     * 错误发布测试
     */
    @Order(1)
    @ParameterizedTest
    @CsvSource({",正文"})
    void abnormalTest (String title, String content) throws InterruptedException {
        driver.get("http://8.130.122.250:8080/blog/blog_eidt.html");
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 输入测试
        ((JavascriptExecutor)driver).executeScript("document.querySelector(\"#title\").value="+title+"");
        driver.findElement(By.cssSelector("#submit")).click();
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 等弹窗出现
        sleep(1000);
        // 点击弹窗
        driver.switchTo().alert().accept();
        driver.navigate().back();
    }

    /**
     * 正确发布测试
     */
    @Order(2)
    @Test
    void normalTest() throws InterruptedException {
        // 点击按钮
        driver.findElement(By.cssSelector("body > div.nav > div > div > a:nth-child(2)")).click();
        sleep(8000);
        // 输入标题与正文
        String title = "自动化测试最终版2";
        driver.findElement(By.cssSelector("#title")).sendKeys(title);
        // 编辑器无法输入,使用一个能写出来符号的按钮替代
        driver.findElement(By.cssSelector("#blog_edit > div.editormd-toolbar > div > ul > li:nth-child(5) > a > i")).click();
        sleep(1000);
        // 点击提交
        driver.findElement(By.cssSelector("#submit")).click();
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 强制等待弹窗
        sleep(1000);
        // 点击弹窗,是否为发布成功
        String expect = "发布成功";
        String actual = driver.switchTo().alert().getText();
        driver.switchTo().alert().accept();
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 查看跳转页面是否为博客列表界面
        String url = "http://8.130.122.250:8080/blog/blog_list.html";
        String actualUrl = driver.getCurrentUrl();
        Assertions.assertEquals(url, actualUrl);
        // 查看第一条博客标题是否为刚才所发
        String actualTitle = driver.findElement(By.cssSelector("body > div.container > div.container-right > div:nth-child(1) > div.blog-title")).getText();
        Assertions.assertEquals(title, actualTitle);
    }

    /**
     * 关闭浏览器
     */
    @AfterAll
    static void quit() {
        driver.quit();
    }
}

7.测试删除博客

因为删除博客的功能暂时没有完成,下次补上

8.最终运行结果

本篇博客就到这里啦!!我们下篇博客见~~

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

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

相关文章

Git时间:版本控制工具进阶

Git时间&#xff1a;版本控制工具进阶 忽略文件 Git允许用户将指定的文件或目录排除在版本控制之外&#xff0c;它会检查代码仓库的目录下是否存在一个名为.gitignore的文件&#xff0c;如果存在&#xff0c;就去一行行读取这个文件中的内容&#xff0c;并把每一行指定的文件…

【算法和数据结构】257、LeetCode二叉树的所有路径

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;首先看这道题的输出结果&#xff0c;是前序遍历。然后需要找到从根节点到叶子节点的所有路径&#xff…

C++笔记之vector的底层实现和扩容机制

C笔记之vector的底层实现和扩容机制 1. 先申请内存空间&#xff0c;内存空间容量变成原来的n倍(一般是原来的两倍) 2. 将原本容器中的数据拷贝到新的内存空间中 3. 释放原来的内存空间 4. 将数组指针指向新容器的内存空间 code review! 文章目录 C笔记之vector的底层实现和扩…

秒级体验本地调试远程 k8s 中的服务

点击上方蓝色字体&#xff0c;选择“设为星标” 回复”云原生“获取基础架构实践 背景 在这个以k8s为云os的时代&#xff0c;程序员在日常的开发过程中&#xff0c;肯定会遇到各种问题&#xff0c;比如&#xff1a;本地开发完&#xff0c;需要部署到远程k8s集群&#xff0c;本地…

LLaMA模型论文《LLaMA: Open and Efficient Foundation Language Models》阅读笔记

文章目录 1. 简介2.方法2.1 预训练数据2.2 网络架构2.3 优化器2.4 高效的实现 3.论文其余部分4. 参考资料 1. 简介 LLaMA是meta在2023年2月开源的大模型&#xff0c;在这之后&#xff0c;很多开源模型都是基于LLaMA的&#xff0c;比如斯坦福大学的羊驼模型。 LLaMA的重点是比…

观察者模式、中介者模式和发布订阅模式

观察者模式 定义 观察者模式定义了对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都将得到通知&#xff0c;并自动更新 观察者模式属于行为型模式&#xff0c;行为型模式关注的是对象之间的通讯&#xff0c;观察者模式…

iOS--通知、代理、单例模式总结

通知 概要 观察者和被观察者都无需知晓对方&#xff0c;只需要通过标记在NSNotificationCenter中找到监听该通知所对应的类&#xff0c;从而调用该类的方法。并且在NSNotificationCenter中&#xff0c;观察者可以只订阅某一特定的通知&#xff0c;并对齐做出相应操作&#xf…

Ros终端出现找不到bash: /home/***/devel/setup.bash: 没有那个文件或目录

现象&#xff1a;Ros终端出现找不到bash: /home/***/devel/setup.bash: 没有那个文件或目录 问题&#xff1a;配置时路径写错 解决方法&#xff1a;改正路径 1.打开文件 gedit ~/.bashrc2.修改正确路径

解决分类任务中数据倾斜问题

大家好&#xff0c;在处理文本分类任务时&#xff0c;基准测试流行的自然语言处理架构的性能是建立对可用选项的理解的重要步骤。在这里&#xff0c;本文将深入探讨与分类相关的最常见的挑战之一——数据倾斜。如果你曾经将机器学习&#xff08;ML&#xff09;应用于真实世界的…

IDEA 使用 maven 搭建 spring mvc

1. 创建项目 1.1 创建成功之后配置 Spring MVC 1.2 勾选 Spring MVC 2.更改配置文件 2.1 更改web.xml配置 更改为 <servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/</url-pattern></servlet-mapping>2.2 dispat…

数据结构基础:3.单链表的实现。

单链表的介绍和实现 一.基本概念1.基本结构2.结构体节点的定义&#xff1a; 二.功能接口的实现0.第一个节点&#xff1a;plist1打印链表2创建一个节点3.头插4.头删5.尾插6.尾删7.查找8.在pos之前插入x9.在pos之后插入x10.删除pos位置11.删除pos的后一个位置12.链表释放 三.整体…

leetcode743. 网络延迟时间 floyd

https://leetcode.cn/problems/network-delay-time/ 有 n 个网络节点&#xff0c;标记为 1 到 n。 给你一个列表 times&#xff0c;表示信号经过 有向 边的传递时间。 times[i] (ui, vi, wi)&#xff0c;其中 ui 是源节点&#xff0c;vi 是目标节点&#xff0c; wi 是一个信…

SpringBoot使用PropertiesLauncher加载外部jar包

启用SpringBoot的PropertiesLauncher 使用SpringBoot的PropertiesLauncher可以优先加载外部的jar文件, 这样可以在程序运行前替换jar包, 官方文档: Launching Executable Jars 使用演示 建立一个SpringBoot工程, 工程中依赖一个叫自定义的utils包, 版本是1.0.0, 通过http接口…

LiveGBS流媒体平台GB/T28181功能-支持轮巡播放分屏轮巡值守播放监控视频轮播大屏轮询播放

LiveGBS支持轮巡播放分屏轮巡值守播放监控视频轮播大屏轮询播放 1、背景2、分屏展示3、选择轮播通道4、配置轮播间隔(秒)5、点击开始轮播6、轮播停止及全屏7、搭建GB28181视频直播平台 1、背景 视频监控项目使用过程中&#xff0c;有时需要大屏值守&#xff0c;值守的时候多分…

Sestra 实用教程(二)方程求解器

目 录 一、前言二、超单元分析三、惯性释放四、模态叠加法4.1 Eigenvalue solvers4.2 Static back substitution 五、模态综合法六、Master-Slave七、参考文献 一、前言 SESAM &#xff08;Super Element Structure Analysis Module&#xff09;是由挪威船级社&#xff08;DNV-…

mac m1安装Centos9

先看结果&#xff08;在mac M1 安装centos8 安装不成功的原因大部分是没有找到正确的系统&#xff09; 由于Cnetos8 停服&#xff0c;现有mac m1 上能够按照的Centos8 并非由官方发布&#xff0c;因此寻找官方发布的能够在mac m1上安装的centos版本。 在YouTuBe上找到一个视频…

redis突然变慢问题定位

CPU 相关&#xff1a;使用复杂度过高命令、数据的持久化&#xff0c;都与耗费过多的 CPU 资源有关 内存相关&#xff1a;bigkey 内存的申请和释放、数据过期、数据淘汰、碎片整理、内存大页、内存写时复制都与内存息息相关 磁盘相关&#xff1a;数据持久化、AOF 刷盘策略&…

IntelliJ IDEA 2023.2 最新变化

主要更新 AI Assistant 限定访问 Ultimate 在此版本中&#xff0c;我们为 IntelliJ IDEA 引入了一项重要补充 – AI Assistant。 AI Assistant 当前具备一组由 AI 提供支持的初始功能&#xff0c;提供集成式 AI 聊天&#xff0c;可以完成一些任务&#xff0c;例如自动编写文档…

[JAVAee]定时器

目录 定时器的含义 定时器的使用 定时器的解析 ①TaskQueue ​②TimerThread ③Timer 定时器的模拟实现 ①创建Task自定义类型 ②创建TimerThread类 ③Timer类 完整代码 定时器的含义 从名字上看,就是我们通俗理解的那个定时器.设置一定的时间,并在一定的时间后发生…

01 矩阵(力扣)多源广度优先搜索 JAVA

给定一个由 0 和 1 组成的矩阵 mat &#xff0c;请输出一个大小相同的矩阵&#xff0c;其中每一个格子是 mat 中对应位置元素到最近的 0 的距离。 两个相邻元素间的距离为 1 。 输入&#xff1a;mat [[0,0,0],[0,1,0],[0,0,0]] 输出&#xff1a;[[0,0,0],[0,1,0],[0,0,0]] 输入…