【博文汇项目全维度测试报告:功能与自动化双轨验证】

](https://img-home.csdnimg.cn/images/20220524100510.png#pic_center)
🌈个人主页: Aileen_0v0
🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法
💫个人格言:“没有罗马,那就自己创造罗马~”

文章目录

  • 项目背景:
    • 项目背景与意义:
    • 项目概述
      • 已实现的主要功能包括:
      • 当前系统存在的不足:
    • 项目的系统功能说明
      • 1. 登录功能
      • 2. 博客列表页
      • 3. 博客详情页
      • 4. 博客编辑页
    • 测试目标:
    • 测试项目相关信息:
  • 测试安排:
  • 测试分类:
    • (1)功能测试
    • (2)自动化测试
    • ①编写Web测试用例:
    • ②创建空项目
      • (1)配置准备:添加需要的pom.xml依赖
      • (2)创建驱动对象driver
      • (3)测试用例的划分
    • 自动化测试工具准备:
    • 测试用例tests的编写:
      • ①登录页面:
        • 检查页面的正常加载:
        • 检查成功登录:
        • 检查登录失败:
      • ②列表页面测试:
      • ③编辑页面:
      • ④:详情页面:
    • (3)性能测试:
      • 模拟并发访问登录页面:
  • 总结测试 tips:

项目名称博文汇版本号/
发布类型分级发布测试负责人Aileen
测试完成日期7/9联系方式

项目背景:

项目背景与意义:

  • 随着互联网的发展,博客平台成为技术交流、知识分享的重要载体。CSDN作为国内知名的技术社区,为广大开发者提供了丰富的学习与交流资源。作为一名CSDN博主,我在日常写作和交流中深刻体会到一个高效、便捷、安全的博客系统对于个人成长和技术传播的重要性。因此,我以CSDN为参考,设计并开发了**“博文汇”**项目,旨在打造一个简洁易用、功能完善的个人博客平台,便于回顾所学的知识。
  • 本项目的创建不仅是对主流博客平台功能的实践和复现,更是对Web开发全流程的系统学习和能力提升。通过项目开发,我深入掌握了Java、Spring Boot、前端技术、JWT 令牌加密等关键技能,并在实际应用中强化了对安全性、用户体验、系统可维护性的理解,实现将自己所学的知识融会贯通到项目中,加深自己对技术的理解。
  • 若有不足或改进之处,也希望大家指出☺️~

项目概述

本项目实现了一个基于前后端分离架构的个人博客系统,采用数据库存储用户与博客数据,并部署在云服务器上。系统前端主要由四个页面组成:登录页、博客列表页、博客详情页和博客编辑页,整体模拟实现了一个简洁的个人博客平台。

已实现的主要功能包括:

  • 用户登录与注销
  • 博客的发布与删除
  • 博客列表与详情查看
  • 强制登录验证(未登录状态下无法访问其他页面)

当前系统存在的不足:

  • 未实现用户注册功能,用户信息需提前写入数据库
  • 用户头像为静态图片,无法自定义设置
  • 用户文章数与分类数未在后端动态统计,前端为静态展示

项目的系统功能说明

1. 登录功能

  • 用户需输入已存在于数据库中的用户名和密码进行登录
  • 登录成功后跳转至博客列表页
  • 未登录状态下点击“主页”或“写博客”按钮,将强制跳转至登录页

2. 博客列表页

  • 展示博客的简要信息,包括标题、发布时间、内容概要
  • 左侧显示当前登录用户的基本信息(如用户名、文章数、分类数等)
  • 右上角提供三个功能按钮:
    • 主页:返回博客列表页
    • 写博客:跳转至博客编辑页
    • 注销:退出当前用户,返回登录页

3. 博客详情页

  • 点击列表页中的“查看全文”按钮进入详情页
  • 展示博客的完整内容,包括标题、发布时间、作者及正文
  • 右上角提供四个功能按钮:
    • 主页:返回博客列表页
    • 写博客:跳转至博客编辑页
    • 删除:删除当前博客,删除后返回列表页
    • 注销:退出当前用户,返回登录页

4. 博客编辑页

  • 登录状态下点击“写博客”按钮进入编辑页
  • 用户可输入博客标题与正文内容
  • 点击“发布文章”按钮后,博客将被保存并发布,随后跳转至博客列表页

测试目标:

  • 目标:主页面测试率达到 90%

测试项目相关信息:

  • 项目链接地址:http://47.94.167.83:8080/blog_login.html
  • 项目代码:https://gitee.com/gu-ling-c-language/spring_-blog
  • 接口:登录,主页,编辑,详情页

测试安排:

模块子模块前端开发提测时间测试工时排期进度备注
登陆登陆功能AileenAileen6.30Aileen0.5d6.31测试完成
主页博主信息、博客列表页、导航栏AileenAileen6.30Aileen0.5d6.31测试完成
写博客博客编辑与发布AileenAileen6.31Aileen1d7.3测试完成
博客详情页博客详情页AileenAileen6.31Aileen0.5d7.3测试完成

测试分类:

(1)功能测试

我的博文项目测试

  • 功能测试结果:测试用例 100%通过

(2)自动化测试

①编写Web测试用例:

②创建空项目

(1)配置准备:添加需要的pom.xml依赖

<dependency><groupId>io.github.bonigarcia</groupId><artifactId>webdrivermanager</artifactId><version>5.8.0</version><scope>test</scope>
</dependency><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>

(2)创建驱动对象driver

  • 为了方便测试所有的页面,我们创建一个driver对象供所有的测试用例使用

(3)测试用例的划分

  • 按照页面分类,每个页面就是一个Java文件,页面下所有的用例统一管理

在这里插入图片描述

自动化测试工具准备:

package common;import io.github.bonigarcia.wdm.WebDriverManager;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;public class Utils {//创建WebDriver对象public static WebDriver driver;public static WebDriver createDriver(){//先判断驱动是否为nullif(driver == null) {//如果为null,则创建一个新的WebDriver实例WebDriverManager.chromedriver().setup();ChromeOptions options = new ChromeOptions();// 允许访问所有网站options.addArguments("--allow-remote-origins=*");//创建ChromeDriver实例driver = new ChromeDriver(options);//等待->隐式等待driver.manage().timeouts().implicitlyWait(java.time.Duration.ofSeconds(2));}return driver;}public Utils(String url){//调用 driver 对象driver = createDriver();//访问urldriver.get(url);}//测试截图public void getScreenShot(String str) throws IOException {//截图放置的位置:  ./src/test/image///                              /2025-7-20///                                        /test01-150001.png//                                        /test02-150030.png//                              /2025-7-21///                                        /test01-150001.png//                                        /test02-150030.png//格式设置SimpleDateFormat sim1 = new SimpleDateFormat("yyyy-MM-dd");SimpleDateFormat sim2 = new SimpleDateFormat("HHmmssSS");//SS将文件名精确到毫秒级别避免截图同名String dirTime = sim1.format(System.currentTimeMillis());String fileTime = sim2.format(System.currentTimeMillis());// ./src/test/image/2025-7-20/test01-150001.pngString filename = "./src/test/image/"+ dirTime +"/"+str +"-"+ fileTime+".png";//打印一下生成的filename名称System.out.println("filename: "+ filename);//屏幕截图File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);//srcFile放到指定位置FileUtils.copyFile(srcFile , new File(filename));}}
  • 后面测试用例就可以通过继承这个工具创建测试对象,访问URL

测试用例tests的编写:

①登录页面:

  • 登录页面的基本功能测试:只有账号和密码匹配才能正常登录,其他情况都登录失败。

检查页面的正常加载:

package tests;import common.Utils;
import org.openqa.selenium.By;public class LoginPage extends Utils {public static String url = "http://47.94.167.83:8080/blog_login.html";/*** 构造函数,调用父类Utils的构造函数* 访问登录页面*/public LoginPage() {super(url);}/***检查页面是否能正确加载* @throws InterruptedException*/public void loginPageRight() throws InterruptedException {//查看页面元素是否存在来检查页面是否能成功加载//这里选择主页按钮元素driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)"));//登录输入框driver.findElement(By.cssSelector("body > div.container-login > div"));Thread.sleep(3000);driver.quit();}
}

检查成功登录:
    /*** 检查登录功能 - 成功登录*/public void LoginSuc(){//找到登录页面中的用户输入框,输入账号和密码并点击登录按钮driver.findElement(By.cssSelector("#username")).sendKeys("Aileen");driver.findElement(By.cssSelector("#password")).sendKeys("123456");driver.findElement(By.cssSelector("#submit")).click();//检查登录之后是否登陆成功//检查页面是否跳转到博客列表页//根据博客列表页的元素来判断driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a"));//检查页面标题是否正确--这里需要配置断言String exceptTitle = driver.getTitle();assert exceptTitle.equals("博客列表页") : "登录失败,页面标题不正确!";driver.quit();}


检查登录失败:

  • 当我们登录成功之后通过 navigate.back() 回到登录页之后,需要先将账号密码清空才能进行登录失败的测试,否则会叠加到原来成功登录输入的内容之后:
    /*** 检查登录功能 - 登录失败*///检查登录失败,在测完登录成功之后需要先回到登录页面才能进行登录失败的检查↑public void LoginFail() throws InterruptedException {//先清空之前成功登录在输入框中输入的内容://清空方式有两种://1.使用clear()方法driver.findElement(By.cssSelector("#username")).clear();driver.findElement(By.cssSelector("#password")).clear();//2.使用refresh()方法刷新页面//driver.navigate().refresh();//输入错误的账号和密码driver.findElement(By.cssSelector("#username")).sendKeys("Aileen111");//账号错误driver.findElement(By.cssSelector("#password")).sendKeys("123456");driver.findElement(By.cssSelector("#submit")).click();//等待alert弹窗出现Thread.sleep(2000); // 等待2秒钟,确保alert弹窗出现//获取失败的弹窗内容,将它和预期的错误信息进行比较String alertText = driver.switchTo().alert().getText();String expectedAlertText = "用户不存在";assert alertText.equals(expectedAlertText);//接受弹窗driver.switchTo().alert().accept();driver.quit();}

②列表页面测试:

  • 测试列表页面又分为两种情况:登录成功和登录失败(未登录状态)去访问博客列表页:
package tests;import common.Utils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;import java.io.IOException;public class ListPage extends Utils {public static String url = "http://127.0.0.1:8080/blog_list.html";public ListPage() {super(url);}/*** 根据登录状态访问列表页* 这里需要先登录成功* 测试看列表页是否有只属于列表页的元素* 有则说明访问成功*/public void ListByLogin(){//查看是否能加载列表页String exceptTitle = driver.getTitle();assert exceptTitle.equals("博客列表页") : "列表页加载失败,页面标题不正确!";//查看页面元素是否存在来检查页面是否能成功加载//这里选择查看全文按钮WebElement ele = driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a"));//通过断言检查是否有这个按钮assert ele.isDisplayed() : "列表页加载失败,页面元素不存在!";//点击查看全文按钮ele.click();}
}

  • 未登录状态查看博客列表处理弹窗出现问题
    • 我通过给每个测试用例屏幕截图查找问题

  • 通过截图我们可以看到:我们执行到我们本来预期是:以未登录状态访问列表页的,但是当它执行并跳转到未登录访问博客列表的测试方法前,它通过 driver 访问博客列表时,还保存着之前的登录状态,所以未登录的方法的警告框实际上并未出现。

③编辑页面:

package tests;import common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;/*** 特殊测试:编辑页面* 由于markdown是第三方库,无法直接测试博客的发布功能,但是默认情况下页面编辑已有默认内容,* 但是我们可以测试编辑页面的标题,因为标题是我自己实现的HTML元素*/
public class EditPage extends Utils {public static String url = "http://127.0.0.1:8080/blog_edit.html";public EditPage() {super(url);}/*** 发布博客测试* 无法输入博客内容怎么解决----->两种方式*/public void EditSuc() throws InterruptedException {//①方式1:博客本身就有默认内容,无需手动实现WebElement ele = driver.findElement(By.cssSelector("#title"));Thread.sleep(6000); //等待2秒钟,查看输入的效果ele.sendKeys("乌萨奇的博客");Thread.sleep(2000); //等待2秒钟,查看输入的效果driver.findElement(By.cssSelector("#submit")).click();//------------//点击弹窗的确认按钮->跳转到博客列表页Thread.sleep(1000);driver.switchTo().alert().accept();//②方式2:通过鼠标操作来实现---这里就不实现了,有点麻烦...//检查博客发布之后是否成功在列表页展示出WebElement exceptArticleTitle = driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > div.title"));String exceptTitle = exceptArticleTitle.getText();assert exceptTitle.equals("乌萨奇的博客") : "编辑页面发布博客失败,标题不正确!";}
}

④:详情页面:

package tests;import common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;public class DetailPage extends Utils {public static String url = "http://127.0.0.1:8080/blog_detail.html?blogId=14";public DetailPage() {super(url);}/*** 检查详情页是否能正确加载* 通过查找博客标题元素来判断* @throws InterruptedException*/public void DetailByLogin() throws InterruptedException {//查看页面元素是否存在来检查页面是否能成功加载//这里选择编辑按钮//用户点击编辑,然后修改标题,点击发布,跳转到博客列表页String exceptDetailTitle = driver.getTitle();assert exceptDetailTitle.equals("博客详情页") : "详情页加载失败,页面标题不正确!";Thread.sleep(3000);//点击编辑按钮driver.findElement(By.cssSelector("body > div.container > div.right > div > div.operating > button:nth-child(1)")).click();Thread.sleep(3000);//修改标题WebElement ele = driver.findElement(By.cssSelector("#title"));Thread.sleep(2000); //等待2秒钟,查看输入的效果ele.clear();Thread.sleep(2000); //等待2秒钟,查看输入的效果ele.sendKeys("永不言弃的Aileen");Thread.sleep(2000); //等待2秒钟,查看输入的效果driver.findElement(By.cssSelector("#submit")).click();//将内容发表->点击发布成功弹窗的按钮Thread.sleep(2000);driver.switchTo().alert().accept(); //点击弹窗的确认按钮->跳转到博客列表页Thread.sleep(2000);// 跳转到博客列表页//检查是否跳转到博客列表页String exceptTitle = driver.getTitle();assert exceptTitle.equals("博客列表页") : "详情页修改失败,无法跳转到博客列表页!";//注销按钮测试//点击注销按钮driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();Thread.sleep(3000);//检查是否能跳转到登录页面String exceptLoginTitle = driver.getTitle();assert exceptLoginTitle.equals("博客登陆页") : "注销失败,无法跳转到登录页面!";}
}

(3)性能测试:

模拟并发访问登录页面:

  • 2s 内 10 个虚拟用户不断发送请求,总共发送了 4445 次请求

  • 我们可以看到响应时间和吞吐量成反比:
    • 响应时间长,吞吐量小或相对稳定,可能系统达到了性能瓶颈。
    • 响应时间短,吞吐量大,性能越好

  • 根据线程响应时间图,我们可以看到,存在一个异常:有一个线程一直没有退出,下面我们结合聚合报告进一步分析:

- 我们可以考到列表页的响应时间是最长的,说明可能是列表页存在问题,我觉得是因为我们每次列表页返回的都是所有的数据,响应量大,数据较多,导致时间较长
- **解决方案:将返回的响应量分解,给博客列表页添加分页,限制每页返回的最大博客条数,这样就可以有效解决响应时间过长的问题。**

  • 通过 JMeter 生成测试报告,可看到总共 959 个请求,没有错误,错误率为 0,说明高并发场景下,系统能够正常处理业务。
  • 但是博客列表页的响应时间太长了,应该是一次请求的响应资源太多了,我们可以将一次请求的请求量分多次请求来减少响应时间,通过给列表页添加翻页功能,限制每页展示的博客条数

总结测试 tips:

  • 先测试部分接口功能是否能正常实现,再进行整体测试,要注意各个接口之间的关联关系。

](https://img-home.csdnimg.cn/images/20220524100510.png#pic_center)
](https://img-home.csdnimg.cn/images/20220524100510.png#pic_center)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java陷阱之assert关键字详解

Assert.isTrue()方法用于断言条件是否为真&#xff0c;如果条件不满足&#xff08;即为false&#xff09;&#xff0c;则会抛出IllegalArgumentException&#xff0c;并附带预设的错误信息。在示例中&#xff0c;当1.23不小于2.23时&#xff0c;方法抛出了异常&#xff0c;显示…

mysql 散记:innodb引擎和memory引擎对比 sql语句少用函数 事务与长事务

文章目录innodb引擎和memory引擎对比对比sql 语句&#xff1a;尽可能不使用函数条件隐式转换隐式类型转换隐式字符编码转换补充问题事务与长事务ACIDread viewMVCC 一致性视图当前读view 虚拟表长事务的影响与排查影响排查方法预防innodb引擎和memory引擎对比 innodb引擎是索引…

APK安装器(安卓端)一键解除VX限制!轻松安装各种手机应用

VX为了防止恶意软件通过平台传播&#xff0c;保障用户设备安全&#xff0c;会把通过VX发送的 APK 文件自动改成 “apk.1” 格式&#xff0c;这样就能减少恶意软件传播的风险。我平时推荐安卓软件的时候&#xff0c;有朋友反馈说&#xff0c;文件发到VX里就变成 “apk.1” 了&am…

Debian:从GNOME切换到Xfce

最近为20年前的T43重新安装了Debian系统&#xff0c;但使用的gnome桌面太卡了。于是换成轻量级的Xfce系统。 1.安装Xfce sudo apt update sudo apt install xfce4 xfce4-goodies命令中xfce4 是Xfce桌面环境的核心组件&#xff0c;xfce4-goodies 是一些额外的工具和插件&#xf…

徐州服务器租用:BGP线路的特点有哪些?

BGP的中文全称为边界网关协议&#xff0c;是指一种运行在传输控制协议上的自治系统路由协议&#xff0c;主要的功能就是可以实时控制路由的传播&#xff0c;同时能够帮助用户选择更合适的路由线路&#xff0c;保证网络能够稳定的运行&#xff0c;不会轻易出现网络卡顿或故障的状…

Java使用OSHI获取服务器信息

OSHI可以获取系统信息&#xff08;CPU、内存、磁盘、网络等&#xff09;&#xff0c;纯Java实现&#xff08;通过JNA访问本地API&#xff0c;无需安装本地库&#xff09;&#xff0c;跨平台支持。引入依赖<dependency><groupId>com.github.oshi</groupId><…

企业数字化资产管理安全、成本、协作困局难解?

在数字化浪潮席卷全球的今天&#xff0c;3D技术已成为驱动影视动画、工业设计、建筑可视化等领域创新的核心动力。然而&#xff0c;随着3D资产规模呈指数级增长&#xff0c;企业正面临前所未有的管理挑战&#xff1a;海量模型存储混乱、版本迭代难以追溯、团队协作效率低下、知…

力扣面试150题--组合总和

Day 72 题目描述&#xff08;终于理顺回溯了&#xff09;思路 这里还是基于模板来说明代码思路void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择 : 本层集合中的元素) {处理节点;backtracking(路径, 选择列表); // 递归撤销处理; // 回溯} }对于主要函数的…

多客户端-服务器(select,poll)

多客户端-服务器结构总结一、普通CS架构的局限性核心问题&#xff1a;单线程中accept&#xff08;阻塞等待连接&#xff09;与read&#xff08;阻塞读取数据&#xff09;函数互相干扰&#xff0c;无法同时处理多客户端。本质原因&#xff1a;阻塞型函数需独立执行&#xff0c;若…

如何使用postman做接口测试?

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 常用的接口测试工具主要有以下几种&#xff1a;Postman: 简单方便的接口调试工具&#xff0c;便于分享和协作。具有接口调试&#xff0c;接口集管理&#xff0c…

新型网络架构设计助力智慧医疗降本增效

随着智慧医疗的快速发展,越来越多的医院开始布局“互联网+医疗”服务,通过数字化手段提升医疗服务效率。然而,如何构建一个既稳定可靠又具备灵活扩展能力的医疗网络,成为医院数字化转型中的关键问题。本文以某智慧医疗项目为例,探讨传统网络与SD-WAN结合的最佳实践。 背景…

一文读懂现代卷积神经网络—使用块的网络(VGG)

目录 什么是使用块的网络&#xff08;VGG&#xff09;&#xff1f; 一、VGG 的核心思想&#xff1a;用块&#xff08;Block&#xff09;构建网络 二、VGG 的网络结构 三、VGG 的优势 1. 结构简洁统一 2. 强大的特征表达能力 3. 小卷积核的计算效率 4. 良好的迁移学习性…

Linux的相关学习

linux 1.文件权限怎么修改 chmod [权限模式] [文件或目录]1、**数字模式&#xff08;八进制&#xff09;**&#xff1a; chmod 755 myfile.sh # 所有者&#xff1a;rwx (7)&#xff0c;组&#xff1a;r-x (5)&#xff0c;其他用户&#xff1a;r-x (5) 7 rwx&#xff08;读写…

Kotlin集合接口

Kotlin 集合概述 Kotlin 集合提供了对数据进行各种操作的便捷方式。它们实现了接口&#xff0c;因此可以操作不同类型的数据。例如&#xff0c;你可以编写一个函数&#xff0c;同时打印 Set 和 List 的所有元素。我们来看看这是如何实现的。Iterable 接口 我们已经知道&#xf…

Git 常用操作与注意事项全攻略

1. 基本配置 git config --global user.name "你的名字" git config --global user.email "你的邮箱" git config --list # 查看当前配置建议全局配置用户名和邮箱&#xff0c;否则提交记录可能不规范2.仓库操作 初始化本地仓库 git init只在新建项目时使…

STM32-第五节-TIM定时器-1(定时器中断)

一、定时器原理&#xff1a;1.介绍&#xff1a;对指定输入时钟进行计数&#xff0c;并在计数值达到设定值时触发中断。分类&#xff1a;基本定时器&#xff0c;通用定时器&#xff0c;高级定时器频率&#xff1a;72MHZ2.框图&#xff1a; &#xff08;1&#xff09;基本定时器&…

【图像处理基石】什么是色盲仿真技术?

色盲仿真概述 色盲仿真是一种将正常色彩图像转换为色盲患者感知效果的技术。人类常见的色盲类型包括&#xff1a; 红色盲&#xff08;Protanopia&#xff09;&#xff1a;无法感知红色绿色盲&#xff08;Deuteranopia&#xff09;&#xff1a;无法感知绿色蓝黄色盲&#xff08;…

九、官方人格提示词汇总(中-3)

“参谋代写计划”功能输出欣赏&#xff0c;规则&#xff1a; 本部分统一使用 Gemini 2.5 Pro API。该 API 下的输出质量基本达到我的要求&#xff0c;已具备实用价值。严格等级均为“权衡有度&#xff08;L3&#xff09;”&#xff0c;创造力等级均为“趋势捕手&#xff08;L3…

华为MateBook D 16 SE版 2024款 12代酷睿版i5集显(MCLF-XX,MCLF-16)原厂OEM预装Win11系统

适用型号&#xff1a;MCLF-XX,MCLF-16链接&#xff1a;https://pan.baidu.com/s/1OkvUqZMdCSF98YtQfWAYXw?pwdq2gh 提取码&#xff1a;q2gh 华为开箱状态出厂Windows11系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、系统属性专属LOGO标志、Office办公软件、华为电脑…

Python自动化:每日销售数据可视化

这是手动执行sql分组查出的Linda奶茶店每日的销售数据,那么能否图形化展示方便对比近一个月每日的销售趋势呢。如果是做在网站里,前端可以集成echart或highchart生成柱状图或线状图。如果需要每天定时推送这些数据到邮箱或其他消息通知渠道,第一步肯定是需要先生成图片到服务…