目录
- 一、项目背景
- BI介绍
- 问题分析
- 项目背景
- 二、项目功能
- 三、功能测试
- 1、登录测试
- 测试用例
- 测试结果
- 2、注册测试
- 测试用例
- 测试结果
- 出现的bug
- 3、上传文件测试
- 测试用例
- 测试结果
- 4、AI生成图表测试
- 测试用例
- 测试结果
- 5、分析数据页面测试(异步)
- 测试用例
- 测试结果
- 6、图表列表页面测试
- 测试用例
- 测试结果
- 四、自动化测试
- 整体架构模式
- 登录注册页面
- AI生产图表页面测试
- 图表列表页面测试
- 自动化测试遇到的问题
- 元素定位不到:
- 编写自动化测试代码看不到效果
- StaleElementReferenceException
项目地址:
项目代码:Gitee
一、项目背景
BI介绍
BI: Business Intelligence
即商业智能:数据可视化、报表可视化系统
主流BI平台:
FineBI、PowerBI
https://chartcube.alipay.com/
问题分析
- 需要人工上传数据
- 需要人工拖选分析要用到的数据行和列(数据分析师)
- 需要人工选择图表类型(数据分析师)
- 生成图表并保持配置
项目背景
区别于传统的 BI,用户(数据分析者)只需要导入最最最原始的数据集,输入想要进行分析的目标(比如帮我分析一下网站的增长趋势),就能利用 AI 自动生成一个符合要求的图表以及结论,实现数据分析的降本增效
二、项目功能
- 用户的登录和注册 --用户输入账号密码登录注册
- 智能分析:
– 用户上传excel文件,分析目标(图表类型)
– 对接AI能力 – 对接讯飞星火大模型分析数据
–自动生成图表和分析结论 - 图表管理功能 – 点击图表管理,用户可以看到自己需要生成的数据分析结果和数据分析状态
- 异步化图表生成 – 对图表生成的优化
三、功能测试
软件环境:win11 Google Chrome 131.0.6778.205 mysql 5.7
测试用例总览
1、登录测试
测试用例
测试结果
-
页面显示
-
正常登录 (显示登录成功)
-
异常登录
2、注册测试
测试用例
测试结果
点击注册:
显示该页面不存在
404 一般是路径问题
后端注册接口为:/api/user/register
后端注册接口没问题
出现的bug
bug:openapi自动生成了 前后端交互部分,但是前端没有是实现这个注册页面
3、上传文件测试
测试用例
测试结果
- 正常上传
- 异常上传
yml文件也可以上传成功,这里前端未校验文件格式
点击提交(后端校验文件格式),显示分析失败
4、AI生成图表测试
测试用例
测试结果
分析结论和可视化图表展示正常
鼠标光标定位显示正常
5、分析数据页面测试(异步)
测试用例
测试结果
6、图表列表页面测试
测试用例
测试结果
-
无数据时显示
-
历史图表显示情况
-
在测试时输入新的数据出现bug
异常情况:
解决:观察数据库,AI生成的echarts的json配置不正确,导致前端界面显示正常,预设的 promote 需要重新调整
调整后:
String predefinedInformation = “你是一个数据分析师和前端开发专家,接下来我会按照以下固定格式给你提供内容:\n” +
“分析需求:\n” +
“{数据分析的需求或者目标}\n” +
“原始数据:\n” +
“{csv格式的原始数据,用,作为分隔符}\n” +
“请根据这两部分内容,严格按照以下指定格式生成内容(此外不要输出任何多余的开头、结尾、注释)同时不要使用这个符号 ‘】’\n” +
“‘【【【【【’\n” +
“{前端 Echarts V5 的 option 配置对象 JSON 代码, 不要生成任何多余的内容,比如注释和代码块标记}\n” +
“‘【【【【【’\n” +
“{明确的数据分析结论、越详细越好,不要生成多余的注释} \n”
+ “下面是一个具体的例子的模板:”
+ “‘【【【【【’\n”
+ “JSON格式代码”
+ “‘【【【【【’\n” +
“结论:”;
将后端错误数据逻辑删除,显示正常
- 搜索功能
存在情况
不存在情况
四、自动化测试
整体架构模式
登录注册页面
测试点
自动化代码
package tests;
import common.Utils;
import org.openqa.selenium.By;
import java.io.IOException;
public class LoginPage extends Utils {
public static String url = "http://localhost:8000/user/login";
public LoginPage() {
super(url);
}
// 检查登录功能 -- 登录成功
public void loginSuc() throws InterruptedException, IOException {
// String title = driver.getTitle();
// // 断言
// assert title.equals("");
// 清空输入框里的数据
driver.findElement(By.cssSelector("#root > div > div > div > div.ant-pro-form-login-top.css-dev-only-do-not-override-1wwf28x.css-dev-only-do-not-override-1wwf28x > div.ant-pro-form-login-desc.css-dev-only-do-not-override-1wwf28x > a"));
// 先清除输入框
driver.findElement(By.cssSelector("#userAccount")).clear();
driver.findElement(By.cssSelector("#userPassword")).clear();
Thread.sleep(2000);
driver.navigate().refresh();
// 账号密码正确
driver.findElement(By.cssSelector("#userAccount")).sendKeys("admin");
driver.findElement(By.cssSelector("#userPassword")).sendKeys("admin123");
driver.findElement(By.cssSelector("#root > div > div > div > div.ant-pro-form-login-main.css-dev-only-do-not-override-1wwf28x > form > button")).click();
// driver.navigate().back();
Thread.sleep(2000);
}
// 检查登录功能 -- 登录失败
public void loginFail() throws IOException, InterruptedException {
// 检查元素
driver.findElement(By.cssSelector("#root > div > div > div > div.ant-pro-form-login-top.css-dev-only-do-not-override-1wwf28x.css-dev-only-do-not-override-1wwf28x > div.ant-pro-form-login-desc.css-dev-only-do-not-override-1wwf28x > a"));
// 先清除输入框
driver.findElement(By.cssSelector("#userAccount")).clear();
driver.findElement(By.cssSelector("#userPassword")).clear();
// 密码错误情况
driver.findElement(By.cssSelector("#userAccount")).sendKeys("admwqwin");
driver.findElement(By.cssSelector("#userPassword")).sendKeys("admin123");
driver.findElement(By.cssSelector("#root > div > div > div > div.ant-pro-form-login-main.css-dev-only-do-not-override-1wwf28x > form > button")).click();
// 检查是否登录成功
Utils.getScreenshot("loginFail");
}
}
登成功失败页面
AI生产图表页面测试
测试点:
上传文件代码
// 定位上传文件按钮
WebElement fileInput = driver.findElement(By.cssSelector("input[type='file']"));
String filePath = "D:\\dev-BI\\bi-backend\\backend\\bi-backend\\src\\main\\resources\\测试数据.xlsx";
fileInput.sendKeys(filePath);
自动化代码
package tests;
import common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class BiCreatePage extends Utils {
public static String url = "http://localhost:8000/add_chart";
public BiCreatePage() {
super(url);
}
public void biCreate() throws InterruptedException, IOException {
// 隐式等待
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
// 检查元素
driver.findElement(By.cssSelector("#root > div > div.ant-layout.css-dev-only-do-not-override-1wwf28x > div > main > div.add-chart > div > div:nth-child(2) > div:nth-child(3) > div.ant-card-body > div:nth-child(1)"));
System.out.println("succeed!!!");
driver.findElement(By.cssSelector("#addChart_goal")).sendKeys("分析一下专业情况");
driver.findElement(By.cssSelector("#addChart_name")).sendKeys("专业分析图");
driver.findElement(By.cssSelector("#addChart > div:nth-child(3) > div > div.ant-col.ant-col-16.ant-form-item-control.css-dev-only-do-not-override-1wwf28x > div > div > div > div > span > span.ant-select-selection-search"));
// 定位图表类型下拉框
WebElement chartTypeDropdown = driver.findElement(By.cssSelector(".ant-select"));
chartTypeDropdown.click();
// 定位折线图选项并点击
WebElement lineChartOption = driver.findElement(By.cssSelector(".ant-select"));
lineChartOption.click();
// 定位上传文件按钮
WebElement fileInput = driver.findElement(By.cssSelector("input[type='file']"));
String filePath = "D:\\dev-BI\\bi-backend\\backend\\bi-backend\\src\\main\\resources\\测试数据.xlsx";
fileInput.sendKeys(filePath);
System.out.println("---------------------wfe----------------");
WebElement submitButton = driver.findElement(By.cssSelector(".ant-btn-primary"));
submitButton.click();
}
}
AI生成图表自动化测试
图表列表页面测试
图表管理自动化测试
自动化测试遇到的问题
元素定位不到:
- js渲染需要时间,自动化已经开始下一步了,通过添加等待的方式
- ant design pro 框架有特殊的cssSelector 比如 .ant-btn-primary、.ant-select,通过这种方式定位元素。
- 要定位的元素为动态元素,每次打开对应的元素名不一样
编写自动化测试代码看不到效果
- 通过添加等待,来观察效果
StaleElementReferenceException
- 页面刷新或导航后,原来的 WebElement 对象变得无效。
- 元素所在的 iframe 或者 shadow DOM 发生了变化。
- 动态加载的内容导致元素被重新渲染。
- StaleElementReferenceException 可能是由于页面刷新或元素被重新渲染后,之前的 WebElement 对象变得无效。