在线音乐播放器 —— 测试报告

自动化脚本源代码:Java: 利用Java解题与实现部分功能及小项目的代码集合 - Gitee.com

目录

·前言

一、项目简介

1.项目背景

2.应用技术

(1)后端开发

(2)前端开发

(3)数据库

二、项目功能

三、功能测试

1.编写测试用例

2.测试具体过程

(1)正常登录

(2)异常登录

(3)删除单个音乐

(4)删除选中音乐

(5)喜欢音乐

(6)上传音乐

(7)查询音乐

(8)取消喜欢音乐

四、自动化测试

1.编写自动化测试用例

2.自动化测试代码编写

(1)创建空项目

(2)创建测试用例工具类

(3)创建登录测试用例类

(4)创建音乐列表测试用例类

(5)创建喜欢列表测试用例类

(6)创建上传音乐测试用例类

(7)创建运行测试用例类

3.自动化测试执行结果

五、性能测试

1.创建梯度压测线程组

2.创建 HTTP 请求默认值

3.创建 HTTP Cookie 管理器

4.创建音乐播放器登录请求

5.创建获取音乐列表页请求

6.创建获取喜欢音乐列表页请求

7.性能测试执行结果

8.生成性能测试报告

·总结


·前言

        前面文章中,我们把在线音乐播放器项目从零到一的都编写完成完成,并在每个模块编写的过程中,利用 Postman 进行了接口的简单测试,在本篇文章,我将对我们所编写的这个项目进行一个详细的测试并且再对本项目做一个整体的介绍,来检查我们项目中是否还存在问题,这里我们要进行的测试分为:功能测试、自动化测试、性能测试三种,最后将这些测试的过程及结果总结到一起形成这篇测试报告。

一、项目简介

1.项目背景

        在数字化时代,音乐作为人们生活中不可或缺的一部分,其消费与传播方式发生了巨大变革。传统的音乐播放模式逐渐向线上转移,人们渴望能够通过便捷的网络平台随时随地畅享丰富多样的音乐资源。本在线音乐播放器项目正是为满足这一市场需求而开发,旨在为用户打造一个功能全面、操作便捷的音乐播放与管理平台,使用户无需受限于本地音乐存储,即可轻松探索、播放和管理海量音乐曲目。

2.应用技术

(1)后端开发

        后端开发应用的技术如下所示:

  • Spring 框架:作为核心框架,提供了依赖注入等功能,有效管理项目中的组件对象,解耦各模块之间的依赖关系,提高代码的可维护性与扩展性。
  • SpringBoot:基于 Spring 进一步简化了项目的初始搭建与配置过程,通过自动配置特性,使开发者能够快速聚焦于业务逻辑开发,大大提高开发效率,同时也便于项目的部署与运维。
  • Mybatis:负责数据库访问层的操作,能够将 SQL 查询语句与 Java 代码进行灵活映射,方便对 Mysql 数据库进行数据的持久化操作,如音乐信息、用户数据等的存储与读取,高效处理数据访问需求。
  • SpringMVC:遵循 MVC 设计模式,实现了前端请求与后端处理逻辑的清晰分离与高效交互,负责接收并处理来自前端的各种 HTTP 请求,如用户登录、音乐查询与操作等请求,并将处理结果返回给前端页面进行展示。
  • BCrypt 加密算法:用于对用户密码进行加密存储,保障用户密码在数据库中的安全性,有效防止密码泄露导致的用户账号安全问题,确保用户信息安全。

(2)前端开发

        前端开发应用的技术如下所示:

  • HTML:构建页面的基础结构,负责定义页面的各个元素与布局,如音乐列表界面、用户登录界面、喜欢音乐列表展示等页面的骨架搭建。
  • CSS:用于美化页面样式,通过设置字体、颜色、背景、布局等样式属性,使页面呈现出美观、舒适的视觉效果,提升用户操作体验与界面友好度。
  • JS:为页面添加动态交互功能,如实现音乐播放控制、用户操作响应(如点击登录按钮、添加喜欢音乐等)、数据验证等功能,增强页面的交互性与响应性。
  • jQuery:简化了 JavaScript 的开发过程,提供了丰富的插件与便捷的操作方法,方便对页面元素进行选择、事件绑定、动画效果实现等操作,进一步提高前端开发效率与代码简洁性。
  • Ajax:用于实现前端与后端的异步数据交互,在不刷新整个页面的情况下,能够在后台与服务器进行数据传输,如实时查询音乐、无刷新更新音乐播放列表等功能,提升用户体验的流畅性与实时性。

