音乐云测试报告
目录
一、项目背景
二、项目功能
三、测试计划
1.编写测试用例
1.1功能测试
1.2界面测试
1.3兼容性测试
1.4易用性测试
1.5性能测试
1.6安全性测试
2.执行手工测试
2.1 账号登录功能测试
登录成功验证
登录失败验证
2.2 账号注册功能测试
注册成功验证
注册失败验证
2.3 音乐上传功能测试
上传成功验证
上传失败验证
2.4 音乐删除操作验证
2.5 音乐模糊检索功能测试
2.6 音乐播放功能测试
2.7 收藏管理功能测试
3.使用selenium进行自动化测试
添加相关依赖
3.1 编写公共父类
3.2 注册功能测试
3.3 登录功能测试
3.4 上传音乐功能测试
3.5 音乐收藏管理功能测试
3.6 播放音乐功能测试
3.7 搜索音乐功能测试
3.8 删除音乐功能测试
一、项目背景
我开发的这个简易在线音乐服务器项目,核心目标是为用户打造一款轻量且易上手的音乐管理工具。它能让大家便捷地完成个人音乐文件的上传、整理、查找与分享操作,无需依赖复杂的第三方平台。借助这个项目,用户既能拥有贴合自己喜好的个性化音乐空间,又能保障音乐存储与聆听的私密性,同时还能高效管理自己的曲库,最终获得更省心、更贴合个人需求的音乐体验。
二、项目功能
- 登录系统 —— 通过账号密码验证后,即可进入音乐列表页面
- 上传音乐文件 —— 支持用户将 MP3 格式的音乐上传至服务器
- 删除单首音乐 —— 用户能够移除指定的某首音乐
- 批量删除功能 —— 支持用户一次性删除所有选中的音乐
- 音乐查询 —— 用户可通过音乐名称进行模糊搜索,快速找到目标音乐
- 音乐播放 —— 集成 Sewise Player 开源播放器,实现音乐的在线播放
- 添加至我的喜欢 —— 用户可将选中的音乐收藏到个人喜欢列表中
- 移除喜欢音乐 —— 支持用户从个人喜欢列表中删除不再需要的音乐
三、测试计划
1.编写测试用例
从功能测试、界面测试、安全性测试、性能测试、易用性测试、兼容性测试这六个方面来编写:
1.1功能测试
1.2界面测试
1.3兼容性测试
1.4易用性测试
1.5性能测试
1.6安全性测试
2.执行手工测试
2.1 账号登录功能测试
登录成功验证
测试目的:验证登陆功能
测试步骤:
1.在登陆界面填写正确的账号密码
2.点击登录
预期结果:系统弹出登录成功提示弹窗,并自动跳转至音乐列表页面
实际结果:系统弹出登录成功提示弹窗,且成功跳转至音乐列表页面
登录失败验证
测试目的:验证登陆功能
测试步骤:
1.在登陆界面填写错误的账号密码
2.点击登录
预期结果:系统弹出登录失败提示弹窗,点击确定后页面不跳转
实际结果:系统弹出登录失败提示弹窗,点击确定后页面不跳转
2.2 账号注册功能测试
注册成功验证
测试目的:验证注册功能
测试步骤:
1.在注册界面填写与其他人不重复的用户名进行注册
2.点击注册
预期结果:系统弹出注册成功提示弹窗,点击确定后页面跳转到登录页
实际结果:系统弹出注册成功提示弹窗,点击确定后页面跳转到登录页
注册失败验证
测试目的:验证注册功能
测试步骤:
1.在注册界面填写与其他人重复的用户名进行注册
2.点击注册
预期结果:系统弹出注册失败提示弹窗,点击确定后页面不跳转
实际结果:系统弹出注册成功提示弹窗,点击确定后页面不跳转
2.3 音乐上传功能测试
上传成功验证
测试目的:验证音乐上传功能
测试步骤:
1.在音乐上传界面填写上传的音乐信息,并上传MP3格式的音乐文件
2.点击上传
预期结果:系统弹出上传成功提示弹窗,点击确定后页面跳转到主页
实际结果:系统弹出上传成功提示弹窗,点击确定后页面跳转到主页
上传失败验证
测试目的:验证音乐上传功能
测试步骤:
1.在音乐上传界面填写上传的音乐信息,并上传非MP3格式的音乐文件
2.点击上传
预期结果:系统弹出上传失败提示弹窗,点击确定后页面不跳转
实际结果:系统弹出上传失败提示弹窗,点击确定后页面不跳转
2.4 音乐删除操作验证
测试目的:验证音乐删除功能
前提条件:只能删除用户自己上传的音乐
测试步骤:
1.在全部音乐界面找到自己上传的音乐,点击右侧的”垃圾桶“按钮
2.提示弹窗是否要删除
预期结果:点击确定后删除成功
实际结果:点击确定后删除成功
2.5 音乐模糊检索功能测试
测试目的:验证音乐模糊检索的功能
前提条件:音乐库中要有用户上传的音乐
测试步骤:
1.全部音乐界面点击顶部的搜索框,输入关键词
2.检查页面是否都是包含当前关键词的音乐
预期结果:页面都是包含关键词的音乐
实际结果:页面都是包含关键词的音乐
2.6 音乐播放功能测试
测试目的:验证音乐播放的功能
前提条件:音乐库中要有用户上传的音乐
测试步骤:
1.在全部音乐界面点击任意音乐的右侧播放按钮
2.检查页面底部是否显示当前正在播放的音乐信息3.点击底部的暂停按钮,播放按钮,是否正常
预期结果:播放功能正常,底部下方正常显示当前播放的音乐信息
实际结果:播放功能正常,底部下方正常显示当前播放的音乐信息
2.7 收藏管理功能测试
测试目的:验证音乐收藏的功能
前提条件:音乐库中要有用户上传的音乐
测试步骤:
1.在全部音乐界面点击任意音乐的右侧收藏按钮
2.检查我的喜欢页面是否显示收藏的音乐3.在我的喜欢页面点击任意音乐的右侧取消收藏按钮
4.检查是否取消收藏成功
预期结果:点击收藏按钮后收藏音乐成功,在我的喜欢页面点击取消收藏后,取消成功
实际结果:点击收藏按钮后收藏音乐成功,在我的喜欢页面点击取消收藏后,取消成功
3.使用selenium进行自动化测试
自动化测试代码地址:自动化测试: 自动化测试代码 - Gitee.com
下面将展示UI自动化测试的部分相关代码
添加相关依赖
<!--驱动管理--><dependency><groupId>io.github.bonigarcia</groupId><artifactId>webdrivermanager</artifactId><version>5.8.0</version><scope>test</scope></dependency><!--安装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></dependencies>
3.1 编写公共父类
public class Utils {// 驱动public static WebDriver driver;// 显示等待public static WebDriverWait wait;public Utils(String url) {createDriver();wait = new WebDriverWait(driver, Duration.ofSeconds(3));driver.get(url);}/*** 创建驱动* @return*/public WebDriver createDriver() {if (driver == null) {// 谷歌浏览器驱动WebDriverManager.chromedriver().setup();ChromeOptions options = new ChromeOptions();options.addArguments("--remote-allow-origins=*");driver = new ChromeDriver(options);// 隐式等待 整个driver都使用整个隐式等待来等待元素driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));}return driver;}/*** 屏幕截图* 路径:.src/test/java/images/* /2025-05-27/test01-21105511.png* /2025-05-28/test02-20104522.png* @param str 调用这个方法的方法名*/public void screenShot(String str) throws IOException {SimpleDateFormat simp1 = new SimpleDateFormat("yyyy-MM-dd");// 年月日SimpleDateFormat simp2 = new SimpleDateFormat("HHmmssSS");// 时分秒毫秒String dirTime = simp1.format(System.currentTimeMillis());// 目录名String fileTime = simp2.format(System.currentTimeMillis());// 文件名String fileName = "src/test/java/images/"+dirTime+"/"+str+"-"+fileTime+".png";
// System.out.println("文件名:"+fileName);File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(srcFile, new File(fileName));}/*** 销毁driver,关闭浏览器*/public static void quit() {if (driver != null)driver.quit();}
}
3.2 注册功能测试
public class RegisterTest extends Utils {private static String url = "http://localhost:8080/pages/login.html";public RegisterTest() {super(url);}/*** 注册成功*/public void registerSuccess() {driver.findElement(By.cssSelector("#register-tab")).click();// 生成一个随机的UUIDUUID uuid = UUID.randomUUID();// 转换为字符串(最常用形式,包含连字符)String uuidStr = uuid.toString();String testName = "test" + uuidStr.substring(0, 10); // 随机用户名,每次都不同driver.findElement(By.cssSelector("#register-username")).sendKeys(testName);driver.findElement(By.cssSelector("#register-password")).sendKeys("1234");driver.findElement(By.cssSelector("#register-submit")).click();Alert alert = wait.until(ExpectedConditions.alertIsPresent());alert.accept();}/*** 注册失败 用户名已被注册*/public void registerFail() {driver.findElement(By.cssSelector("#register-tab")).click();driver.findElement(By.cssSelector("#register-username")).sendKeys("zhangsan");driver.findElement(By.cssSelector("#register-password")).sendKeys("1234");driver.findElement(By.cssSelector("#register-submit")).click();Alert alert = wait.until(ExpectedConditions.alertIsPresent());alert.accept();}
}
3.3 登录功能测试
public class LoginTest extends Utils {private static String url = "http://localhost:8080/pages/login.html";public LoginTest() {super(url);}/*** 成功登录*/public void loginSuccess() throws IOException {// 先清空框中的内容driver.findElement(By.cssSelector("#login-username")).clear();driver.findElement(By.cssSelector("#login-password")).clear();driver.findElement(By.cssSelector("#login-username")).sendKeys("zhangsan");// 账号输入框driver.findElement(By.cssSelector("#login-password")).sendKeys("1234");// 密码输入框driver.findElement(By.cssSelector("#login-submit")).click();// 提交按钮// 显示等待,等待弹窗出现wait.until(ExpectedConditions.alertIsPresent());// 处理弹出的窗口,等窗口出现后才能处理,否则会报错Alert alert = driver.switchTo().alert();alert.accept();// 跳转页面后检查新页面的元素是否存在来判断是否跳转成功driver.findElement(By.cssSelector("#sidebar > div.sidebar-content > div > span"));// 检查”音乐云“logo是否存在screenShot(Thread.currentThread().getStackTrace()[1].getMethodName());}/*** 登录失败*/public void loginFail() throws IOException {// 先清空框中的内容driver.findElement(By.cssSelector("#login-username")).clear();driver.findElement(By.cssSelector("#login-password")).clear();driver.findElement(By.cssSelector("#login-username")).sendKeys("zhangsan");// 账号输入框driver.findElement(By.cssSelector("#login-password")).sendKeys("12345");// 密码输入框driver.findElement(By.cssSelector("#login-submit")).click();// 提交按钮// 显示等待,等待弹窗出现wait.until(ExpectedConditions.alertIsPresent());// 处理弹出的窗口,等窗口出现后才能处理,否则会报错Alert alert = driver.switchTo().alert();alert.accept();screenShot(Thread.currentThread().getStackTrace()[1].getMethodName());}
}
3.4 上传音乐功能测试
public class UploadMusicTest extends Utils {private static String url ="http://localhost:8080/pages/upload.html";public UploadMusicTest() {super(url);}public void uploadMusic() {driver.findElement(By.cssSelector("#sidebar > div.sidebar-content > ul:nth-child(2) > li:nth-child(3) > a")).click();WebElement musicName = driver.findElement(By.cssSelector("#title"));WebElement singer = driver.findElement(By.cssSelector("#singer"));musicName.clear();singer.clear();musicName.sendKeys("自动化测试");singer.sendKeys("test");WebElement fileInput = driver.findElement(By.cssSelector("#music-file"));String musicPath = "D:/GoogleDonload/心墙 - 郭静.mp3";fileInput.sendKeys(musicPath);driver.findElement(By.cssSelector("#upload-form > div:nth-child(5) > button")).click();Alert alert = wait.until(ExpectedConditions.alertIsPresent());alert.accept();// 等待全部音乐页面加载完成(通过核心元素判断)wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("music-list") // 音乐列表容器,确保页面已渲染));}}
3.5 音乐收藏管理功能测试
public class LoveMusicTest extends Utils {private static String url = "http://localhost:8080/pages/index.html";public LoveMusicTest() {super(url);}/*** 收藏音乐*/public void addLoveMusic() {// 点击全部音乐列表driver.findElement(By.cssSelector("#sidebar > div.sidebar-content > ul:nth-child(2) > li:nth-child(1) > a")).click();// 点击音乐右侧的收藏按钮driver.findElement(By.cssSelector("#music-list > div:nth-child(1) > div.music-extra > div.music-actions > button.music-btn.like-btn")).click();// 显示等待,等待弹窗出现wait.until(ExpectedConditions.alertIsPresent());// 处理弹出的窗口,等窗口出现后才能处理,否则会报错Alert alert = driver.switchTo().alert();alert.accept();// 主页的音乐名称String indexMusicName = driver.findElement(By.cssSelector("#music-list > div:nth-child(1) > div.music-info > div.music-detail > div.music-title")).getText();// 跳转到我的喜欢页面driver.findElement(By.cssSelector("#sidebar > div.sidebar-content > ul:nth-child(2) > li:nth-child(2) > a")).click();// 我的喜欢页面的音乐名称String LoveMusicName = driver.findElement(By.cssSelector("#liked-music-list > div > div.music-info > div.music-detail > div.music-title")).getText();// 对比我的喜欢音乐名称和主页的音乐名称是否相同assert !indexMusicName.equals(LoveMusicName);}/*** 移除音乐*/public void cancelLoveMusic() {// 跳转到我的喜欢页面driver.findElement(By.cssSelector("#sidebar > div.sidebar-content > ul:nth-child(2) > li:nth-child(2) > a")).click();// 点击取消收藏按钮driver.findElement(By.cssSelector("#liked-music-list > div > div.music-extra > div.music-actions > button")).click();// 处理第一个弹窗(确定/取消)// 等待第一个弹窗出现Alert firstAlert = wait.until(ExpectedConditions.alertIsPresent());// 点击"确定"(如果需要点击取消则用 firstAlert.dismiss())firstAlert.accept();// 处理第二个弹窗(操作成功提示)// 等待第二个弹窗出现(第一个弹窗关闭后,第二个可能有延迟)Alert secondAlert = wait.until(ExpectedConditions.alertIsPresent());// 点击"确定"关闭成功提示(通常这类弹窗只有确定按钮)secondAlert.accept();}
}
3.6 播放音乐功能测试
public class PlayMusicTest extends Utils {private static String url = "http://localhost:8080/pages/index.html";public PlayMusicTest() {super(url);}public void playMusic() throws InterruptedException {// 先跳转到全部音乐页面driver.findElement(By.cssSelector("#sidebar > div.sidebar-content > ul:nth-child(2) > li:nth-child(1) > a")).click();// 点击音乐右侧的播放按钮driver.findElement(By.cssSelector("#music-list > div:nth-child(1) > div.music-extra > div.music-actions > button.music-btn.play-btn")).click();// 获取音乐名称String indexMusicName = driver.findElement(By.cssSelector("#music-list > div:nth-child(1) > div.music-info > div.music-detail > div.music-title")).getText();// 获取底部播放栏的音乐名称String bottomMusicName = driver.findElement(By.cssSelector("#now-playing-title")).getText();
// System.out.println("主页音乐:"+indexMusicName);
// System.out.println("播放栏音乐:"+bottomMusicName);assert !indexMusicName.equals(bottomMusicName);}
}
3.7 搜索音乐功能测试
public class SearchMusic extends Utils {private static String url = "http://localhost:8080/pages/index.html";public SearchMusic() {super(url);}public void searchMusic() {// 跳转到主页driver.findElement(By.cssSelector("#sidebar > div.sidebar-content > ul:nth-child(2) > li:nth-child(1) > a")).click();// 搜索关键字driver.findElement(By.cssSelector("#search-input")).sendKeys("心");String keyWord = driver.findElement(By.cssSelector("#search-input")).getAttribute("value");// 第一个音乐的音乐名String searchMusic = driver.findElement(By.cssSelector("#music-list > div > div.music-info > div.music-detail > div.music-title")).getText();// 判断搜索框中输入的关键字是否匹配搜索结果assert !keyWord.contains(searchMusic);}
}
3.8 删除音乐功能测试
public class DeleteMusicTest extends Utils {private static String url = "http://localhost:8080/pages/index.html";public DeleteMusicTest() {super(url);}public void deleteMusic() {// 跳转到主页driver.findElement(By.cssSelector("#sidebar > div.sidebar-content > ul:nth-child(2) > li:nth-child(1) > a")).click();// 删除按钮driver.findElement(By.cssSelector("#music-list > div > div.music-extra > div.music-actions > button.music-btn.delete-btn")).click();// 处理第一个弹窗(确定/取消)// 等待第一个弹窗出现Alert firstAlert = wait.until(ExpectedConditions.alertIsPresent());// 点击"确定"(如果需要点击取消则用 firstAlert.dismiss())firstAlert.accept();// 处理第二个弹窗(操作成功提示)// 等待第二个弹窗出现(第一个弹窗关闭后,第二个可能有延迟)Alert secondAlert = wait.until(ExpectedConditions.alertIsPresent());// 点击"确定"关闭成功提示(通常这类弹窗只有确定按钮)secondAlert.accept();}
}
自动化代码运行起来后功能均符合预期