表白墙系统测试

标题一、项目背景

校园表白墙网站系统采用前后端分离的方法来实现,同时使用了数据库来存储相关的数据。前端主要有六个页面构成:注册页、登录页、表白帖列表页、表白帖详情页、表白帖编辑页、表白帖修改页,以上模拟实现了最简单的校园表白墙网站系统。其结合后端实现了以下的主要功能:用户注册、登录、注销、编辑表白帖、修改表白帖、以及强制登录等、删除表白帖功能。
项目源代码:https://gitee.com/qklzzb/blog-system

标题二、项目功能

校园表白墙网站系统主要实现了以下几个功能:用户注册、登录、注销、发表表白帖以及修改表白帖、删除表白帖等功能。

  1. 注册功能:用户通过输入用户名、密码以及学校名称进行注册,如果点击注册按钮则跳转到登录页面;如果输入的用户名、密码、学校名称三者至少有一个为空,则提示用户注册失败。
    在这里插入图片描述

  2. 登录功能:用户输入用户名和密码,如果输入正确的用户名和密码则登录成功并跳转到表白墙列表页面;如果输入错误,则提示用户输入的信息有误,登录失败。
    在这里插入图片描述

  3. 展示表白墙列表功能:表白墙系统主页可展示该系统上所有用户发表的表白帖。
    在这里插入图片描述

  4. 发表表白功能:用户在登录的状态下可进行发表表白,对于发表的表白需要验证表白的标题和内容,两者均不能为空内容,如果两者都不为空内容则点击发表表白,表白帖发表成功,反之发表失败。
    在这里插入图片描述

  5. 展示表白帖详情功能:展示表白帖的正文所有内容以及标题,并且在表白帖详情页会显示出该表白帖的作者信息。
    在这里插入图片描述

  6. 修改表白帖功能:用户可以修改自己已发表的表白内容,进入表白帖详情页面,点击编辑进入修改页面,修改完成之后,点击更新则修改成功,反之修改失败。修改完成之后会跳转到表白墙列表页面。
    在这里插入图片描述

  7. 删除表白帖功能:用户可以删除自己已发表的表白内容,进入表白帖详情页面,点击删除则表白帖删除成功(使用逻辑删除),反之删除失败。删除完成之后会跳转到表白墙列表页面。
    在这里插入图片描述

  8. 注销登录:用户进行正常登录后,如若需要退出登录,点击右上角的注销按钮,则退出登录并且跳转到登录页面。

标题三、自动化测试

1. 编写测试用例

在这里插入图片描述

看不清的话可以进行下载,或者通过链接进行查看:表白墙系统测试用例

2.编写自动化测试代码

在我们的Web自动化测试项目中,需要对登录页、表白墙列表页、表白帖编辑页、表白帖详情页,这几个页面分别进行针对性测试。
对功能主流程进行自动化测试:

  1. 公共类
    创建驱动、保存现场截图、关闭驱动

在进行测试时都需要创建驱动和使用驱动,如果每一个类中我们都去创建驱动,最后释放驱动,这样的过程是十分消耗资源的,那么我们便可以把创建驱动这个操作放在一个类中,并设置驱动对象为静态的,就可以让创建和销毁驱动的步骤执行一次,其他类如果需要驱动直接继承该类即可

public class InitAndEnd {
	//浏览器驱动
    static WebDriver webDriver;

    /**
     * 创建驱动
     */
    @BeforeAll
    static void init() {
        //创建一个Chrome浏览器驱动
        webDriver = new ChromeDriver();
    }

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