(3)数据库

        采用 Mysql 关系型数据库进行数据存储,能够高效地组织与管理平台所需的各类数据,包括音乐信息(歌曲名、歌手、音频文件路径)、用户信息(用户名、密码)、用户音乐信息(喜欢音乐),确保数据的完整性、一致性与持久性,为平台的稳定运行提供数据支持。

二、项目功能

        本在线音乐播放器项目的核心功能有:登录、上传音乐、删除指定音乐、批量删除选中的音乐、查询要找的音乐、添加音乐至喜欢列表、移除喜欢的音乐。

        部分功能的详细介绍如下所示:

  • 登录功能:用户名与加密后的密码都已经写入到后端的数据库中了,本项目目前还没有实现注册功能,即:用户名与密码是已经存在的,登录成功后就会跳转到音乐列表页。
  • 音乐列表页:在这个页面中,我们可以看到所有的音乐信息,其包括音乐名称,歌手。在每个音乐对应的行中有播放音乐、删除音乐、喜欢音乐的三个按钮,这三个按钮也对应着三个功能,每个音乐前面设计了一个选择框,通过这个可以实现批量删除的操作。
  • 喜欢音乐列表页:这个页面的整体布局与音乐列表页布局大致相同,只不过没有喜欢音乐及批量删除选中音乐的功能了,添加了取消喜欢音乐的功能和回到首页的功能,在这个页面中也可以针对喜欢的音乐进行查询操作。
  • 上传音乐页面:在这个页面进行的就是上传音乐的操作,并且还有返回首页的连接。

三、功能测试

1.编写测试用例

        功能测试的测试用例如下图所示:

2.测试具体过程

(1)正常登录

(2)异常登录

(3)删除单个音乐

(4)删除选中音乐

(5)喜欢音乐

(6)上传音乐

(7)查询音乐

(8)取消喜欢音乐

四、自动化测试

1.编写自动化测试用例

        自动化测试的测试用例如下图所示:

2.自动化测试代码编写

(1)创建空项目

① 添加依赖(pom.xml 文件)代码如下所示:

    <dependencies>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.0.0</version>
        </dependency>
        <dependency>
            <groupId>io.github.bonigarcia</groupId>
            <artifactId>webdrivermanager</artifactId>
            <version>5.8.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
    </dependencies>

② 创建项目结构,如下图所示:

(2)创建测试用例工具类

        创建 Utils 类,用它存放我们自动化代码中通用的方法,在这个类中我们要创建的方法如下:

  • 创建驱动对象;
  • 创建屏幕截图方法;
  • 创建构造方法。

        有关 Utils 类的具体代码及详细介绍如下所示:

public class Utils {
    public static WebDriver driver;

    // 创建驱动对象
    public static WebDriver createDriver() {
        // 判断当前是否有驱动对象
        if (driver == null) {
            // 没有驱动对象就创建驱动对象
            WebDriverManager.chromedriver().setup();
            ChromeOptions options = new ChromeOptions();
            // 允许访问所有链接
            options.addArguments("--remote-allow-origins=*");
            driver = new ChromeDriver(options);
            // 设置隐式等待
            driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
        }
        // 有驱动对象之间返回
        return driver;
    }

    // 进阶版屏幕截图
    public void getScreenShot(String str) throws IOException {
        // 规定时间格式为 年-月-日, 如: 2024-11-17
        SimpleDateFormat sim1 = new SimpleDateFormat("yyyy-MM-dd");
        // 规定时间格式为 时分秒毫秒, 如: 171953345
        SimpleDateFormat sim2 = new SimpleDateFormat("HHmmssSS");
        // 创建文件夹的名称, 以现在的日期来命名, 用 sim1 来转化时间格式
        String dirTime = sim1.format(System.currentTimeMillis());
        // 创建文件名称, 以现在的时间来命名, 用 sim2 来转化时间格式
        String fileTime = sim2.format(System.currentTimeMillis());
        // 拼接好完整文件名(包含:存放具体位置,及文件名称)
        String filename = "./src/test/image/" + dirTime + "/" + str + "-" + fileTime + ".png";
        // 屏幕截图
        File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
        // 把截图 srcFile 放到指定的位置
        FileUtils.copyFile(srcFile, new File(filename));
    }

    // 创建构造方法, 接收访问页面的 URL
    public Utils(String url) {
        // 1. 调用 driver 对象
        driver = createDriver();
        // 2. 访问 URL
        driver.get(url);
    }
}

