在线音乐播放器测试

在线音乐播放器测试报告

1. 项目背景

在线音乐播放器是一个简单的个人项目,主要通过项目来学习 spring boot , mybatis,spring AOP 等框架,以及测试流程

2. 项目简介


项目主要功能: 登录,注册,上传音乐,播放音乐,收藏音乐,搜索音乐,批量删除音乐等.

2.1登录页面


业务描述: 管理员用户需要通过登录页面进入在线音乐播放器系统,登录页面是进入系统的唯一页面

需求描述: 管理员需要输入用户名,密码才能登该系统.

行为人: 管理员

UI 界面:
在这里插入图片描述


业务规则:

  1. 用户名长度 1-8 区分大小写但不含特殊字符.
  2. 用户密码长度为 6 - 15 且不含特殊字符 当用户输入完用户名和用户密码点击登录才能进入系统.

2.2 主页面


业务描述: 登录系统后,管理员可以上传音乐,播放音乐,对上传后的音乐点击喜欢加入收藏,可以删除已上传的音乐,还可以通过搜索框对 音乐进行搜索. 除了但个删除单个收藏外,还支持 批量删除音乐和收藏音乐.


需求描述:

上传音乐 : 用户点击添加歌曲按钮后,跳转到上传歌曲页面.

播放音乐 : 用户选中歌曲后,点击播放音乐,网站通过读取服务器本地音乐文件进行播放.

添加喜欢: 用户选中歌曲后,点击喜欢按钮,歌曲被收藏然后跳转到收藏页面.

删除音乐: 用户选中歌曲后,点击删除按钮,歌曲被删除,如果歌曲再用户的收藏列表,歌曲一同被删除.

搜索音乐: 用户可以在搜索框输入歌曲名(可以不完整,支持模糊查询)然后点击查询 ,页面出现需要搜索的歌曲.

批量删除/喜欢: 用户对多首歌曲点击删除或喜欢,歌曲被删除或被添加至喜欢列表.

行为人: 管理员

UI 界面:

在这里插入图片描述

业务规则:

  1. 主页面的按钮点击后能供切换颜色,让用户感觉出按钮被点击.
  2. 用户为在输入框输入歌曲名点击查询将数据库中的歌曲全部查出放到页面
  3. 用户在输入框输入歌曲名应支持模糊查询 比如 输入 白,页面应将 歌曲含 白 的歌曲 都查出来并放到页面上.

2.3 收藏页面


业务描述: 在主页面点击喜欢列表后跳转至收藏页面,在收藏页面可以对收藏的音乐进行播放,删除,批量删除,搜索音乐.

需求描述:

播放音乐 : 用户选中歌曲后,点击播放音乐,网站通过读取服务器本地音乐文件进行播放.

删除音乐: 用户选中歌曲后,点击删除按钮,歌曲被删除,如果歌曲再用户的收藏列表,歌曲一同被删除.

搜索音乐: 用户可以在搜索框输入歌曲名(可以不完整,支持模糊查询)然后点击查询 ,页面出现需要搜索的歌曲.

批量删除: 用户对多首歌曲点击删除,歌曲被删除

行为人: 管理员

UI 界面:

在这里插入图片描述

业务规则:

  1. 主页面的按钮点击后能供切换颜色,让用户感觉出按钮被点击.
  2. 用户为在输入框输入歌曲名,点击查询将当前用户喜欢的音乐全部展示.
  3. 用户在输入框输入歌曲名应支持模糊查询 比如 输入 白,在当前用户收藏的音乐进行搜索,如果没有找到表格置空

2.4 上传音乐页面


业务描述: 用户在主页面点击添加歌曲跳转到上传音乐页面,在上传音乐页面,点击选择文件可以从本地上传 mp3 文件, 输入完歌手名后点即上传按钮完成音乐上传.

需求描述: 用户点击上传文件,从本地选中 mp3 文件后,在输入完歌手名后,点击上传按钮,对文件进行上传.

行为人: 管理员

UI 界面:

在这里插入图片描述

业务规则: 用户上传重复文件后,系统报错,提示文件已上传.

2.5 注册页面

业务描述: 用于注册用户

需求描述 : 用户 进入 注册页面后,输入用户名和密码,再次确认密码后,点击确定完成注册.

行为人: 用户

UI 界面:

在这里插入图片描述


业务规则:

  1. 用户名区分大小写但不含特殊字符
  2. 用户密码长度为 6 - 15且不含特殊字符, 当用户输入完用户名 , 密码和确认密码后才能点击按钮进行注册

3. 需求评测

4. 制定测试计划


目的 : 对在线音乐播放器进行测试.


测试内容:

