【测试报告】个人博客系统自动化测试报告

文章目录

  • 项目背景
  • 项目功能
  • 测试计划
    • 功能测试
      • 测试用例
      • 执行测试的操作步骤
    • 自动化测试
      • 设计的模块、自动化运行的结果、问题定位的结果
      • 自动化测试优点

项目背景

        对于一个程序员来说,定期整理总结并写博客是不可或缺的步骤,不管是对近期新掌握的技术或者是遇到bug解决bug过程的记录等,都是非常有必要的。
        目前的博客网站有很多,比如CSDN、掘金、博客园等。本人在整个学习的阶段也都会经常在上面发布文章和见解等,最近学了一些开发所需要的主流框架,因此以做项目代学,做出了一个简易版的个人博客系统。

项目功能

        博客系统中最基本的用户管理、文章管理(增删改查等)都有涉及,此外在这个博客系统中不需要担心安全问题(因为用户密码采用了加盐加密处理,破解成本高,且在一些私人界面加入了拦截器等)、短时间内不需要重复登录(因为在redis中存储了用户的session信息并进行了持久化处理)、可以随时随地地更换自己喜欢的头像(因为上传的图片发送到服务器并使用Nginx存储起来,稍等一段时间后台刷新后即可看到换的头像)。

测试计划

功能测试

测试用例

在这里插入图片描述
        测试的第一步永远都是测试用例的编写,这里对这个项目中的功能使用脑图进行测试用例的编写。

执行测试的操作步骤

登录页:
(1)账号或密码为空:
在这里插入图片描述
(2)账号或密码填写错误:
在这里插入图片描述
(3)正确登录跳转到个人列表页:
在这里插入图片描述
个人列表页:
(1)正常登录状态下:
在这里插入图片描述
(2)未登录的状态下输入url - http://43.139.71.60:8081/myblog_list.html(跳转到登录页):
在这里插入图片描述
博客列表页:
(1)在未登录的情况下(只有登录按钮):
在这里插入图片描述
(2)在登录的状态下(有三个按钮选择):
在这里插入图片描述
博客详情页:
(1)在未登录的情况下(只读):
在这里插入图片描述
(2)在登录root账号下打开cxz的文章(只读):
在这里插入图片描述
(3)在cxz账户下打开自己的文章(可删除、修改):
在这里插入图片描述
博客编辑页:
(1)未登录的状态下(提示失败并跳转到登录页):
在这里插入图片描述
(2)登录的状态下(提示成功并跳转到个人列表页):
在这里插入图片描述
在这里插入图片描述

自动化测试

        重点还是自动化测试。编写自动化代码通常是需要根据编写的测试用例来进行的,但是由于时间关系,本自动化测试对部分主要功能进行编写,如分页、更换头像等没有在范围内,但是这些基本上都是类似的,这里就以部分为例。

设计的模块、自动化运行的结果、问题定位的结果

环境:
编译器:IDEA 2021.3.2
浏览器:Microsoft Edge 113.0.1774.57
驱动程序:msedgedriver.exe(具体在官网选择当前浏览器对应的版本的驱动即可)
自动化测试工具:selenium4
自动化测试框架:junit5
以上对应的依赖包:

        <!--    自动化测试    -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.0.0</version>
        </dependency>

        <!--    保存屏幕截图文件    -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

        <!--    junit5     -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.8.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>

        由于驱动对象是在一开始就创建的,且全局只用这一个,所以我们可以将它封装起来并用static来修饰:

    public static EdgeDriver driver;

    //创建驱动对象
    public static EdgeDriver createDriver(){
        if(driver == null){
            EdgeOptions options = new EdgeOptions();
            options.addArguments("--remote-allow-origins=*");
            driver = new EdgeDriver(options);

            //创建隐式等待
            driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
        }
        return driver;
    }

登录页:
        首先测试页面是否正常显示,此外需要测试两种情况:一是正常登录的情况;二是异常登录的情况。
        对于异常登录,这里简单测试一组数据,并将报错信息返回回来;对于正常登录,这里测试两组数据。测试登录都使用参数化,也就是以下两个注解:

    @ParameterizedTest
    @CsvSource({"root, 123"})