(3)创建登录测试用例类

        创建 LoginPage 类,在这里编写登录页面的所有测试用例,在这里我们要完成的事情如下:

  • 检查登录页面是否正确加载;
  • 检查正常登录功能是否正常;
  • 检查异常登录功能是否正常。

        有关 LoginPage 类的具体代码及详细介绍如下所示:

public class LoginPage extends Utils {
    // 指定页面的 URL
    private static String url = "http://127.0.0.1:8080/login.html";
    // 设置显式等待
    private WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    // 创建构造方法, 传入 url
    public LoginPage() {
        super(url);
    }

    // 测试页面是否成功加载
    public void loginPageRight() throws InterruptedException {
        // 通过查看页面元素是否存在来检查页面加载是否成功
        // 查找状态提示框
        driver.findElement(By.cssSelector("#message"));
        // 获取页面标题
        String title = driver.getTitle();
        // 验证当前页面标题信息
        assert title.equals("音乐播放器登录页面");
    }

    // 检查登录功能----登录失败
    public void loginFail() throws InterruptedException {
        // 1. 测试用户名为空
        // 刷新当前页面,防止输入框中残留信息
        driver.navigate().refresh();
        driver.findElement(By.cssSelector("#user")).sendKeys("123");
        driver.findElement(By.cssSelector("#submit")).click();
        // 显式等待弹窗出现
        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        // 验证弹窗的文本信息
        assert alert.getText().equals("用户名或密码错误!");
        // 点击确定,关闭弹窗
        alert.accept();
        // 2. 测试用户名不存在
        driver.findElement(By.cssSelector("#user")).sendKeys("usseee");
        driver.findElement(By.cssSelector("#password")).sendKeys("123");
        driver.findElement(By.cssSelector("#submit")).click();
        wait.until(ExpectedConditions.alertIsPresent());
        assert alert.getText().equals("用户名或密码错误!");
        alert.accept();
        // 3. 测试用户名正确, 密码为空
        driver.findElement(By.cssSelector("#user")).sendKeys("lisi");
        driver.findElement(By.cssSelector("#submit")).click();
        wait.until(ExpectedConditions.alertIsPresent());
        assert alert.getText().equals("密码错误! ");
        alert.accept();
        // 4. 测试用户名正确, 密码错误
        driver.findElement(By.cssSelector("#user")).sendKeys("lisi");
        driver.findElement(By.cssSelector("#password")).sendKeys("232424");
        driver.findElement(By.cssSelector("#submit")).click();
        wait.until(ExpectedConditions.alertIsPresent());
        assert alert.getText().equals("密码错误! ");
        alert.accept();
    }

    // 检查登录功能----登录成功
    public void loginSuc() throws InterruptedException {
        // 刷新当前页面,防止输入框有残留信息
        driver.navigate().refresh();
        // 输入存在的用户名和正确的密码
        driver.findElement(By.cssSelector("#user")).sendKeys("lisi");
        driver.findElement(By.cssSelector("#password")).sendKeys("123456");
        driver.findElement(By.cssSelector("#submit")).click();
        // 显式等待, 等待弹窗出现
        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        // 验证弹窗文本信息
        assert alert.getText().equals("登录成功! ");
        // 点击确定,关闭弹窗
        alert.accept();
        // 获取当前页面标题
        String title = driver.getTitle();
        // 验证当前页面标题信息,观察是否成功跳转
        assert title.equals("在线音乐列表");
    }

}

(4)创建音乐列表测试用例类

        创建 ListPage 类,在这里编写列表页面的所有测试用例,在这里我们要完成的事情如下:

  • 检查列表页面是否能正确加载;
  • 检查音乐的查询功能是否正常;
  • 检查音乐的删除功能是否正常;
  • 检查选中音乐的删除功能是否正常;
  • 检查喜欢音乐的功能是否正常。

         有关 ListPage 类的具体代码及详细介绍如下所示:

public class ListPage extends Utils {
    // 指定页面的 URL
    private static String url = "http://127.0.0.1:8080/list.html";
    // 设置显式等待
    private WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(2));

    public ListPage() {
        super(url);
    }

    // 测试页面是否正确加载
    public void listPageRight() {
        driver.findElement(By.cssSelector("#exampleInputName2"));
        // 获取页面标题
        String title = driver.getTitle();
        // 验证当前页面标题信息
        assert title.equals("在线音乐列表");
    }

    // 检查音乐的查询功能
    public void selectMusic() {
        WebElement input = driver.findElement(By.cssSelector("#exampleInputName2"));
        input.sendKeys("李宇春 - 咏春");
        WebElement select = driver.findElement(By.cssSelector("#submit1"));
        select.click();
        List<WebElement> result = driver.findElements(By.cssSelector("#info > tr"));
        assert result.size() == 1;

        input.clear();
        input.sendKeys("南征北战");
        select.click();
        result = driver.findElements(By.cssSelector("#info > tr"));
        assert result.size() >= 1;

        input.clear();
        select.click();
        result = driver.findElements(By.cssSelector("#info > tr"));
        assert result.size() >= 1;

        input.clear();
        input.sendKeys("没有这个音乐");
        select.click();
        result = driver.findElements(By.cssSelector("#info > tr"));
        assert result.size() == 0;
        input.clear();
    }

    // 检查删除选中音乐的功能
    public void deleteSelMusic() {
        driver.findElement(By.cssSelector("#exampleInputName2")).sendKeys("");
        driver.findElement(By.cssSelector("#submit1")).click();
        List<WebElement> result = driver.findElements(By.cssSelector("#info > tr"));
        int i = result.size();
        if (i > 10) {
            driver.findElement(By.cssSelector("#\\31 " + (i % 10 - 1))).click();
        }else {
            driver.findElement(By.cssSelector("#\\3" + (i - 1))).click();
        }
        driver.findElement(By.cssSelector("#delete")).click();
        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        assert alert.getText().equals("音乐全部删除成功! ");
        alert.accept();
        i--;

        driver.navigate().refresh();
        int count = 3;
        assert count <= i;
        while (count > 0 && i > 10) {
            driver.findElement(By.cssSelector("#\\31 " + (i % 10 - 1))).click();
            i--;
            count--;
        }
        while (count > 0) {
            driver.findElement(By.cssSelector("#\\3" + (i - 1))).click();
            i--;
            count--;
        }
        driver.findElement(By.cssSelector("#delete")).click();
        wait.until(ExpectedConditions.alertIsPresent());
        assert alert.getText().equals("音乐全部删除成功! ");
        alert.accept();

        driver.findElement(By.cssSelector("#delete")).click();
        wait.until(ExpectedConditions.alertIsPresent());
        assert alert.getText().equals("批量删除音乐失败!! ");
        alert.accept();
    }

    // 检查删除音乐的功能
    public void deleteMusic() {
        driver.findElement(By.cssSelector("#exampleInputName2")).sendKeys("");
        driver.findElement(By.cssSelector("#submit1")).click();
        int index = driver.findElements(By.cssSelector("#info > tr")).size();
        driver.findElement(By.cssSelector("#del" + (index - 1))).click();
        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        assert alert.getText().equals("删除音乐成功! ");
        alert.accept();
    }

    // 检查喜欢音乐的功能
    public void loveMusic() {
        driver.findElement(By.cssSelector("#exampleInputName2")).sendKeys("");
        driver.findElement(By.cssSelector("#submit1")).click();
        int index = driver.findElements(By.cssSelector("#info > tr")).size();
        driver.findElement(By.cssSelector("#love" + (index - 1))).click();
        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        assert alert.getText().equals("喜欢成功! ");
        alert.accept();
    }
}

(5)创建喜欢列表测试用例类

        创建 LovePage 类,在这里编写喜欢列表页面的所有测试用例,在这里我们要完成的事情如下:

  • 检查喜欢列表页面是否能正确加载;
  • 检查喜欢音乐的查询功能是否正常;
  • 检查取消喜欢音乐的功能是否正常;
  • 检查回到大厅的按钮功能是否正常。

         有关 LovePage 类的具体代码及详细介绍如下所示:

public class LovePage extends Utils {
    // 指定页面的 URL
    private static String url = "http://127.0.0.1:8080/loveMusic.html";
    // 设置显式等待
    private WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    public LovePage() {
        super(url);
    }

    // 检查页面是否正确加载
    public void lovePageRight() {
        driver.findElement(By.cssSelector("body > div.container > div:nth-child(3) > a"));
        String title = driver.getTitle();
        assert title.equals("喜欢音乐列表");
    }

    // 检查喜欢音乐查询功能
    public void selLoveMusic() {
        WebElement input = driver.findElement(By.cssSelector("#exampleInputName2"));
        input.sendKeys("李宇春 - 咏春");
        WebElement select = driver.findElement(By.cssSelector("#submit1"));
        select.click();
        List<WebElement> result = driver.findElements(By.cssSelector("#info > tr"));
        assert result.size() == 1;

        input.clear();
        input.sendKeys("无涯");
        select.click();
        result = driver.findElements(By.cssSelector("#info > tr"));
        assert result.size() >= 1;

        input.clear();
        select.click();
        result = driver.findElements(By.cssSelector("#info > tr"));
        assert result.size() >= 1;

        input.clear();
        input.sendKeys("没有这个音乐");
        select.click();
        result = driver.findElements(By.cssSelector("#info > tr"));
        assert result.size() == 0;
        input.clear();
    }