模块名称测试点优先级说明
用户模块注册功能测试
用户模块登录并发性测试
主模块上传音乐功能测试
主模块播放音乐功能测试
主模块收藏音乐功能测试
主模块搜索音乐功能测试
主模块删除音乐功能测试
主模块批量删除/喜欢音乐功能测试
收藏模块播放音乐功能测试
收藏模块取消收藏功能测试
收藏模块搜索音乐功能测试
收藏模块批量取消收藏功能测试
上传模块上传音乐功能测试
上传模块上传大额文件性能测试


测试环境 :

  1. Windows
  2. 浏览器 Chrome 版本: 125.0.6422.142(正式版本) (64 位)


测试方法: 黑盒测试

测试工具: ApiPost , Selenium , Junit


测试人员 : 牧..

5. 设计测试用例

5.1 注册


用户名 : 用户名长度 1-8 区分大小写但不含特殊字符.

密码: 用户密码长度为 6 - 15, 当用户输入完用户名和用户密码点击登录才能进入系统

划分等价类

输入条件有效等价类无效等价类
用户名不含特殊字符且长度在 1-8 之间空白字符串
用户名含有特殊字符
用户名长度大于 8
密码不含特殊字符
长度在 6 - 15 之间
空白字符串
密码含有特殊字符
密码长度大于8

边界值

用户名密码
用户名长度: 0,1,2,7,8,9密码长度:5,6,7,14,15,16

测试用例

方案用户名密码确认密码注册预期说明
1abc123456123456有效注册成功,跳蛛至登录页面用户名不含特殊字符且大于1小于8
密码和确认密码相同,密码长度大于 6 小于 15
2123456123456无效注册失败,弹出提框用户名不能为空用户名长度小于1
3a123456123456有效注册成功,跳蛛至登录页面用户名不含特殊字符,用户名长度正好达到最低要求
密码和确认密码相同,密码长度大于 6 小于 15
4ab123456123456有效注册成功,跳蛛至登录页面用户名不含特殊字符,
用户名长度 大于 1 小于 8
密码和确认密码相同,密码长度大于 6 小于 15
5abc1234123456123456有效注册成功,跳蛛至登录页面用户名不含特殊字符,
用户名长度 大于 1 小于 8
密码和确认密码相同,密码长度大于 6 小于 15
6abc12345123456123456有效注册成功,跳蛛至登录页面用户名不含特殊字符,
用户名长度 大于 1 小于 8
密码和确认密码相同,密码长度大于 6 小于 15
7abc123456123456123456无效注册失败,弹出提示用户名长度大于8用户名长度大于8
8abc""\123456123456无效注册失败,弹出提示用户名含有特殊字符用户名含有特殊字符 " /
9abc1234512345无效注册失败,弹出提示密码长度小于6密码长度小于6
10abc12345671234567有效注册成功,跳蛛至登录页面用户名不含特殊字符,
用户名长度 大于 1 小于 8
密码和确认密码相同,密码长度大于 6 小于 15
11abc1234567123456712345671234567有效注册成功,跳蛛至登录页面用户名不含特殊字符,
用户名长度 大于 1 小于 8
密码和确认密码相同,密码长度大于 6 小于 15
12abc123456712345671123456712345671有效注册成功,跳蛛至登录页面用户名不含特殊字符,
用户名长度 大于 1 小于 8
密码和确认密码相同,密码长度大于 6 小于 15
13abc12345671234567121234567123456712无效注册失败,弹出提示密码长度大于15密码长度大于15
14abc123456无效注册失败,弹出提示框,密码不能为空密码长度小于6
15abc123456无效注册失败,弹出提示框,提示再次输入密码确认密码为空

5.2 登录

测试用例

方案用户密码登录预期说明
16输入已注册的用户名: abc123456有效登录成功跳转至主页面用户和密码已经保存在数据库
17输入未注册的用户名: abcd123456无效登录失败,弹出提示框提示用户未注册用户未注册 (数据库查询不到)
18输入含有特殊字符的用户名123456无效登录失败,弹出提示框提示用户名含有特殊字符用户名含有特殊字符
19输入已注册的用户名: abc12345无效登录失败,弹出提示框提示密码长度小于6密码长度小于6
20输入已注册的用户名: abc1234567
(错误密码)
无效登录失败,弹出提示框用户或密码错误密码错误
21输入已注册的用户名: abc1234567123456712无效登录失败,弹出提示框密码长度大于15密码长度大于15

5.3 主页面

方案功能操作步骤预期结果
22播放音乐选中哆啦A梦的播放音乐按钮点击音乐播放成功
23收藏歌曲选中需要收藏的歌曲点击喜欢按钮音乐被收藏,然后跳转至收藏页面
24收藏歌曲选中用户已收藏的歌曲点击喜欢按钮弹出提示框歌曲已收藏
25删除音乐选中要删除的歌曲点击删除按钮歌曲删除
26批量删除音乐选中需要删除的歌曲点击删除按钮歌曲删除
27校验登录未登录用户通过 URL 直接进入页面弹出提示框提示用户登录然后页面跳转至登录页面
28查找音乐用户在输入框输入完整歌曲名 如 哆啦A梦页面展示出有关哆啦A梦的歌曲
29查找音乐用户在输入框输入 部分歌曲名称 如 哆页面展示出有关 哆 的歌曲
30跳转功能用户点击添加歌曲或喜欢列表按钮页面跳转至上传文件页面或收藏页面