在这里插入图片描述

package com.blogWebAutoTest.Tests;

import com.blogWebAutoTest.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.edge.EdgeDriver;

import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Administrator
 * Date: 2023-05-30
 * Time: 15:16
 */
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class blogLoginTest extends autoTestUtils {
    public static EdgeDriver driver;

    @BeforeAll
    static private void baseControl(){
        driver = createDriver();
        driver.get("http://43.139.71.60:8081/login.html");
    }

    /*
    * 页面是否正确打开
    * 检查点:主页、注册元素是否存在
    * */
    @Test
    @Order(1)
    public void loginPageLoadRight() throws IOException {
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)"));
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)"));
        getScreenShot(getClass().getName());
    }

    /*
    * 检查正常登录情况
    * */
    @ParameterizedTest
    @CsvSource({"root, 123456"})
    @Order(3)
    public void loginSuccess(String username, String password) throws InterruptedException, IOException {
        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("#submit")).click();
        //对登录结果进行检查
//        Thread.sleep(3000);
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)"));
        getScreenShot(getClass().getName());
        driver.navigate().back();
//        Thread.sleep(3000);
    }

    /*
    * 检查异常的登录情况
    * */
    @ParameterizedTest
    @CsvSource({"root, 123"})
    @Order(2)
    public void loginFail(String username, String password) throws IOException, InterruptedException {
        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("#submit")).click();
        //对登录结果进行检查
        Thread.sleep(3000);
        System.out.println(driver.switchTo().alert().getText());
        driver.switchTo().alert().accept();
        getScreenShot(getClass().getName());
//        Thread.sleep(3000);
    }
}

个人列表页:
        通过页面的共同元素看页面是否正常打开。

package com.blogWebAutoTest.Tests;

import com.blogWebAutoTest.common.autoTestUtils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.edge.EdgeDriver;

import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Administrator
 * Date: 2023-05-30
 * Time: 15:16
 */
public class blogListTest extends autoTestUtils {
//    public static EdgeDriver driver;

    @BeforeAll
    static private void baseControl(){
//        driver = createDriver();
        driver.get("http://43.139.71.60:8081/myblog_list.html");
    }

    /*
     * 页面是否正确打开
     * 检查点:创作数、访问量、写博客元素是否存在
     * */
    @Test
    public void loginPageLoadRight() throws IOException {
        driver.findElement(By.cssSelector("body > div.container > div.container-left > div > div:nth-child(5) > span:nth-child(1)"));
        driver.findElement(By.cssSelector("body > div.container > div.container-left > div > div:nth-child(5) > span:nth-child(2)"));
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)"));
        getScreenShot(getClass().getName());
    }
}

博客编辑页:
        首先测试页面是否正常显示,此外需要测试写的博客能否正常提交,这里就可以使用到断言(无论结果显示的是否是“提交成功!”,都可以执行通过,不会出现报错的情况,这也是自动化测试的要求)。
在这里插入图片描述

package com.blogWebAutoTest.Tests;

import com.blogWebAutoTest.common.autoTestUtils;
import org.junit.jupiter.api.*;
import org.openqa.selenium.By;

import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Administrator
 * Date: 2023-05-30
 * Time: 15:17
 */
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class blogEditTest extends autoTestUtils {
    //    public static EdgeDriver driver;

    @BeforeAll
    static private void baseControl(){
//        driver = createDriver();
        driver.get("http://43.139.71.60:8081/blog_edit.html");
    }

    /*
     * 页面是否正确打开
     * 检查点:主页、我的博客、退出登录元素是否存在
     * */
    @Test
    @Order(1)
    public void loginPageLoadRight() throws IOException {
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)"));
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)"));
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)"));
        getScreenShot(getClass().getName());
    }

    @Test
    @Order(2)
    public void editAndSubmitBlog() throws IOException, InterruptedException {
        driver.findElement(By.cssSelector("#title")).sendKeys("测试执行自动化测试脚本");
        driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(21) > a > i")).click();
        driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(12) > a > i")).click();
        driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(12) > a > i")).click();
        driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(12) > a > i")).click();
        driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(12) > a > i")).click();
        driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(21) > a > i")).click();
        driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(13) > a > i")).click();
        driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(13) > a > i")).click();
        driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(21) > a > i")).click();
        driver.findElement(By.cssSelector("body > div.blog-edit-container > div.title > button")).click();
        Thread.sleep(3000);
        Assertions.assertEquals("提交成功!", driver.switchTo().alert().getText());
        driver.switchTo().alert().accept();
        getScreenShot(getClass().getName());
    }
}