    /**
     * 获取屏幕截图,把所有的测试用例执行的结果保存下来
     */
    public void getScreenShor(String str) throws IOException {
        List<String> list = getTime();
        //dir+filename
        // ./src/test/java/com/blogWebAutoTest/dirname/filename
        String fileName = "./src/test/java/" + list.get(0) + "/" + str + "-" + list.get(1) + ".png";

        File screenshotAs = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);
        //把屏幕截图生成的文件放到指定的路径
        FileUtils.copyFile(screenshotAs, new File(fileName));
    }

    /**
     * 关闭驱动
     */
    @AfterAll
    static void close() {
        //关闭浏览器驱动
        webDriver.quit();
    }
}
  1. 测试登录功能
    测试登录,输入正确的账号密码,跳转到表白墙列表页面
    ① 驱动已经创建好则不需再次创建驱动,打开登录页面;
    ② 测试正常登录:用户名/密码正确的情况下,是否跳转到表白墙列表页面;
    ③ 表白墙列表页面的用户是否为登录用户
    注意测试的顺序,使用Order注解指定,否则可能会因为执行顺序不对导致测试失败;
	public static Stream<Arguments> generate() {
        return Stream.of(Arguments.arguments("zhangsan", "123456", "http://127.0.0.1:8080/blog_list.html"));
    }

    /**
     * 测试登录,输入正确的账号密码,跳转到表白墙列表页面
     */
    @Order(1)
    @ParameterizedTest
    @MethodSource(value = "generate")
    void LoginSuccess(String userName, String password, String expect_url) throws InterruptedException {
        //进入登陆页面
        webDriver.get("http://127.0.0.1:8080/blog_login.html");
        //输入账号
        webDriver.findElement(By.cssSelector("#username")).sendKeys(userName);
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        //输入密码
        webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        //点击提交按钮
        webDriver.findElement(By.cssSelector("#submit")).click();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        //判断页面是否跳转到表白墙列表页面
        String cur_url = webDriver.getCurrentUrl();
        Assertions.assertEquals(expect_url, cur_url);
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        //判断登录用户是否正确
        String cur_userName = webDriver.findElement(By.cssSelector("body > div.container > div.left > div > h3")).getText();
        Assertions.assertEquals(userName, cur_userName);
    }
  1. 表白墙列表页面博客信息
	/**
     * 表白墙列表页面,表白帖的数目不为0
     */
    @Order(2)
    @Test
    public void list_num() {
        webDriver.get("http://127.0.0.1:8080/blog_list.html");
        //获取列表页表白帖的数量
        int blog_num = webDriver.findElements(By.cssSelector(".title")).size();
        //判断表白帖的数量是否不为0
        Assertions.assertNotEquals(0, blog_num);
    }
  1. 发布表白内容
    表白内容发布之后,跳转到表白墙列表页面
    ① 驱动已经创建好则不需再次创建驱动,打开写表白页面;
    ② 写表白内容之后及进行发布,检验是否跳转到表白墙列表页面;
    ③ 表白墙列表页面的第一条表白内容是否为刚刚发布的表白信息(表白帖的标题和时间是否正确)
	/**
     * 写表白并且发布表白内容
     */
    @Order(3)
    @ParameterizedTest
    @CsvFileSource(resources = "title.csv")
    void writeAndPublish(String title) throws InterruptedException {
        //进入写表白页面
        webDriver.get("http://127.0.0.1:8080/blog_edit.html");
        //写表白内容
        webDriver.findElement(By.cssSelector("#title")).sendKeys(title);
        //使用JS的方式写表白信息的标题
//        ((JavascriptExecutor)webDriver).executeScript("document.getElementById(\"title\").value=\"自动化测试\""); //使用JS时不能使用变量
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//        webDriver.findElement(By.cssSelector("#content")).sendKeys("测试");
        //提交表白的内容
        webDriver.findElement(By.cssSelector("#submit")).click();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        sleep(3000);
        //判断页面是否进行跳转
        String cur_url = webDriver.getCurrentUrl();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        Assertions.assertEquals("http://127.0.0.1:8080/blog_list.html", cur_url);
    }

    /**
     * 校验已发布表白帖的标题,同时校验已发布表白帖的时间
     */
    @Order(4)
    @ParameterizedTest
    @CsvFileSource(resources = "title.csv")
    void BlogInfoChecked(String title) throws InterruptedException {
        //进入表白墙列表页面
        webDriver.get("http://127.0.0.1:8080/blog_list.html");
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        //校验第一个表白帖的标题
        String cur_title = webDriver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > div.title")).getText();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        //判断第一篇表白的title和csv文件当中的字符串是否相同
        Assertions.assertEquals(title, cur_title);
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        //校验第一篇表白的时间是否和预期时间相同
        String cur_time = webDriver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > div.date")).getText();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        if (cur_time.contains("2024-04-06")) {
            System.out.println("测试通过");
        } else {
            System.out.println("测试不通过");
        }
    }

  1. 表白详情页面测试
    ① 驱动已经创建好则不需再次创建驱动,打开表白墙列表页面;
    ② 点击查看详情,是否跳转到表白帖详情页面;
    ③ 查看表白帖信息是否为列表第一条表白的信息(查看表白帖的标题和时间是否正确)
    /**
     * 检验表白帖的详情
     */

    public static Stream<Arguments> generate2() {
        return Stream.of(Arguments.arguments("表白帖详情页", "自动化测试", "http://127.0.0.1:8080/blog_detail.html?blogId="));
    }

    @Order(5)
    @ParameterizedTest
    @MethodSource(value = "generate2")
    void testDetail(String expect_title, String expect_blog_title, String expect_url) {
        webDriver.get("http://127.0.0.1:8080/blog_list.html");
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        //点击查看全文
        webDriver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a")).click();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        //判断页面标题
        String cur_title = webDriver.getTitle();
        Assertions.assertEquals(expect_title, cur_title);
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        //判断表白帖title是否为自动化测试
        String cur_blog_title = webDriver.findElement(By.cssSelector("body > div.container > div.right > div > div.title")).getText();
        Assertions.assertEquals(expect_blog_title, cur_blog_title);
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        //判断是否跳转表白帖详情页面
        String cur_url = webDriver.getCurrentUrl();
        if (cur_url.contains(expect_url)) {
            System.out.println("测试通过");
        } else {
            System.out.println("测试不通过");
        }
    }

  1. 删除表白帖测试
    ① 驱动已经创建好则不需再次创建驱动,打开表白帖详情页面;
    ② 点击删除按钮,查看是否跳转到表白墙列表页面;
    ③ 表白墙列表页面的第一条表白帖是否为刚刚删除的表白帖信息
 	/**
     * 删除刚才写的表白信息
     */
    @Order(6)
    @ParameterizedTest
    @CsvFileSource(resources = "title.csv")
    void testDelete(String title) throws InterruptedException {
        webDriver.get("http://127.0.0.1:8080/blog_list.html");
        webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
        //点击查看全文
        webDriver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a")).click();
        webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
        //点击删除按钮
        webDriver.findElement(By.cssSelector("body > div.container > div.right > div > div.operating > button:nth-child(2)")).click();
        webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
        //第一条表白的标题不是自动化测试
        String cur_title = webDriver.findElement(By.cssSelector("body > div.container > div.right > div > div.title")).getText();
        webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
        Assertions.assertNotEquals(title,cur_title);
    }