5.4 收藏页面

方案功能操作步骤预期结果
31播放音乐选中哆啦A梦的播放音乐按钮点击音乐播放成功
32取消收藏选中要取消收藏的歌曲点击删除按钮歌曲删除
33校验登录未登录用户通过 URL 直接进入页面弹出提示框提示用户登录然后页面跳转至登录页面
34查找音乐用户在输入框输入完整歌曲名 如 哆啦A梦页面展示出有关哆啦A梦的歌曲
35查找音乐用户在输入框输入 部分歌曲名称 如 哆页面展示出有关 哆 的歌曲
36跳转功能用户点击回到首页按钮页面跳转至主页面

5.5 添加歌曲

方案功能操作步骤预期结果
37上传歌曲点击选中文件,在本地选中要上出的 mp3 文件
然后输入歌手名点击上传
弹出提示框文件上传成功,页面跳转至主页面

6. 执行测试用例

搭建自动化测试环境: jdk8 + selenium + junit

创建 maven 项目 导入相关依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>csdn_test_demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- selenium 相关依赖-->
        <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>
        <!-- Junit 相关依赖-->
        <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>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-reporting</artifactId>
            <version>1.8.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>


创建 Constants,创建常量存储 url :

package constants;

public class Constants {
    //    public static final String LOGIN_URL = "https://www.csdn.net/";
    public static final String ALL_REQUEST = "--remote-allow-origins=*";
    public static final String MY_LOGIN_URL = "http://127.0.0.1:8080/login.html";
    public static final String MY_INDEX_URL = "http://127.0.0.1:8080/list.html";
    public static final String MY_REGISTER_URL = "http://127.0.0.1:8080/register.html";
    public static final String MY_LOVEMUSIC_URL = "http://127.0.0.1:8080/loveMusic.html";
    public static final String MY_UPLOADMUSICFILE_URL = "http://127.0.0.1:8080/upload.html";
    public static final String MY_FILE_UPLOAD_PATH = "D:/SSM项目存放/project/j_music/test/";

}

创建 DriverUtils ,更好获取 webDriver

package utils;

import constants.Constants;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;


public class DriverUtils {
    public static WebDriver getWebDriver() {
        ChromeOptions options = new ChromeOptions();
        // 允许浏览器接受来自任何源的远程请求
        options.addArguments(Constants.ALL_REQUEST);
        return new ChromeDriver(options);
    }
}

6.1 注册

页面 符合 UI 设计

在这里插入图片描述


编写自动化测试


在 resources 下创建 registerTest.csv 文件 存放 要测试的数据

在这里插入图片描述


测试数据

abc,123456,123456
,123456,123456
a,123456,123456
ab,123456,123456
abc1234,123456,123456
abc12345,123456,123456
abc123456,123456,123456
abc""\,123456,123456
abce,12345,12345
abcd,1234567,1234567
abcde,12345671234567,12345671234567
abcdef,123456712345671,123456712345671
abcf,1234567123456712,1234567123456712
abc,123456,
abc,,123456

创建 registerTest 类 , 编写自动化测试方法

package register;

import constants.Constants;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import utils.DriverUtils;

public class RegisterTest {

    private WebDriver webDriver;

    @AfterEach
    public void quit() {
        webDriver.quit();
    }

