个人博客系统测试报告

一.项目背景

当学习完一项技能后,我们总会习惯通过博客来总结所学的知识点,方便后期遗忘时随时查看和快速复习。本次开发的类似于CSDN的个人博客系统便是为了更加轻量和方便地记录自己的学习笔记,方便自己后期学习记录。

二.项目功能

该个人博客系统主要实现了以下功能:注册和登录、注销、编写博客、修改博客、删除博客、查看博客详情,修改个人信息等功能。

  • 注册登录功能:用户输入想创建的账号和密码,点击注册按钮无误后跳转到登陆页面,在登录页面输入正确的账号密码,登录成功后就会跳转到博客列表页。在右上角存在网站主页,注册两个按钮。
  • 博客列表页面:可以在列表页查看用户所有的博客文章简介(支持分页功能),其包括博客标题、发布时间以及内容概要。在左侧可以看到登录的用户以及文章数、分类数等的模块。在右上角有主页、写博客和注销三个功能。
  • 博客详情页面:在博客列表页面下方点击“查看全文”按钮就会跳转到当前博客详情页,此时就可以看到该篇博客的完整内容。在右上角有主页和写博客两个功能
  • 个人信息页面:该页面显示用户全部的个人信息,包括头像,性别,账号,昵称,个人简介等,用户也可以修改除账号以外的全部信息。
  • 博客编辑页面:在登录之后的任意界面点击“写博客”之后就会进入博客编辑页面,此时就可以进行博客的编写(支持markdown格式),点击“发布文章”后就可以成功发布文章,此时就会跳转到我的博客页面。

三.测试用例

3.1 功能测试

在这里插入图片描述

3.2 自动化测试(部分测试)

实现工具类,增加代码复用
为了避免在使用时频繁创建驱动类,我们可以定义一个功能类使用单例创建驱动对象。

// An highlighted block
package com.example.blogautotest.common;
 
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.edge.EdgeDriver;
 
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
 
public class AutotestUtils {
    public static EdgeDriver driver;
 
    //创建驱动对象
    public static EdgeDriver createDriver(){
        //单例模式
        if(driver==null){
            driver=new EdgeDriver();
            //创建隐式等待
            driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
        }
        return driver;
    }
 
    //获取当前时间将截图按照时间保存
    public List<String> getTime(){
        //文件夹以天保存
        //截图以毫秒时间戳保存
        SimpleDateFormat sim1=new SimpleDateFormat("yyyyMMdd-HHmmssSS");
        SimpleDateFormat sim2 = new SimpleDateFormat("yyyyMMdd");
        String filename=sim1.format(System.currentTimeMillis());
        String dirname=sim2.format(System.currentTimeMillis());
        List<String> list = new ArrayList<>();
        list.add(dirname);
        list.add(filename);
        return  list;
    }
 
    //获取屏幕截图,把所有的用例执行的结果保存下来
    public void getScreenShot(String str) throws IOException {
        List<String> list=getTime();
        // ./指的是当前的项目路径下,也就是BlogAutoTest下
        String filename="./src/test/java/com/blogautotest/"+list.get(0)+"/"+str+"_"+list.get(1)+".png";
        File srcfile=driver.getScreenshotAs(OutputType.FILE);
        //把屏幕截图生成的文件放到指定的路径
        FileUtils.copyFile(srcfile,new File(filename));
    }
}

3.2.1登陆页面

创建一个类(自定义名为BlogLoginTest )继承 AutoTestUtils 类,获取驱动,之后选取典型 case 使用参数化注解对异常、正常登录分别进行测试,进行相应弹窗处理,最后进行屏幕截图.

package com.example.blogautotest.Tests;
 
import com.example.blogautotest.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;
 