3.使用测试套件进行代码测试

采用测试套件,可以降低测试人员的工作量,通过套件一次执行所有要运行的测试用例。

@Suite
@SelectClasses({BlogCases.class})
	public class RunSuite {
}

所有测试用例通过:
在这里插入图片描述

标题四、web自动化测试总结

  1. 提高测试效率:自动化测试可以快速执行测试用例,比手动测试更高效。

  2. 只创建一次驱动对象,避免每个用例重复创建驱动对象造成时间和资源的浪费。

  3. 使用参数化:保持用例的简洁,提高代码的可读性。

  4. 使用测试套件:降低了测试人员的工作量,通过套件一次执行所有要运行的测试用例。

  5. 使用了等待:提高了自动化的运行效率,提高了自动化的稳定性,减小误报的可能性。

  6. 使用了Junit5中提供的注解:避免生成过多的对象,造成资源和时间的浪费,提高了自动化的执行效率。

  7. 增加测试覆盖范围:自动化测试可以覆盖更多的测试场景和用例,提高软件质量。

  8. 重复执行测试:自动化测试可以反复执行相同的测试用例,确保软件在不同环境下的稳定性。

标题五、性能测试

5.1 loadRunner介绍

在这里插入图片描述
我们使用以上三个工具针对我们的项目进行性能测试。

a)Virtual User Generator(简称VUG):用于录制用户操作脚本,可以模拟用户在应用程序上执行的操作。就是通过录制或编写脚本来模拟用户的行为,同时会打印出日志信息,方便调试脚本;VuGen也是一个集成开发调试环境,在这里完成脚本开发并调试通过后就可以放到Controller中创建场景。

b)Controller:创建测试场景,运行和监控场景。用于管理并协调多个虚拟用户同时访问应用程序,以模拟真实的用户负载。

c)Analysis:生成测试报告,分析性能测试结果。用于分析性能测试结果,生成报告并提供性能指标,如响应时间、吞吐量等。

5.2 编写测试脚本(Virtual User Generator)