    // 检查取消喜欢音乐功能
    public void delLoveMusic() throws InterruptedException {
        driver.findElement(By.cssSelector("#exampleInputName2")).sendKeys("");
        driver.findElement(By.cssSelector("#submit1")).click();
        int index = driver.findElements(By.cssSelector("#info > tr")).size();
        driver.findElement(By.cssSelector("#del0")).click();
        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        assert alert.getText().equals("取消喜欢音乐成功!");
        alert.accept();
    }

    // 检查回到大厅的按钮功能
    public void loveBack() {
        driver.findElement(By.cssSelector("body > div.container > div:nth-child(3) > a")).click();
        String title = driver.getTitle();
        assert title.equals("在线音乐列表");
    }
}

(6)创建上传音乐测试用例类

        创建 UploadPage 类,在这里编写上传音乐页面的所有测试用例,在这里我们要完成的事情如下:

  • 检查上传音乐页面是否能正确加载;
  • 检查上传音乐的功能是否正常;
  • 检查回到首页的连接跳转功能是否正常。

         有关 UploadPage 类的具体代码及详细介绍如下所示:

public class UploadPage extends Utils {
    // 指定页面的 URL
    private static String url = "http://127.0.0.1:8080/upload.html";
    // 设置显式等待
    private WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    public UploadPage() {
        super(url);
    }

    // 检查页面正确加载
    public void uploadPageRight() {
        // 查找是否有歌手输入框
        driver.findElement(By.cssSelector("#singerInput"));
        driver.findElement(By.cssSelector("#fileInput"));
        String title = driver.getTitle();
        assert title.equals("上传音乐");
    }

    // 检查上传音乐功能
    public void uploadMusic() throws InterruptedException {
        driver.findElement(By.cssSelector("#fileInput")).sendKeys("D:\\音乐下载\\李宇春 - 咏春.mp3");
        driver.findElement(By.cssSelector("#singerInput")).sendKeys("李宇春");
        driver.findElement(By.cssSelector("#uploadFrom > input[type=submit]:nth-child(3)")).click();
        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        assert alert.getText().equals("已经拥有当前歌曲! ");
        alert.accept();

        driver.navigate().refresh();
        driver.findElement(By.cssSelector("#fileInput")).sendKeys("D:\\音乐下载\\庞龙 - 兄弟抱一下 [mqms2].mp3");
        driver.findElement(By.cssSelector("#singerInput")).sendKeys("庞龙");
        driver.findElement(By.cssSelector("#uploadFrom > input[type=submit]:nth-child(3)")).click();
        wait.until(ExpectedConditions.alertIsPresent());
        assert alert.getText().equals("音乐上传成功! ");
        alert.accept();
        String title = driver.getTitle();
        assert title.equals("在线音乐列表");
    }

    // 检查返回首页的功能
    public void uploadBack() {
        driver.get(url);
        driver.findElement(By.cssSelector("#uploadFrom > a")).click();
        String title = driver.getTitle();
        assert title.equals("在线音乐列表");
    }

}

(7)创建运行测试用例类

        创建 RunTest 类, 在这里进行所有测试代码的运行,我们要以合理的方式调用每一个页面的所有测试方法,来进行在线音乐播放器的 UI 自动化测试,关于 RunTest 的具体代码及详细介绍如下所示:

public class RunTest {
    public static void main(String[] args) throws InterruptedException {
        // 1. 运行登录页面的测试用例自动化测试方法
        LoginPage loginPage = new LoginPage();
        loginPage.loginPageRight();
        loginPage.loginFail();
        loginPage.loginSuc();

        // 2. 运行上传音乐页面的测试用例自动化测试方法
        UploadPage uploadPage = new UploadPage();
        uploadPage.uploadPageRight();
        uploadPage.uploadMusic();
        uploadPage.uploadBack();

        // 3. 运行喜欢列表页面的测试用例自动化测试方法
        LovePage lovePage = new LovePage();
        lovePage.lovePageRight();
        lovePage.selLoveMusic();
        lovePage.delLoveMusic();
        lovePage.loveBack();

        // 4. 运行列表页面的测试用例自动化测试方法
        ListPage listPage = new ListPage();
        listPage.listPageRight();
        listPage.selectMusic();
        listPage.loveMusic();
        listPage.deleteMusic();
        listPage.deleteSelMusic();

        // 5. 释放 driver 对象
        Utils.driver.quit();
    }
}