    @ParameterizedTest
    @CsvSource(value = "黑蛋243,123456,123456")
    public void singleRegister(String name, String password, String repetitionPassword) throws InterruptedException {
        WebDriver webDriver = DriverUtils.getWebDriver();
        webDriver.get(Constants.MY_REGISTER_URL);
        webDriver.findElement(By.cssSelector("#user")).sendKeys(name);
        webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
        webDriver.findElement(By.cssSelector("#repetition_password")).sendKeys(repetitionPassword);
        webDriver.findElement(By.cssSelector("#submit")).click();
        WebDriverWait wait = new WebDriverWait(webDriver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = webDriver.switchTo().alert();
        alert.accept();
        String currentUrl = webDriver.getCurrentUrl();
        Assertions.assertEquals(currentUrl, Constants.MY_LOGIN_URL);
    }

    @ParameterizedTest
    @CsvFileSource(resources = "/registerTest.csv")
    public void batchRegister(String name, String password, String repetitionPassword) {
        webDriver = DriverUtils.getWebDriver();
        webDriver.get(Constants.MY_REGISTER_URL);
        webDriver.findElement(By.cssSelector("#user")).sendKeys(name == null ? "" : name);
        webDriver.findElement(By.cssSelector("#password")).sendKeys(password == null ? "" : password);
        webDriver.findElement(By.cssSelector("#repetition_password")).sendKeys(repetitionPassword == null ? "" : repetitionPassword);
        webDriver.findElement(By.cssSelector("#submit")).click();
        WebDriverWait wait = new WebDriverWait(webDriver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = webDriver.switchTo().alert();
        alert.accept();
        String currentUrl = webDriver.getCurrentUrl();
        Assertions.assertEquals(currentUrl, Constants.MY_LOGIN_URL);
//        webDriver.quit();
    }
}

执行 batchRegister 方法 :

在这里插入图片描述

执行完自动化后,会发现出了密码为空和确认密码为空的两个用例没有过,其他的都通过了就说明:

  1. 系统没有对用户名做非空验证
  2. 系统没有对用户名做长度校验
  3. 系统没有对用户名是否含有特殊字符做校验
  4. 系统没有对密码长度做判断

此时数据库:

在这里插入图片描述

6.2 登录


页面符合 UI 设计

在这里插入图片描述

验证按钮是否可点击:

package login;

import constants.Constants;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import utils.DriverUtils;

import java.util.concurrent.TimeUnit;

public class MyMusicWebsiteLoginTest {

    private WebDriver driver;

    @BeforeEach
    public void getWebDriver() {
        driver = DriverUtils.getWebDriver();
    }

    @AfterEach
    public void quit() {
        driver.quit();
    }

    // 验证登录按钮是否有用
    @Test
    public void checkLongButton() {
        driver.get(Constants.MY_LOGIN_URL);
        // 找到 button 按钮进行点击
        driver.findElement(By.cssSelector("#submit")).click();
        // 校验是否出现弹出框
        WebDriverWait wait = new WebDriverWait(driver, 6);
        // 等待弹出框
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        Assertions.assertNotNull(alert);
        alert.accept();
    }
}


测试通过

在这里插入图片描述


测试登录功能:

  1. 登录成功: 判断依据用户输入完账户密码后点击确认按钮,成功进入到主页面 (判断当前 页面 url 是否为主页面 url 即可)
  2. 登录失败 : 判断是点击完弹窗是否还是在 登录页面即可

编写自动化测试脚本:


    @ParameterizedTest
    @CsvSource(value = "abc,123456")
    public void checkLoginSuccess(String name, String password) {
        driver.get(Constants.MY_LOGIN_URL);
        driver.findElement(By.cssSelector("#user")).sendKeys(name == null ? "" : name);
        driver.findElement(By.cssSelector("#password")).sendKeys(password == null ? "" : password);
        driver.findElement(By.cssSelector("#submit")).click();
        // 此时出现 alter
        WebDriverWait wait = new WebDriverWait(driver, 5);
        // 显示等待出现弹出框
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        // 判断 alert --> 到这里就可以判断出否登录成功了
        Assertions.assertEquals("登录成功!!!", alert.getText());
        alert.accept();
        // 在这里还可以通过判断 url
        String currentUrl = driver.getCurrentUrl();
        Assertions.assertEquals(Constants.MY_INDEX_URL, currentUrl);
    }


测试结果:

在这里插入图片描述

构造测试数据(登录失败用例): 在 resources 创建 logintest.csv 在文件中输入一下数据.

abc,123456
abcd,123456
abc/"",123456
abc,12345
abc,1234567
abc,1234567123456712

编写自动化脚本

  @ParameterizedTest
    @CsvFileSource(resources = "/logintest.csv")
    public void checkLoginFail(String name, String password) {
        driver.get(Constants.MY_LOGIN_URL);
        driver.findElement(By.cssSelector("#user")).sendKeys(name == null ? "" : name);
        driver.findElement(By.cssSelector("#password")).sendKeys(password == null ? "" : password);
        driver.findElement(By.cssSelector("#submit")).click();
        // 显示等待 弹出框
        WebDriverWait wait = new WebDriverWait(driver, 5);
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());

        if (name == null || name.equals("") || Objects.equals(password, "")) {
            Assertions.assertEquals("用户名或密码为空 !!!", alert.getText());
        } else {
            Assertions.assertEquals("用户名或密码错误 !!!!", alert.getText());
        }
        alert.accept();
        // 判断 url
        Assertions.assertEquals(Constants.MY_LOGIN_URL, driver.getCurrentUrl());
    }

在这里插入图片描述

这里 abc , 123456 是 正确的账号和密码 所以被拦住了

看完上面运行会发现问题:

  1. 未对用户名做长度校验
  2. 未对密码做长度校验
  3. 未校验用户名是否含有特殊字符

6.2 主页面


页面符合 UI 设计

在这里插入图片描述


执行测试用例:

方案功能操作步骤预期结果
22播放音乐选中哆啦A梦的播放音乐按钮点击音乐播放成功
23收藏歌曲选中需要收藏的歌曲点击喜欢按钮音乐被收藏,然后跳转至收藏页面
24收藏歌曲选中用户已收藏的歌曲点击喜欢按钮弹出提示框歌曲已收藏
25删除音乐选中要删除的歌曲点击删除按钮歌曲删除
26批量删除音乐选中需要删除的歌曲点击删除按钮歌曲删除
27校验登录未登录用户通过 URL 直接进入页面弹出提示框提示用户登录然后页面跳转至登录页面
28查找音乐用户在输入框输入完整歌曲名 如 哆啦A梦页面展示出有关哆啦A梦的歌曲
29查找音乐用户在输入框输入 部分歌曲名称 如 哆页面展示出有关 哆 的歌曲
30跳转功能用户点击添加歌曲或喜欢列表按钮页面跳转至上传文件页面或收藏页面
31上传音乐点击选中文件,在本地选中要上出的 mp3 文件
然后输入歌手名点击上传
弹出提示框文件上传成功,页面跳转至主页面

编写自动化脚本:

package login;

import constants.Constants;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.*;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import utils.DriverUtils;

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


@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class MainPageTest {

    private static WebDriver webDriver;

    // 在所有方法执行之前执行一下这个获取 driver 的方法
    @BeforeAll
    static void getWebDriver() {
        webDriver = DriverUtils.getWebDriver();
    }

    // 在所有方法执行之后 对 driver 进行关闭
    @AfterAll
    static void quit() {
        webDriver.quit();
    }

    @Order(1)
    @Test
    // 未登录直接通过 url 进入 主页面
    public void noLoginEnterIHomePage() {
        webDriver.get(Constants.MY_INDEX_URL);
        // 此时会直接回到登录页面
        String currentUrl = webDriver.getCurrentUrl();
        Assertions.assertEquals(Constants.MY_LOGIN_URL, currentUrl);
    }


    //  登录
    @Order(2)
    @ParameterizedTest
    @CsvSource(value = "abc,123456")
    public void login(String name, String password) {
//        webDriver.get(Constants.MY_LOGIN_URL);
        webDriver.findElement(By.cssSelector("#user")).sendKeys(name == null ? "" : name);
        webDriver.findElement(By.cssSelector("#password")).sendKeys(password == null ? "" : password);
        webDriver.findElement(By.cssSelector("#submit")).click();
        // 此时出现 alter
        WebDriverWait wait = new WebDriverWait(webDriver, 5);
        // 显示等待出现弹出框
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        // 判断 alert --> 到这里就可以判断出否登录成功了
        Assertions.assertEquals("登录成功!!!", alert.getText());
        alert.accept();
    }


    @Order(3)
    @Test
    public void playMusic() {
        webDriver.findElement(By.cssSelector("#info > tr:nth-child(1) > td:nth-child(4) > button")).click();

        // 此时判断歌曲是否被播放,只要判断播放器,上显示歌曲的名字是否不为 空即可
        String musicName = webDriver.findElement(By.cssSelector("#body > div:nth-child(2) > div > div > div.topbar > div.topbar-program > div.topbar-program-title")).getText();
        Assertions.assertNotEquals("", musicName);
    }

    @Order(4)
    @Test
    public void loveMusic() {
        webDriver.findElement(By.cssSelector("#info > tr:nth-child(1) > td:nth-child(5) > button:nth-child(2)")).click();
        // 弹出提示框
        WebDriverWait wait = new WebDriverWait(webDriver, 5);
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        String loveMusicDesc = alert.getText();
        alert.accept();
        if (loveMusicDesc.equals("歌曲已经收藏,请重新选择")) {
            return;
        }
        Assertions.assertEquals("添加成功", loveMusicDesc);
//        webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
        // 此时跳转至喜欢页面
        String currentUrl = webDriver.getCurrentUrl();
        Assertions.assertEquals(Constants.MY_LOVEMUSIC_URL, currentUrl);

        // 此时将喜欢音乐添加成功,将页面退回至主页面 通过窗口操作
        webDriver.navigate().back();
    }

    // 添加重复的音乐
    @Order(5)
    @Test
    public void loveRepetitionMusic() {
        webDriver.findElement(By.cssSelector("#info > tr:nth-child(1) > td:nth-child(5) > button:nth-child(2)")).click();
        // 弹出提示框
        WebDriverWait wait = new WebDriverWait(webDriver, 5);
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        String loveMusicDesc = alert.getText();
        Assertions.assertEquals("歌曲已经收藏,请重新选择", loveMusicDesc);
        alert.accept();
//        webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
        // 此时跳转至喜欢页面
        String currentUrl = webDriver.getCurrentUrl();
        Assertions.assertEquals(Constants.MY_INDEX_URL, currentUrl);

        // 此时将喜欢音乐添加成功,将页面退回至主页面 通过窗口操作
//        webDriver.navigate().back();
    }


    // 上传音乐
    @Order(6)
    @ParameterizedTest
    @CsvFileSource(resources = "/musicName.csv")
    public void uploadMusicFile(String musicName, String singerName) {
        webDriver.findElement(By.cssSelector("#body > div.container > div:nth-child(3) > a:nth-child(2)")).click();
        // 此时页面进行跳转
        // 上传文件 1.找到上传文件按钮,然后通过 sendKeys 输入要上传文件的路径即可
        webDriver.findElement(By.cssSelector("body > form > input[type=file]:nth-child(1)")).sendKeys(Constants.MY_FILE_UPLOAD_PATH + musicName);

        // 输入歌手名 --> 避免上传文件重复 (后端主要同故宫 判断歌曲名和歌手名) 这里就对 歌手名加一个随机数
        singerName = singerName + DriverUtils.getRandomStr(Constants.LEN_5);
        // 输入歌手名
        webDriver.findElement(By.cssSelector("body > form > label > input[type=text]")).sendKeys(singerName);

        // 点击上传按钮
        webDriver.findElement(By.cssSelector("body > form > input[type=submit]:nth-child(3)")).click();

        // 此时校验是否长传成功,判断当前页面的 url 是否为主页面即可
        String currentUrl = webDriver.getCurrentUrl();
//        System.out.println("------------------当前页面Url: " + currentUrl + "----------------");
        Assertions.assertEquals(Constants.MY_INDEX_URL, currentUrl);
    }


    @Order(7)
    @ParameterizedTest
    @CsvFileSource(resources = "/findMusicKeys.csv")
    public void findMusicByKey(String key) {
        // 找到查找框
        webDriver.findElement(By.cssSelector("#exampleInputName2")).sendKeys(key);
        // 点击查询按钮
        webDriver.findElement(By.cssSelector("#submit1")).click();

        // 拿到整个 表格
        WebElement tableElement = webDriver.findElement(By.cssSelector("#info"));

        // 获取 表格中的每一行的数据
        List<WebElement> trElements = tableElement.findElements(By.tagName("tr"));
        // 这里的结构是
        // <tr>xxxxx<tr/>
        // <tr><tr/>
        for (WebElement nowTrLabel : trElements) {
            // 获取到当前 tr 标签
            // 获取标签中的 th 元素
            List<WebElement> thElements = nowTrLabel.findElements(By.tagName("td"));
            if (thElements.isEmpty()) {
                continue;
            }
            // 此时不为空 -- 校验 musicName
            WebElement thElement = thElements.get(0);
            // 判断 音乐名是否含有 key 比如 哆啦a梦 是否含有 哆
            Assertions.assertTrue(thElement.getText().contains(key));
        }

        // 此时查找完成后,再次找到输入框 输入 "" , 再次点击查询按钮 查询到所有的音乐
        // 找到查找框
//        webDriver.findElement(By.cssSelector("#exampleInputName2")).sendKeys("");
        // 点击查询按钮
        webDriver.findElement(By.cssSelector("#submit1")).click();
    }

    // 删除音乐 --> 删除单个音乐
    @Order(8)
    @Test
    public void deleteMusic() {
        // 获取 表格
        WebElement tableElement = webDriver.findElement(By.cssSelector("#info"));

        // 获取 表格中的每一行的数据
        List<WebElement> trElements = tableElement.findElements(By.tagName("tr"));

        int totalSize = trElements.size();

        // 删除最后一个
        WebElement finallyTrElement = trElements.get(trElements.size() - 2);

        // 拿到勾选框
        List<WebElement> thElements = finallyTrElement.findElements(By.tagName("th"));
        List<WebElement> tdElements = finallyTrElement.findElements(By.tagName("td"));

        // 找到 input 框进行点击
        thElements.get(0).findElement(By.tagName("input")).click();
        // 找到删除按钮
        List<WebElement> buttons = tdElements.get(3).findElements(By.tagName("button"));
        WebElement deleteButton = buttons.get(0);
        deleteButton.click();
        // 此时删除音乐弹出对话框
        WebDriverWait wait = new WebDriverWait(webDriver, 5);
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        alert.accept();
        // 判断是否删除 重新获取 table 判断个数即可

        // 获取 表格
        tableElement = webDriver.findElement(By.cssSelector("#info"));

        // 获取 表格中的每一行的数据
        trElements = tableElement.findElements(By.tagName("tr"));

        Assertions.assertEquals(totalSize - 2, trElements.size());
    }


    // 批量删除音乐
    @Order(9)
    @ParameterizedTest
    @CsvSource(value = "3")
    public void batchDeleteMusic(Integer count) {

        // 获取整个表格
        WebElement tableElement = webDriver.findElement(By.cssSelector("#info"));

        // 获取 tr 标签
        List<WebElement> trElements = tableElement.findElements(By.tagName("tr"));

        int totalSize = trElements.size();

        // 循环勾选
        for (int i = 0; i < count * 2; i += 2) {
            // 拿到勾选框
            WebElement nowTrElement = trElements.get(i);
            // 获取 th 标签里面的 input
            WebElement thElement = nowTrElement.findElement(By.tagName("th"));
            // 找到 input 框 进行勾选
            thElement.findElement(By.tagName("input")).click();
        }

        // 此时该删除的都勾选了 点击 批量删除按钮
        webDriver.findElement(By.cssSelector("#delete")).click();
        WebDriverWait wait = new WebDriverWait(webDriver, 5);
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        alert.accept();

        // 校验是否删除成功 --> 判断当前表格 tr 个数即可
        tableElement = webDriver.findElement(By.cssSelector("#info"));
        trElements = tableElement.findElements(By.tagName("tr"));
        
        Assertions.assertEquals(totalSize - count * 2, trElements.size());
    }
}


执行脚本:

在这里插入图片描述

校验登录不符合预期结果,用户在未登录的情况下,进入 主页面并没有弹出提示框而是直接回到登录页面.

6.3 收藏页面

页面符合 UI 设计

在这里插入图片描述

方案功能操作步骤预期结果
32播放音乐选中哆啦A梦的播放音乐按钮点击音乐播放成功
33取消收藏选中要取消收藏的歌曲点击删除按钮歌曲删除
34校验登录未登录用户通过 URL 直接进入页面弹出提示框提示用户登录然后页面跳转至登录页面
35查找音乐用户在输入框输入完整歌曲名 如 哆啦A梦页面展示出有关哆啦A梦的歌曲
36查找音乐用户在输入框输入 部分歌曲名称 如 哆页面展示出有关 哆 的歌曲
36跳转功能用户点击回到首页按钮页面跳转至主页面
37校验登录未登录用户通过 URL 直接进入页面弹出提示框提示用户登录然后页面跳转至登录页面

编写自动化脚本:

package login;

import constants.Constants;
import org.checkerframework.checker.units.qual.A;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.*;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import utils.DriverUtils;

import java.awt.*;
import java.lang.annotation.Documented;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Random;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class LovePageTest {
    private static WebDriver webDriver;

    // 在所有方法执行之前执行一下这个获取 driver 的方法
    @BeforeAll
    static void getWebDriver() {
        webDriver = DriverUtils.getWebDriver();
    }

    // 在所有方法执行之后 对 driver 进行关闭
    @AfterAll
    static void quit() {
        webDriver.quit();
    }

    @Order(1)
    @Test
    // 未登录直接通过 url 进入 收藏页面
    public void noLoginEnterIHomePage() {
        webDriver.get(Constants.MY_LOVEMUSIC_URL);
        // 此时会直接回到登录页面
        String currentUrl = webDriver.getCurrentUrl();

        Assertions.assertEquals(Constants.MY_LOGIN_URL, currentUrl);
    }

    //  登录
    @Order(2)
    @ParameterizedTest
    @CsvSource(value = "abc,123456")
    public void login(String name, String password) {

//        webDriver.get(Constants.MY_LOGIN_URL);
        webDriver.findElement(By.cssSelector("#user")).sendKeys(name == null ? "" : name);
        webDriver.findElement(By.cssSelector("#password")).sendKeys(password == null ? "" : password);
        webDriver.findElement(By.cssSelector("#submit")).click();
        // 此时出现 alter
        WebDriverWait wait = new WebDriverWait(webDriver, 5);
        // 显示等待出现弹出框
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        // 判断 alert --> 到这里就可以判断出否登录成功了
        Assertions.assertEquals("登录成功!!!", alert.getText());
        alert.accept();
    }

    // 防止收藏页面没有歌曲,先对歌曲进行收藏
    @Order(3)
    @Test
    public void loveMusic() {
        // 拿到表格
        WebElement tableElement = webDriver.findElement(By.cssSelector("#info"));
        List<WebElement> trElements = tableElement.findElements(By.tagName("tr"));
//        int randomUnevenNumber = DriverUtils.getRandomEvenNumber(trElements.size());
        // 拿到勾选框
        List<WebElement> thElements = null;
        List<WebElement> tdElements = null;
        while (true) {
            int size = new Random().nextInt(trElements.size());
            thElements = trElements.get(size).findElements(By.tagName("th"));
            tdElements = trElements.get(size).findElements(By.tagName("td"));
            if (thElements.size() == 1) {
                break;
            }
        }
        thElements.get(0).click();
        // 拿到喜欢按钮

        WebElement treeTdElement = tdElements.get(3);
        List<WebElement> buttons = treeTdElement.findElements(By.tagName("button"));
        WebElement loveButton = buttons.get(1);
        // 使用JavaScript滚动到元素位置 --> 要不然找会找不到按钮点击会报错
//        ((JavascriptExecutor) webDriver).executeScript("arguments[0].scrollIntoView(true);", loveButton);
//        loveButton.click();

        // 上面移动还是有点问题 直接 调用 javascript 进行点击即可
        // 使用JavaScript点击元素
        ((JavascriptExecutor) webDriver).executeScript("arguments[0].click();", loveButton);

        // 点击弹窗
        WebDriverWait wait = new WebDriverWait(webDriver, 5);
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());

        if (!alert.getText().equals("添加成功")) {
            return;
        }
        alert.accept();
        // 校验 url
        String currentUrl = webDriver.getCurrentUrl();
        Assertions.assertEquals(Constants.MY_LOVEMUSIC_URL, currentUrl);

        // 退回 主页面
        webDriver.navigate().back();
    }