主要的操作步骤为:

  1. 录制脚本 :a)访问登录页;b)输入用户名密码进行登录;c)进入表白墙列表页面

  2. 脚本加强
    在此期间,为了更好的让我们进行性能测试的数据收集,我们可以使用下面这些来加强脚本

    • 事务:衡量性能的重要指标,通过观察每秒事务通过数来衡量性能;
    • 集合点:让所有的虚拟用户执行到集合点时断在集合,满足条件后一起执行下一个步骤(保证每一个虚拟用户同时执行下一步);
    • 检查点:可以用来检测当前页面的元素是否存在以及存在个数(检查点一般放在请求之前);
    • 参数化:通过提供的数据源可以实现多个参数逐个执行;
Action()
{
	//开始事务
	lr_start_transaction("login");

	//插入集合点
	lr_rendezvous("rendezous");

	web_url("blog_login.html", 
		"URL=http://192.168.193.128:8080/blog_login.html", 
		"Resource=0", 
		"Referer=", 
		"Snapshot=t1.inf", 
		"Mode=HTML", 
		EXTRARES, 
		"Url=/css/common.css", ENDITEM, 
		"Url=/css/login.css", ENDITEM, 
		"Url=/pic/logo2.jpg", ENDITEM, 
		"Url=/js/jquery.min.js", ENDITEM, 
		"Url=/pic/back.jpg", "Referer=http://192.168.193.128:8080/css/common.css", ENDITEM, 
		"Url=/user/login?userName={userName}&password={password}", ENDITEM,     //参数化
		LAST);
	
	//结束事务
	lr_end_transaction("login", LR_AUTO);

	return 0;
}

在Parameter中添加登陆的用户和密码(添加数据源)
在这里插入图片描述
在这里插入图片描述
4. 设置迭代次数
设置脚本执行次数,如果设置1,那么只有Parameters中的第一个用户登录(这里我设置为3,因为我添加了三个用户参数)
在这里插入图片描述
在日志设置中开启打印参数日志(便于观察当前测试的用户)
在这里插入图片描述
5. 运行脚本
在这里插入图片描述
测试通过
在这里插入图片描述
观察日志,查看用户登录的详情,进行结果分析。

5.3 创建测试场景(Controller)

针对我们已经编写好的脚本打开controller工具,创建测试场景,如下:

  1. 设置并发数,设置10个虚拟用户,防止电脑崩溃
    在这里插入图片描述

  2. 在Controller中设计场景,具体设置如下:
    在这里插入图片描述
    初始化虚拟用户
    在这里插入图片描述
    开始运行虚拟用户
    在这里插入图片描述
    虚拟用户的运行时间
    在这里插入图片描述
    结束虚拟用户的过程
    在这里插入图片描述
    在这里插入图片描述

  3. 开始进行运行,性能测试开始(运行中+结束截图)
    在这里插入图片描述
    运行中截图
    在这里插入图片描述
    运行结束截图
    在这里插入图片描述

5.4 生成测试报告(Analysis)

在这里插入图片描述
在这里插入图片描述
作用:通过显示的虚拟用户数量可以判断出哪个时间段服务器负载最大(上图1:05~ 02:05负载最大)。
在这里插入图片描述
作用:通过点击率可以判断出某时间段内服务器的负载。
在这里插入图片描述

问题一:为什么吞吐量图和点击数图相似,但是吞吐量图要滞后一点?

当用户发起点击请求时,点击数图记录了用户的操作次数,而吞吐量图表示系统在单位时间内处理的请求数量或事务数量。系统处理请求需要一定的时间,包括网络传输、服务器处理、数据库查询等过程,这些过程会导致吞吐量图相对于点击数图出现一定的滞后。

问题二:如果请求变多但是吞吐量没变化,原因是什么?

  1. CPU资源达到极限:处理请求的计算量过大,导致CPU负载很高,无法及时处理更多请求。
  2. 内存不足:请求处理过程中需要大量内存,系统内存不足会导致请求被拒绝或处理缓慢。
  3. 网络带宽受限:系统的网络带宽达到极限,无法承载更多的请求数据传输。
  4. 服务器响应太慢,来不及反应; 压力没有到服务器;
  5. 服务器设计一定的阈值(到达阈值以后,虽然也收到了请求,但是服务器不会做任何处理),保证了服务器不会因为并发量过大而出现宕机的情况;

在这里插入图片描述
作用:可以观察到,虚拟用户在性能测试中,每秒在服务器上命中的次数,可以根据命中的次数评估虚拟用户生成的负载量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值