3.自动化测试执行结果

        我们在 RunTest 类中进行运行,运行的过程及结果如下图所示:

        如上图运行过程所示,我们的自动化测试用例全部通过,在执行自动化测试的时候,我们要注意多次执行的时候,在上传音乐的方法中要更改新的上传音乐,否则就会上传音乐失败,在执行失败的时候要多用屏幕截图来抓取当时出错的场景。 

五、性能测试

        下面我来使用 JMeter 对在线音乐播放器项目的登录接口和获取音乐列表接口及获取喜欢音乐列表接口进行简单的性能测试,下面就来介绍在线音乐播放器项目性能测试的一个测试流程。

1.创建梯度压测线程组

        这里我们创建一个梯度压测线程组(Stepping Thread Group),来慢慢增大我们对这两个接口的并发请求的数量,创建的梯度压测线程组的具体配置如下图所示:

2.创建 HTTP 请求默认值

        在在线音乐播放器项目中涉及到的接口协议、IP、端口号及内容编码都完全一样,所以我们就可以把这些单独抽取出来,存放在默认值中,这样其他接口就可以省略不写协议、IP、端口号及内容编码了,这里我们具体设置的默认值如下图所示:

3.创建 HTTP Cookie 管理器

        如果我们在未登录状态进行获取音乐列表的操作,将会获取到一个空的音乐列表,这显然是不科学的,所以为了我们可以获取到登录请求中用户的用户信息就需要添加一个 HTTP Cookie 管理器,它会像浏览器一样存储和发送 Cookie ,如果我们 HTTP 请求返回的响应中包含 Cookie 那么 Cookie 管理器就会自动存储该 Cookie,并把这个 Cookie 用于后面特定的请求中,所以添加了 HTTP Cookie 管理器后,就会自动存储并发送 Cookie,添加的管理器如下图所示:

4.创建音乐播放器登录请求

        根据在线音乐播放器项目中用户登录的接口来编写用户登录请求的内容,具体内容如下图所示:

5.创建获取音乐列表页请求

        根据在线音乐播放器项目中获取音乐列表请求接口来编写获取音乐列表的内容,具体内容如下图所示:

6.创建获取喜欢音乐列表页请求

        根据在线音乐播放器项目中获取喜欢音乐列表请求接口来编写获取喜欢音乐列表的内容,具体内容如下图所示:

7.性能测试执行结果

        执行性能测试之前,我们添加以下四个监听器,它们的用途如下所示:

  • Active Thread Over Time:这是用来记录每一时刻存活线程的数目,最后形成一个图表;
  • Transactions per Second(TPS):这个监听器是用来分析系统吞吐量的重要工具。TPS 即每秒事务数,表示一个客户机向服务器发送请求后服务器做出反应的过程,这个指标反映了系统在同一时间内处理业务的最大能力,TPS 越高,说明系统的处理能力越强。
  • Response Times Over Time:这个监听器是用来监听整个事务运行期间的响应时间,在测试过程中,它可以帮我们观察并分析响应时间的实时平均值以及整体响应时间的走向,通过这个监听器,我们可以更直观的了解系统中不同时间点的响应性能,从而发现可能存在的性能问题;
  • 聚合报告:通过这个报告,可以看到性能测试过程中整体的数据变化。

        下面我们开始执行性能测试,关于各监听器执行后的结果,如下图所示:

8.生成性能测试报告

        执行完成性能测试之后,我们需要出具一份性能测试报告,这个报告不用我们手动进行编写,而是通过命令的方式使用 JMeter 来自动帮我们生成,具体操作如下图所示:

        关于上图中命令所涉及参数的含义,具体介绍如下所示:

  • -n:以无图形化运行;
  • -t:被运行的脚本;
  • -l:将运行信息写入日志文件,后缀为 jtl 的日志文件;
  • -e:生成测试报告;
  • -o:指定报告输出目录。 

注意:日志文件和目录可以不存在,若已经存在,要保证内容为空,否则会出现错误。

        那么测试报告生成之后,在 网页版五子棋性能测试报告 文件夹下将出现如下图所示的内容:

         双击 index.html 文件,界面展示如下:

        关于性能测试报告的具体内容我在这里就不进行过多展示了,感兴趣的小伙伴我会把这个报告附在本篇文章中,可以自行观察。 