    // 点击添加歌曲按钮进入收藏页面
    @Order(4)
    @Test
    public void clickLoveButton() {
        // 找到按钮进行点击
        webDriver.findElement(By.cssSelector("#body > div.container > div:nth-child(3) > a:nth-child(1)")).click();
        String currentUrl = webDriver.getCurrentUrl();
        Assertions.assertEquals(Constants.MY_LOVEMUSIC_URL, currentUrl);
    }

    // 播放音乐
    @Order(5)
    @Test
    public void playMusic() {
        webDriver.findElement(By.cssSelector("#info > tr:nth-child(1) > td:nth-child(3) > button")).click();
        WebDriverWait wait = new WebDriverWait(webDriver, 5);
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div:nth-child(2) > div > div > div.topbar > div.topbar-program > div.topbar-program-title")));
        // 此时判断歌曲是否被播放,只要判断播放器,上显示歌曲的名字是否不为 空即可
        String musicName = webDriver.findElement(By.cssSelector("body > div:nth-child(2) > div > div > div.topbar > div.topbar-program > div.topbar-program-title")).getText();
//        System.out.println(musicName);
        Assertions.assertNotEquals("", musicName);
    }

    // 查找收藏音乐

    @Order(6)
    @ParameterizedTest
    @CsvFileSource(resources = "/findMusicKeys.csv")
    public void findLoveMusicByKey(String key) {
        // 找到查找框
        webDriver.findElement(By.cssSelector("#exampleInputName2")).sendKeys(key);
        // 点击查询按钮
        webDriver.findElement(By.cssSelector("#submit1")).click();
        // 拿到整个 表格
        WebElement tableElement = webDriver.findElement(By.cssSelector("#info"));
        // 获取 表格中的每一行的数据
        List<WebElement> trElements = tableElement.findElements(By.tagName("tr"));
        // 这里的结构是
        // <tr>xxxxx<tr/>
        // <tr><tr/>
        for (WebElement nowTrLabel : trElements) {
            // 获取到当前 tr 标签
            // 获取标签中的 th 元素
            List<WebElement> thElements = nowTrLabel.findElements(By.tagName("td"));
            if (thElements.isEmpty()) {
                continue;
            }
            // 此时不为空 -- 校验 musicName
            WebElement thElement = thElements.get(0);
            // 判断 音乐名是否含有 key 比如 哆啦a梦 是否含有 哆
            Assertions.assertTrue(thElement.getText().contains(key));
        }
        webDriver.findElement(By.cssSelector("#submit1")).click();

    }

    // 移除收藏音乐
    @Order(7)
    @Test
    public void deleteLoveMusic() {
        webDriver.findElement(By.cssSelector("#info > tr:nth-child(1) > td:nth-child(4) > button")).click();
        WebDriverWait wait = new WebDriverWait(webDriver, 5);
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        alert.accept();
        String currentUrl = webDriver.getCurrentUrl();
        Assertions.assertEquals(Constants.MY_INDEX_URL, currentUrl);
    }

}

运行结果:

在这里插入图片描述

到此该项目基础功能都测试完成, 简述当前系统存在的 bug

注册:

  1. 未对用户名做长度校验

  2. 未对用户名做特殊字符判断 (用户名包含特殊字符)

  3. 未对用户输入框做判空校验 (用户名可以未空 ,然后进行注册)

  4. 未对用户密码做长度校验

登录:

  1. 未对用户名做长度校验
  2. 未对用户名做特殊字符判断 (用户名包含特殊字符)
  3. 未对用户密码做长度校验

主页面:

  1. 用户在未登录情况下 ,通过 url 进入主页面后,直接跳转至登录页面 (未弹出提示框让用户登录)
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值