//设置优先级
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogLoginTest extends AutotestUtils {
 
    public static final String UNIVERSAL_KAPTCHA_CODE="c8fd27d19b2aa9fa24affd2a4726778c";
    public static EdgeDriver driver=createDriver();
 
    @BeforeAll
    public static void baseControl(){
        driver.get("http://127.0.0.1:8080/login.html");
    }
 
    /*
    检查登录页面打开是否正确
    检查点:登录标题  用户名是否存在
     */
    @Test
    @Order(1)
    public void loginPageLoadRight() throws IOException {
        //检验页面是否加载正确(两个检查点)
        driver.findElement(By.cssSelector("body > div.login-container > div > h3"));
        driver.findElement(By.cssSelector("body > div.login-container > div > div:nth-child(2) > span"));
        getScreenShot(getClass().getName());
    }
 
    @ParameterizedTest
    @CsvSource({"zhangsan,123","admin,admin"})
    @Order(2)
    public void loginSuc(String name , String password) throws InterruptedException, IOException{
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        driver.findElement(By.cssSelector("#rightCode")).clear();
 
        driver.findElement(By.cssSelector("#username")).sendKeys(name);
        driver.findElement(By.cssSelector("#password")).sendKeys(password);
        driver.findElement(By.cssSelector("#rightCode")).sendKeys(UNIVERSAL_KAPTCHA_CODE);
        driver.findElement(By.cssSelector("#submit")).click();
        //处理弹窗
        Thread.sleep(300);
        driver.switchTo().alert().accept();
        //对登录结果进行检测,存在草稿页元素代表登录成功
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)"));
        //getScreenShot(getClass().getName());
        driver.navigate().back();
    }
 
    @ParameterizedTest
    @CsvSource({"admin,123","zhangsan,666"})
    @Order(3)
    public void loginFail(String name,String password) throws IOException, InterruptedException {
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        driver.findElement(By.cssSelector("#rightCode")).clear();
 
        driver.findElement(By.cssSelector("#username")).sendKeys(name);
        driver.findElement(By.cssSelector("#password")).sendKeys(password);
        driver.findElement(By.cssSelector("#rightCode")).sendKeys(UNIVERSAL_KAPTCHA_CODE);
        driver.findElement(By.cssSelector("#submit")).click();
        //处理弹窗
        Thread.sleep(300);
        //获取弹窗内容
        String text=driver.switchTo().alert().getText();
        String except="登陆成功!";
        driver.switchTo().alert().accept();
        Assertions.assertNotEquals(except,text);
        //获取当前页面截屏
        //getScreenShot(getClass().getName());
    }
}

3.2.2博客详情页

package com.example.blogautotest.Tests;
 
import com.example.blogautotest.common.AutotestUtils;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.edge.EdgeDriver;
 
import java.io.IOException;
 
public class BlogDetailTest extends AutotestUtils {
    public static EdgeDriver driver=createDriver();
    @BeforeAll
    public static void baseControl(){
        driver.get("http://127.0.0.1:8080/blog_content.html?id=12869974016131072");
    }
 
    @Test
    public void blogDeailLoadRight() throws IOException{
        driver.findElement(By.cssSelector("#data"));
        driver.findElement(By.cssSelector("#title"));
    }
}

3.2.3博客编辑页

package com.example.blogautotest.Tests;
 
import com.example.blogautotest.common.AutotestUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.edge.EdgeDriver;
 
import java.io.IOException;
 
public class BlogEditTest extends AutotestUtils {
    public static EdgeDriver driver=createDriver();
    @BeforeAll
    public static void baseControl(){
        driver.get("http://127.0.0.1:8080/blog_edit.html");
    }
 
    @Test
    public void editAndSubimitBlog() throws IOException, InterruptedException {
        driver.findElement(By.cssSelector("#title")).sendKeys("自动化测试");
        //博客系统使用到的编辑是第三方软件,所以不能直接使用sendKeys向编辑模块发送文本
        driver.findElement(By.cssSelector("#editorDiv > div.editormd-toolbar > div > ul > li:nth-child(30)")).click();
        driver.findElement(By.cssSelector("body > div.blog-edit-container > div.title > button:nth-child(2)")).click();
        Thread.sleep(300);
        String actual=driver.switchTo().alert().getText();
        driver.switchTo().alert().accept();
        String expect = "恭喜:添加成功!";
        Assertions.assertEquals(expect,actual);
    }
}

3.2.4个人列表页

package com.example.blogautotest.Tests;
 
import com.example.blogautotest.common.AutotestUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.edge.EdgeDriver;
 