引入截图功能:
        由于自动化执行的速度是比较快的,所以中间过程是比较难看到的,因此我们可以使用截图并保存来看:
在这里插入图片描述
在这里插入图片描述
        图片不能单纯地命名为固定的,因为这样会造成覆盖的情况,也就是说之前截的图片会被覆盖掉,比较主流、合理的方法是使用时间戳来命名,更严谨的是按照日期来建文件夹,按照当前时间来取文件名的形式,避免重名的情况。

    //使用时间戳动态生成图片名
    public List<String> getTime(){
        //以天的维度按照文件夹进行保存
        List<String> list = new ArrayList<>();
        SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyyMMdd-HHmmssSS");
        String dirname = simpleDateFormat1.format(System.currentTimeMillis());
        String filename = simpleDateFormat2.format(System.currentTimeMillis());
        list.add(dirname);
        list.add(filename);
        return list;
    }

    //获取屏幕截图,把所有用例结果保存下来(非常适用于无头模式)
    public void getScreenShot(String s) throws IOException {
        List<String> list = getTime();
        String filename = "./src/test/java/com/blogWebAutoTest/" + list.get(0) + "/" + s + "_" + list.get(1) + ".png";
        File file = driver.getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(file, new File(filename));
    }

博客详情页:
        博客详情页共同的元素是文章标题和发布时间,所以根据其来确定页面是否正常加载。
在这里插入图片描述

package com.blogWebAutoTest.Tests;

import com.blogWebAutoTest.common.autoTestUtils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;

import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Administrator
 * Date: 2023-05-30
 * Time: 15:17
 */
public class blogDetailTest extends autoTestUtils {
    //    public static EdgeDriver driver;

    @BeforeAll
    static private void baseControl(){
//        driver = createDriver();
        driver.get("http://43.139.71.60:8081/blog_content.html?id=18");
    }

    @Test
    public void blogDetailLoadRight() throws IOException {
        driver.findElement(By.cssSelector("#title"));
        driver.findElement(By.cssSelector("#data"));
        getScreenShot(getClass().getName());
    }

    @AfterAll
    private static void driverQuit(){
        driver.quit();
    }
}

        注意在最后需要使用@AfterAll注解来释放掉驱动对象,同样也是全局执行一次。


        实际上这个自动化涉及到的用例测试是非常少的,且很多功能都还没有测试全面,但其实也是大同小异。后面有时间会继续写完整后面的自动化代码,感兴趣的后面可以看完整代码:博客系统自动化测试代码(努力填坑中…)。

自动化测试优点

(1)使用了junit5框架中提供的注解,避免生成过多的对象,造成时间和资源的浪费,提高了自动化的执行效率。
(2)只创建一次驱动对象,避免每个用例重复创建驱动对象造成时间和资源的浪费。
(3)使用参数化,保持用例的简洁,提高代码的可读性,同时也方便存储大量数据的.csv文件导入。
(4)使用测试套件,降低自动化测试的工作量,因为通过套件就可以一次执行所有运行的测试用例。
(5)使用了隐式等待,提高了自动化的运行效率,提高了自动化的稳定性。
(6)加入了屏幕截图功能,方便在无头模式下追溯问题的位置。

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

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

相关文章

代码随想录算法训练营第五十三天 | 力扣 1143.最长公共子序列, 1035.不相交的线, 53. 最大子序和

1143.最长公共子序列 题目 1143. 最长公共子序列 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符…

SpringBoot——原理(自动配置+原理分析-源码跟踪)