·总结

        文章到此就要结束了,在这里我再对本篇测试报告做一个总结,我们一共进行了功能测试、自动化测试以及性能测试这三种测试方式,在功能测试阶段,我们着重点是对项目整体进行了一个简易的测试;在自动化测试阶段,我们主要测试各个页面的相关信息,着重测试了登录及音乐列表页面的相关功能;在性能测试阶段,我们着重测试了用户登录、获取用音乐列表、获取喜欢音乐列表的接口性能,并生成了性能测试报告,在以上过程中,遇到的问题就是执行自动化测试时会出现上传音乐失败的情况,这是因为我们每次运行自动化测试脚本时,都需要更改上传音乐的信息,否则就会出现音乐已经存在的情况,还有就是性能测试中,获取音乐列表及获取喜欢音乐列表为空,解决方式就是添加 HTTP Cookie 管理器,如果对文章内容有所疑惑,欢迎在评论区进行留言,如果感觉本篇文章还不错希望能收到你的三连支持,那么我们下一篇文章再见吧~~~

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

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

相关文章

TCP/IP协议攻击与防范

一、TCP/IP协议攻击介绍 1.1 Internet的结构​ LAN&#xff1a;局域网 WAN&#xff1a;广域网 WLAN&#xff1a;无线局域网 私有IP地址与公有IP地址&#xff1f; 私有地址&#xff1a;A类&#xff1a;10.0.0.0~10.255.255.255 B类&#xff1a;172.16.0.0~172.31.255.255…

Unity ShaderLab 实现3D物体描边

实现思路&#xff1a; 给物体添加第二个材质球&#xff0c;在shader的顶点着色器中使顶点的位置变大&#xff0c;然后在片元着色器中输出描边颜色。 shader Graph实现如下&#xff1a; ShaderLab实现如下&#xff1a; Shader "Custom/Outline" {Properties{[HDR]_…

复合查询和内外连接

文章目录 1. 简单查询2. 多表查询2.1 显示雇员名、雇员工资以及所在部门的名字2.2 显示部门号为10的部门名&#xff0c;员工名和工资2.3 显示各个员工的姓名&#xff0c;工资&#xff0c;及工资级别 3. 自连接4. 子查询4.1 where后的子查询4.1.1 单行子查询4.1.2 多行子查询 (i…

java八股-分布式服务的接口幂等性如何设计?

文章目录 接口幂等token Redis分布式锁 原文视频链接&#xff1a;讲解的流程特别清晰&#xff0c;易懂&#xff0c;收获巨大 【新版Java面试专题视频教程&#xff0c;java八股文面试全套真题深度详解&#xff08;含大厂高频面试真题&#xff09;】 https://www.bilibili.com/…

Windows Serv 2019 虚拟机 安装Oracle19c,图文详情(超详细)

1、下载安装文件 Oracle官网下载直链&#xff1a;https://www.oracle.com/database/technologies/oracle-database-software-downloads.html#db_ee 夸克网盘下载&#xff1a;https://pan.quark.cn/s/1460a663ee83 2、新建 Windows Server 2019 虚拟机 &#xff08;超详细&a…

时间的礼物:如何珍视每一刻

《时间的礼物&#xff1a;如何珍视每一刻》 夫时间者&#xff0c;宇宙之精髓&#xff0c;生命之经纬&#xff0c;悄无声息而流转不息&#xff0c;如织锦之细线&#xff0c;串联古今&#xff0c;贯穿万物。 人生短暂&#xff0c;犹如白驹过隙&#xff0c;倏忽而逝&#xff0c;…

FreeRTOS之vTaskStartScheduler实现分析

FreeRTOS之vTaskStartScheduler实现分析 1 FreeRTOS源码下载地址2 函数接口2.1 函数接口2.2 函数参数简介3 vTaskDelete的调用关系3.1 调用关系3.2 调用关系示意图 4 函数源码分析4.1 vTaskStartScheduler4.2 prvCreateIdleTasks4.2.1 prvCreateIdleTasks4.2.2 xTaskCreate 4.3…

NLP论文速读(EMNLP2024)|多风格可控生成的动态多奖励权重

论文速读|Dynamic Multi-Reward Weighting for Multi-Style Controllable Generation 论文信息&#xff1a; 简介&#xff1a; 本文探讨了文本风格在沟通中的重要性&#xff0c;指出文本风格传达了除原始语义内容之外的多种信息&#xff0c;如人际关系动态&#xff08;例如正式…

【AI】Sklearn

长期更新&#xff0c;建议关注、收藏、点赞。 友情链接&#xff1a; AI中的数学_线代微积分概率论最优化 Python numpy_pandas_matplotlib_spicy 建议路线&#xff1a;机器学习->深度学习->强化学习 目录 预处理模型选择分类实例&#xff1a; 二分类比赛 网格搜索实例&…