public class MyBlogListTest extends AutotestUtils {
    public static EdgeDriver driver=createDriver();
    @BeforeAll
    public static void baseControl(){
        driver.get("http://127.0.0.1:8080/myblog_list.html");
    }
    @Test
    public void myListPageLoadRight(){
        //检查博客列表加载是否正常
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(7)"));
        driver.findElement(By.cssSelector("body > div.container > div.container-left > div > a"));
        driver.findElement(By.cssSelector("body > div.container > div.container-right > div.blog-pagnation-wrapper > button:nth-child(1)"));
        driver.findElement(By.cssSelector("body > div.container > div.container-right > div.blog-pagnation-wrapper > button:nth-child(3)"));
    }
 
    @Test
    public void jumpTest(){
        //测试导航栏能否正常跳转
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)")).click();
        Assertions.assertEquals("http://127.0.0.1:8080/blog_list.html",driver.getCurrentUrl());
        driver.navigate().back();
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
        Assertions.assertEquals("http://127.0.0.1:8080/blog_edit.html",driver.getCurrentUrl());
        driver.navigate().back();
    }
}

3.2.5测试结果

在这里插入图片描述

3.3 性能测试

通过LoadRunner模拟多个用户进行并发进行登录后访问所有文章列表页面。
3.3.1.编写性能测试脚本

Action()
{
	
	//开启进入登录页事务
	lr_start_transaction("login_index");
    /* 注册获取返回参数,该方法可以配合打印返回数据,检测数据内容 */
	web_reg_save_param("ParaResult",
					   "LB=",
					   "RB=",
					   LAST);
    // 定时检查点,检测登录页面是否正确打开
    web_reg_find("Text=登录",LAST);
    // 定义虚拟用户结合点
    lr_rendezvous("start");
    // 进入登录页面
	web_url("login_html",
		"URL=http://127.0.0.1:7070/login.html",
		"TargetFrame=",
		"Resource=0",
		"Referer=",
		LAST);
    // 结束进入登录页事务
	lr_end_transaction("login_index", LR_AUTO);
	//开启登录事务
	lr_start_transaction("login");
    // 进行登录
	web_submit_data("login",
		"Action=http://127.0.0.1:7070/user/login",
		"Method=POST",
		"EncType=application/x-www-form-urlencoded; charset=UTF-8",
		"TargetFrame=",
		"Referer=",
		"Mode=HTTP",
		ITEMDATA,
		"Name=username", "Value=<username>", ENDITEM,
		"Name=password", "Value=<password>", ENDITEM,
		LAST);

    //定时检测所有文章列表页检查点
    web_reg_find("Text=查看全文",LAST);
    // 结束登录事务
	lr_end_transaction("login", LR_AUTO);
	
	//文章列表事务
	lr_start_transaction("blog_list");
    // 登录后访问所有文章列表页面
	web_url("blog_list",
		"URL=http://127.0.0.1:7070/blog_list.html",
		"TargetFrame=",
		"Resource=0",
		"Referer=",
		LAST);

    // 结束文章列表页事务
	lr_end_transaction("blog_list", LR_AUTO);
    


	return 0;
}

测试脚本没有问题后修改Action脚本的执行次数,执行5次脚本

在这里插入图片描述

为了保证测试的合理性,多个虚拟用户使用多个不同的账号进行登录,使用LoadRunner的参数化即可实现。

在这里插入图片描述

针对编写好的脚本通过Controller创建测试场景

  • 设置15个虚拟用户

  • 在这里插入图片描述

  • 设置每5秒进入3个虚拟用户到测试场景在这里插入图片描述

  • 设置虚拟用户执行循环执行5分钟
    在这里插入图片描述

  • 设置虚拟用户执行完毕后每10秒退出5个虚拟用户
    在这里插入图片描述

  • 添加监视系统资源
    CPU运行时间和剩余内存
    在这里插入图片描述
    性能测试报告
    在这里插入图片描述

通过虚拟用户运行图标可以发现,在脚本运行40秒到5分30秒之间虚拟用户给了服务器负载

在这里插入图片描述

通过点击率表可以看到和虚拟用户运行表运行对应起来,虚拟用户的增多点击率也随之增多,点击率越多说明和服务器的交互次数也越多。

在这里插入图片描述

通过事务响应时间发现,访问登录页面的时间比较长,登录事务时间响应时间是比较短的

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值