源码跟踪 从Springboot的启动类进入&#xff0c;进行分析. 源码跟踪技巧 在以后接触各种框架的时候&#xff0c;如果需要查看源码&#xff0c;需要找到关键点和核心流程&#xff0c;先在宏观对整个原理和流程有一个认识&#xff0c;之后再去了解其中的细节。 按住Ctrl左键进…

怎么实现常用网络接口自动化测试框架应用?

一、RESTful&#xff08;resource representational state transfer)类型接口测试 (一&#xff09;GUI界面测试工具&#xff1a;jmeter 1、添加线程组 2、添加http请求 3、为线程组添加察看结果树 4、写入接口参数并运行 5、在查看结果树窗口查看结果 6、多组数据可增加CSVDat…

基于物理信息的神经网络(Physics-informed Neural Networks;PINNs)Part-1(简单介绍)

【摘要】 基于物理信息的神经网络&#xff08;Physics-informed Neural Networks&#xff0c;简称PINNs&#xff09;&#xff0c;是一类用于解决有监督学习任务的神经网络&#xff0c;它不仅能够像传统神经网络一样学习到训练数据样本的分布规律&#xff0c;而且能够学习到数学…

UFS 2 -UFS架构简介2

UFS 2 -UFS架构简介2 1 UFS架构简介1.1 System Boot and Enumeration1.2 UFS Interconnect (UIC) Layer1.2.1 UFS Physical Layer Signals1.2.2 MIPI UniPro1.2.3 MIPI UniPro Related Attributes 1.3 UFS Transport Protocol (UTP) Layer1.3.1 Architectural Model1.3.1.1 Cli…

图解max{X,Y}和min{X,Y}并求相关概率