Dockerfile打包部署

Dockerfile打包 先找到打包完的目录下创建一个Dockerfile文件 touch Dockerfile 进去文件内编写 vim Dockerfile # 基础镜像 FROM openjdk:8 # author MAINTAINER yxh # 挂载目录 VOLUME /home/project # 创建目录 RUN mkdir -p /home/project # 指定路径 WORKDIR /home/pr…

鸿蒙学习使用模拟器运行应用(开发篇)

文章目录 1、系统类型和运行环境要求2、创建模拟器3、启动和关闭模拟器4、安装应用程序包和上传文件QA:在Windows电脑上启动模拟器&#xff0c;提示未开启Hyper-V 1、系统类型和运行环境要求 Windows 10 企业版、专业版或教育版及以上&#xff0c;且操作系统版本不低于10.0.18…

数组学习后记——递归

数组这块学得有点乱,条理性欠佳。这次正好总结一下。上周的课堂内容没有更新, 因为小白自己也还没来得及吸收呢qwq。也解释一下为什么文中有这么多例题。因为我呢喜欢就着题去分析和学习,直接灌输知识不太能理解,有例子就能及时检验和应用了的。 先看看B3817 基础的双数组…

每天五分钟深度学习:神经网络的前向传播的计算过程(单样本)

本文重点 本节课程我们学习神经网络的输出是如何计算的,这个过程叫做神经网络的前向传播。 神经网络的结构 如上所示是一个具有单隐藏层的神经网络,其中输入层不算神经网络的层数。 在这个神经网络中,x表示输入特征,a表示每个神经元的输出,W表示权重参数。 神经网络的…

C++——多态(下)

目录 引言 多态 4.多态的原理 4.1 虚函数表指针 4.2 多态的原理 5.单继承和多继承关系的虚函数表 5.1 单继承中的虚函数表 5.2 多继承中的虚函数表 结束语 引言 接下来我们继续学习多态。 没有阅读多态&#xff08;上&#xff09;的可以点击下面的链接哦~ C——多态…

【CSS in Depth 2 精译_061】9.4 CSS 中的模式库 + 9.5 本章小结

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 【第九章 CSS 的模块化与作用域】 ✔️ 9.1 模块的定义 9.1.1 模块和全局样式9.1.2 一个简单的 CSS 模块9.1.3 模块的变体9.1.4 多元素模块 9.2 将模块组合为更大的结构 9.2.1 模块中多个职责的拆分…

DHCP服务(包含配置过程)

目录 一、 DHCP的定义 二、 使用DHCP的好处 三、 DHCP的分配方式 四、 DHCP的租约过程 1. 客户机请求IP 2. 服务器响应 3. 客户机选择IP 4. 服务器确定租约 5. 重新登录 6. 更新租约 五、 DHCP服务配置过程 一、 DHCP的定义 DHCP&#xff08;Dynamic Host Configur…

技术实践 | AI 安全:通过大模型解决高危WEB应用识别问题

一、引言 在日常企业安全能力建设中&#xff0c;收敛企业外网高危资产&#xff0c;以保障公司外部安全是企业安全的重要工作。WEB 高危服务&#xff08;如&#xff1a;管理后台、内部系统等&#xff09;外开是企业所面临的一个重要风险。针对该风险&#xff0c;传统的方式是基…

C 语言函数递归探秘:从基础概念到复杂问题求解的进阶之路

我的个人主页 我的专栏&#xff1a;C语言&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;点赞❤ 收藏❤ 目录 什么是函数递归递归的基本组成递归的工作原理递归的优缺点递归的经典案例 5.1 阶乘计算5.2 斐波那契数列5.3 汉诺塔问题5.4 二分查找 递归的高级…

多输入多输出 | Matlab实现TCN-LSTM时间卷积神经网络结合长短期记忆神经网络多输入多输出预测

多输入多输出 | Matlab实现TCN-LSTM时间卷积神经网络结合长短期记忆神经网络多输入多输出预测 目录 多输入多输出 | Matlab实现TCN-LSTM时间卷积神经网络结合长短期记忆神经网络多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 多输入多输出 | Matlab实现…

「Mac畅玩鸿蒙与硬件33」UI互动应用篇10 - 数字猜谜游戏

本篇将带你实现一个简单的数字猜谜游戏。用户输入一个数字&#xff0c;应用会判断是否接近目标数字&#xff0c;并提供提示“高一点”或“低一点”&#xff0c;直到用户猜中目标数字。这个小游戏结合状态管理和用户交互&#xff0c;是一个入门级的互动应用示例。 关键词 UI互…