图解max{X,Y}和min{X,Y}并求相关概率 对max{X,Y}或min{X,Y}进行分解再求解 P ( m a x { X , Y } ≥ c ) P [ ( X ≥ c ) ∪ ( Y ≥ c ) ] P ( m a x { X , Y } ≤ c ) P [ ( X ≤ c ) ∩ ( Y ≤ c ) ] P ( m i n { X , Y } ≥ c ) P [ ( X ≥ c ) ∩ ( Y ≥ c ) ] P ( m i…

k8s功能优势应用场景介绍(一)

一&#xff0c;K8S功能: 1、数据卷 pod中容器之间共享数据&#xff0c;可以使用数据卷 2、应用程序健康检查 容器内服务可能进程阻塞无法处理请求&#xff0c;可以设置监控检查策略保证应用健壮性 3、复制应用程序实例 控制器维护着pod副本数量&#xff0c;保证一个pod或一组同…

C++11 auto类型推导

1.类型推导 C11引入了auto 和 decltype 关键字实现类型推导&#xff0c;通过这两个关键字不仅能方便地获取复杂的类型&#xff0c;而且还能简化书写&#xff0c;提高编码效率。 auto 类型推导的语法和规则 在之前的 C 版本中&#xff0c;auto 关键字用来指明变量的存储类型…

Allure测试报告定制全攻略,优化你的Web自动化测试框架!

目录 前言&#xff1a; 1. Allure测试报告简介 2. Web自动化测试框架简介 3. 封装Web自动化框架 3.1 安装Selenium 3.2 封装Selenium 3.3 定制Allure测试报告 3.3.1 适配翻译插件 3.3.2 定制测试报告样式 4. 示例代码 5. 总结 前言&#xff1a; 随着现在Web应用的普…

SciencePub学术 | 计算机科学类重点SCIEI征稿中

SciencePub学术刊源推荐: 计算机科学类SCI&EI征稿中&#xff01;录用率高&#xff0c;自引率低&#xff0c;进展顺利。信息如下&#xff0c;录满为止&#xff1a; 一、期刊概况&#xff1a; 【期刊简介】IF&#xff1a;4.0-4.5↑&#xff0c; JCR 2区&#xff0c;中科院3区…

SpringAOP简介及实现(包含切面、切点、连接点和通知)

目录 1.什么是AOP、SpringAOP&#xff1f; 2.AOP的组成 3.SpringAOP的实现 4.切点的表达式 1.什么是AOP、SpringAOP&#xff1f; 在学习SpringAOP之前&#xff0c;我们得先了解一下什么是AOP。AOP是一种面向切面编程的思想。那什么是切面呢&#xff1f;它其实是对某一类事情…

【HR专用】Vue+SpringBoot,实现人才招聘库的开发(后端部分)

人才招聘库是企业用于储存和管理潜在候选人信息的数据库。通常情况下&#xff0c;这些候选人可能已经应聘过公司的职位&#xff0c;也可能是通过其他途径获取的&#xff0c;例如社交网络、招聘网站等。 对于一个中小公司来说&#xff0c;人力资源部绝对是一个重要部门&#xff…

测试类型(单元、集成、系统或手动测试)

测试类型(单元、集成、系统或手动测试) 单元测试 单元是系统的单个组件&#xff0c;例如类或单个方法。孤立地测试单元称为单元测试。 优点&#xff1a;速度快/易控/易写 缺点&#xff1a;缺乏现实性/无法捕获所有错误&#xff08;例如与其他组件或服务的交互&#xff09; 单元…

Arthas-JVM相关命令使用

tip&#xff1a;作为程序员一定学习编程之道&#xff0c;一定要对代码的编写有追求&#xff0c;不能实现就完事了。我们应该让自己写的代码更加优雅&#xff0c;即使这会费时费力。 开头&#xff1a; 我们先说下生产使用频率较高的有哪些&#xff1a;dashboard、heapdump、jvm…

【连续介质力学】二阶张量的图像表示

二阶张量在特定方向的投影 法向和切向分量 二阶张量T投影到 n ^ \hat n n^方向的结果是 t ⃗ ( n ^ ) T ⋅ n ^ \vec t^{(\hat n)}T \cdot \hat n t (n^)T⋅n^&#xff0c;其中 t ⃗ ( n ^ ) \vec t^{(\hat n)} t (n^)可以分解成&#xff1a; t ⃗ ( n ^ ) T ⃗ N T ⃗ S…

2023年上半年系统规划与管理师上午真题及答案解析

1.香农用概率来定量描述信息的公式如下&#xff0c;其中H(x)表示X的( )&#xff0c;Pi是( )出现第i种状态的( )。 A.信息熵 事件 概率 B.总熵 单位 概率 C.信息熵 单位 概率 D.总熵 单位 度量 2.信息传输模型中&#xff0c;( )负责信息的向外传播&#xff0c;( )负责…

VSLAM视觉里程计总结

相机模型是理解视觉里程计之前的基础。视觉里程计&#xff08;VIO&#xff09;主要分为特征法和直接法。如果说特征点法关注的是像素的位置差&#xff0c;那么&#xff0c;直接法关注的则是像素的颜色差。特征点法通常会把图像抽象成特征点的集合&#xff0c;然后去缩小特征点之…

Android 应用快捷ShortcutManager与ShortcutManagerCompat详解与实战(二)

一、介绍 之前我已通过一篇文章介绍了应用快捷的接入与Demo。如果还未看过上一篇的文章可以先了解入门。 传送门&#xff1a;Android 应用快捷(shortcut)功能的详解(一)_蜗牛、Z的博客-CSDN博客 有创建自然就会有管理&#xff0c;否则一个完美的方案不应该这么被推荐出来。如何…

Zemax Lumerical | 二维光栅出瞳扩展系统优化(下)

简介 本文提出并演示了一种以二维光栅耦出的光瞳扩展&#xff08;EPE&#xff09;系统优化和公差分析的仿真方法。 在这个工作流程中&#xff0c;我们将使用3个软件进行不同的工作 &#xff0c;以实现优化系统的大目标。首先&#xff0c;我们使用 Lumerical 构建光栅模型并使用…

数据库实验报告--安全性实验

一、 实验目的 &#xff08;1&#xff09;理解SQL Server验证用户身份的过程&#xff0c;掌握设置身份验证模式的方法。 &#xff08;2&#xff09;理解登录账号的概念&#xff0c;掌握混合认证模式下登录账号的建立与取消方法。 &#xff08;3&#xff09;掌握混合认证模式…