软件测试学习笔记丨Pytest+Allure测试计算器

本文转自测试人社区,原文链接:https://ceshiren.com/t/topic/31954

项目要求

3.1 项目简介

计算器是近代人发明的可以进行数字运算的机器。 计算器通过对加法、减法、乘法、除法等功能的运算,将正确的结果展示在屏幕上。 可帮助人们更方便的实现数字运算。一般情况下计算器除显示计算结果外,还常有溢出指示、错误指示等功能。

3.1.1 知识点

  • 测试流程与需求分析
  • bug 提交与管理
  • Pytest 测试框架基本用法
  • 参数化
  • 异常处理
  • 标签、跳过用例
  • 结合 Allure 生成测试报告与项目总结
  • 数据驱动
  • pytest fixture 实现测试装置及参数化
  • pytest conftest.py 的用法
  • pytest 文件配置 pytest.ini
  • 使用第三方插件控制用例的执行顺序,分布式并发执行
  • 使用分层思想,实现框架的合理构建
  • 了解内置插件 hook 体系,实现插件开发

3.1.2 受众

  • 资深测试工程师

3.1.3 作业内容

  1. 完整的测试流程,包含需求分析、测试计划设计、测试用例编写、测试执行、bug 的提交与管理。
  2. 使用思维导图完成需求分分析;提供完整测试计划模板,完成测试计划设计;应用多种测试用例设计方法,包括:等价类、边界值、错误推测法等。
  3. 测试执行过程中应用多种测试方法完成计算器的加法、除法运算。
  4. 结合项目管理工具完成 bug 的提交与管理,进行测试报告编写与项目总结。
  5. 编写自动化测试用例,结合 Allure 与截图技术等自动生成带截图与操作步骤的测试报告。
  6. 使用参数化减少代码量,提高代码的可维护性。
  7. 使用 mark 标签为测试用例分类
  8. 设置跳过、预期失败用例
  9. 对异常用例进行处理
  10. 掌握 Pytest 常用的装饰器,例如:添加标签、参数化、Fixture 等。
  11. 掌握 Pytest 自动化测试框架多种复杂配置,比如 pytest.ini 配置、conftest.py 配置等。
  12. 合理使用第三方插件,控制测试用例的执行顺序、分布式并发执行等场景。
  13. 掌握分层思想实现用例的分层,实现测试装置,测试数据,测试日志,测试报告等合理的框架构建。
  14. 开发一个插件,实现命令行传递参数

3.1.4 被测源码

class Calculator:def add(self, a, b):if a > 99 or a < -99 or b > 99 or b < -99:print("请输入范围为【-99, 99】的整数或浮点数")return "参数大小超出范围"return a + bdef div(self, a, b):if a > 99 or a < -99 or b > 99 or b < -99:print("请输入范围为【-99, 99】的整数或浮点数")return "参数大小超出范围"return a / b

3.2 实现过程

3.2.1 代码提交

3.2.2 需求分析

3.2.3 测试计划(简版)

3.2.4 测试用例设计

3.2.5 Pytest自动化测试设计

  • utils.py
from pandas.tests.io.excel.test_openpyxl import openpyxlclass Utils:@classmethoddef get_excel_data(cls, excel_path, sheetname):"""读取 excel文件中指定 sheet 页的数据:param excel_path: excel文件的路径:param sheetname: sheet页的名称:return: 返回读取的数据"""# 打开 Excel 文件book = openpyxl.load_workbook(excel_path)# 获取指定名称的工作表sheet = book[sheetname]# 初始化一个空列表,用于存储行数据values = []for row in sheet.iter_rows(values_only=True):values.append(row)return values
  • test_add_excel.py
import sys
import pytest
import os
import allure
from Calculator_Project.base.base import Base
from Calculator_Project.utils.log_util import logger
from Calculator_Project.utils.utils import Utils# 定义一个获取加法数据的函数,接收一个参数 level
@pytest.mark.parametrize("type",["有效等价类", "无效等价类", "边界值", "错误推测"])
def get_add_data(type):"""读取加法的测试数据:param type: 用例类型:return: 对应优先级的测试数据和 ids"""# 获取当前文件的系统路径root_path = os.path.dirname(os.path.abspath(__file__))# 打印当前文件的系统路径print(f"当前系统路径:{root_path}")# 拼接 Excel文件的路径excel_path = os.sep.join([root_path, '..', 'datas', 'calculator.xlsx'])# 打印 Excel文件的路径print(f"excel文件路径:{excel_path}")sheetname = "加法"# 获取 Excel 数据excel_data = Utils.get_excel_data(excel_path, sheetname)# 打印 Excel 数据print(excel_data)# 初始化空列表,用于存储对应的测试数据datas = []ids = []# 遍历数据行,跳过标题行for row in excel_data[1:]:# 获取对应 level 优先级的数据if row[0] == type:datas.append([row[1], row[2], row[3]])  # 返回 a, b, expectids.append(row[4])  # 返回 ids# 返回测试数据和测试标题的数组return [datas, ids]# 设置allure报告的模块名称
@allure.epic("计算器测试")
# 设置allure报告的模块名称
@allure.feature("计算器加法测试")
# 定义一个加法测试类,继承自Base类
class TestAddExcel(Base):# 设置测试用例的执行顺序@pytest.mark.run(order=1)# 设置allure报告的用户故事@allure.story("加法-有效等价类的用例")# 使用 pytest的参数化装饰器,将get_add_datas("有效等价类")的结果解包成多个参数值,生成测试用例@pytest.mark.parametrize("a, b, expect", get_add_data("有效等价类")[0], ids=get_add_data("有效等价类")[1])# 定义一个测试加法的方法,接收3个参数:a, b, expectdef test_add_valid(self, a, b, expect):# 添加图片allure.attach.file("./datas/pic2.jpg",name="计算器图片2",attachment_type=allure.attachment_type.JPG,extension="JGP")# 记录测试用例参数的日志信息logger.info(f"a={a}, b={b}, expect={expect}")# 设置allure报告的测试步骤with allure.step(f"1. 调用被测程序进行计算{a}+{b}={expect}"):# 测试步骤:调用被测应用进行计算result = self.calculator.add(a, b)# 记录计算结果的日志信息logger.info(f"实际计算结果为:{result}")# 设置allure报告的测试步骤with allure.step(f"2. 断言{result} == {expect}"):# 断言实际结果是否与预期结果一致assert result == expect# 设置测试用例的执行顺序@pytest.mark.run(order=4)# 设置allure报告的用户故事@allure.story("加法-无效等价类的用例")# 使用 pytest的参数化装饰器,将get_add_datas("无效等价类")的结果解包成多个参数值,生成测试用例@pytest.mark.parametrize("a,b,expect", get_add_data("无效等价类")[0], ids=get_add_data("无效等价类")[1])# 定义一个测试加法的方法,接收3个参数:a, b, expectdef test_add_unvalid(self, a, b, expect):# 记录测试用例参数的日志信息logger.info(f"a={a}, b={b}, expect={expect}")# 设置allure报告的测试步骤with allure.step(f"1. 调用被测程序进行计算{a}+{b}={expect}"):# 测试步骤:调用被测应用进行计算result = self.calculator.add(a, b)# 记录计算结果的日志信息logger.info(f"实际计算结果为:{result}")# 设置allure报告的测试步骤with allure.step(f"2. 断言{result} == {expect}"):# 断言实际结果是否与预期结果一致assert result == expect# 设置测试用例的执行顺序@pytest.mark.run(order=2)# 设置allure报告的用户故事@allure.story("加法-边界值的用例")# 使用 pytest的参数化装饰器,将get_add_datas("边界值")的结果解包成多个参数值,生成测试用例@pytest.mark.parametrize("a, b, expect", get_add_data("边界值")[0], ids=get_add_data("边界值")[1])# 定义一个测试加法的方法,接收3个参数:a, b, expectdef test_add_boundary(self, a, b, expect):# 记录测试用例参数的日志信息logger.info(f"a={a}, b={b}, expect={expect}")# 设置allure报告的测试步骤with allure.step(f"1. 调用被测程序进行计算{a}+{b}={expect}"):# 测试步骤:调用被测应用进行计算result = self.calculator.add(a, b)# 记录计算结果的日志信息logger.info(f"实际计算结果为:{result}")# 设置allure报告的测试步骤with allure.step(f"2. 断言{result} == {expect}"):# 断言实际结果是否与预期结果一致assert result == expect# 设置测试用例的执行顺序@pytest.mark.run(order=3)# 设置allure报告的用户故事@allure.story("加法-错误推测的用例")# 使用 pytest的参数化装饰器,将get_add_datas("错误推测")的结果解包成多个参数值,生成测试用例@pytest.mark.parametrize("a,b,expect", get_add_data("错误推测")[0], ids=get_add_data("错误推测")[1])# 定义一个测试加法的方法,接收3个参数:a, b, expectdef test_add_type_error(self, a, b, expect):# 记录测试用例参数的日志信息logger.info(f"a={a}, b={b}, expect={expect}")# 捕获预期的异常with pytest.raises(eval(expect)) as e:# 设置allure报告的测试步骤with allure.step(f"1. 调用被测程序进行计算{a}+{b}={expect}"):# 测试步骤:调用被测应用进行计算result = self.calculator.add(a, b)# 记录计算结果的日志信息logger.info(f"实际计算结果为:{result}")# 记录捕获的异常信息logger.info(f"类型错误为:{e}")# 设置allure报告的测试步骤with allure.step(f"2. 断言{e.type} == {TypeError}"):assert e.type == TypeError# 设置测试用例的执行顺序@pytest.mark.run(order=5)# 设置始终跳过的测试用例@pytest.mark.skipdef test_error_message(self):print("详细提示信息未完成开发,暂不测试。")assert True# 设置测试用例的执行顺序@pytest.mark.run(order=7)# 设置特定条件下跳过的测试用例@pytest.mark.skipif(sys.platform == "darwin", reson = "不做mac的兼容")def test_sys(self):print("Mac系统不做兼容测试")assert True# 设置测试用例的执行顺序@pytest.mark.run(order=6)# 预期失败的测试用例@pytest.mark.xfaildef test_fail(self):print("标记期望失败的案例,还没想好哪些失败。。。")assert True
  • test_div_excel.py
import sys
import pytest
import os
import allure
from Calculator_Project.base.base import Base
from Calculator_Project.utils.log_util import logger
from Calculator_Project.utils.utils import Utils# 定义一个获取除法数据的函数,接收一个参数 level
@pytest.mark.parametrize("type",["有效等价类", "无效等价类", "边界值", "错误推测", "被除数为0"])
def get_div_data(type):"""读取除法的测试数据:param type: 用例类型:return: 对应优先级的测试数据和 ids"""# 获取当前文件的系统路径root_path = os.path.dirname(os.path.abspath(__file__))# 打印当前文件的系统路径print(f"当前系统路径:{root_path}")# 拼接 Excel文件的路径excel_path = os.sep.join([root_path, '..', 'datas', 'calculator.xlsx'])# 打印 Excel文件的路径print(f"excel文件路径:{excel_path}")# 获取 Excel 数据excel_data = Utils.get_excel_data(excel_path, "除法")# 打印 Excel 数据print(excel_data)# 初始化空列表,用于存储对应的测试数据datas = []ids = []# 遍历数据行,跳过标题行for row in excel_data[1:]:# 获取对应 level 优先级的数据if row[0] == type:datas.append([row[1], row[2], row[3]])  # 返回 a, b, expectids.append(row[4])  # 返回 ids# 返回测试数据和测试标题的数组return [datas, ids]# 设置allure报告的模块名称
@allure.epic("计算器测试")
# 设置allure报告的模块名称
@allure.feature("计算器除法测试")
# 定义一个除法测试类,继承自Base类
class TestDivExcel(Base):# 设置测试用例的执行顺序@pytest.mark.run(order=1)# 设置allure报告的用户故事@allure.story("除法-有效等价类的用例")# 使用 pytest的参数化装饰器,将get_div_datas("有效等价类")的结果解包成多个参数值,生成测试用例@pytest.mark.parametrize("a, b, expect", get_div_data("有效等价类")[0], ids=get_div_data("有效等价类")[1])# 定义一个测试除法的方法,接收3个参数:a, b, expectdef test_div_valid(self, a, b, expect):# 添加图片allure.attach.file("./datas/pic1.jpg",name="计算器图片1",attachment_type=allure.attachment_type.JPG,extension="JGP")# 记录测试用例参数的日志信息logger.info(f"a={a}, b={b}, expect={expect}")# 设置allure报告的测试步骤with allure.step(f"1. 调用被测程序进行计算{a}/{b}={expect}"):# 测试步骤:调用被测应用进行计算result = self.calculator.div(a, b)# 记录计算结果的日志信息logger.info(f"实际计算结果为:{result}")# 设置allure报告的测试步骤with allure.step(f"2. 断言{result} == {expect}"):# 断言实际结果是否与预期结果一致assert result == expect# 设置测试用例的执行顺序@pytest.mark.run(order=4)# 设置allure报告的用户故事@allure.story("除法-无效等价类的用例")# 使用 pytest的参数化装饰器,将get_div_datas("无效等价类")的结果解包成多个参数值,生成测试用例@pytest.mark.parametrize("a,b,expect", get_div_data("无效等价类")[0], ids=get_div_data("无效等价类")[1])# 定义一个测试除法的方法,接收3个参数:a, b, expectdef test_div_unvalid(self, a, b, expect):# 记录测试用例参数的日志信息logger.info(f"a={a}, b={b}, expect={expect}")# 设置allure报告的测试步骤with allure.step(f"1. 调用被测程序进行计算{a}/{b}={expect}"):# 测试步骤:调用被测应用进行计算result = self.calculator.div(a, b)# 记录计算结果的日志信息logger.info(f"实际计算结果为:{result}")# 设置allure报告的测试步骤with allure.step(f"2. 断言{result} == {expect}"):# 断言实际结果是否与预期结果一致assert result == expect# 设置测试用例的执行顺序@pytest.mark.run(order=2)# 设置allure报告的用户故事@allure.story("除法-边界值的用例")# 使用 pytest的参数化装饰器,将get_div_datas("边界值")的结果解包成多个参数值,生成测试用例@pytest.mark.parametrize("a, b, expect", get_div_data("边界值")[0], ids=get_div_data("边界值")[1])# 定义一个测试除法的方法,接收3个参数:a, b, expectdef test_div_boundary(self, a, b, expect):# 记录测试用例参数的日志信息logger.info(f"a={a}, b={b}, expect={expect}")# 设置allure报告的测试步骤with allure.step(f"1. 调用被测程序进行计算{a}/{b}={expect}"):# 测试步骤:调用被测应用进行计算result = self.calculator.div(a, b)# 记录计算结果的日志信息logger.info(f"实际计算结果为:{result}")# 设置allure报告的测试步骤with allure.step(f"2. 断言{result} == {expect}"):# 断言实际结果是否与预期结果一致assert result == expect# 设置测试用例的执行顺序@pytest.mark.run(order=3)# 设置allure报告的用户故事@allure.story("除法-错误推测的用例")# 使用 pytest的参数化装饰器,将get_div_datas("错误推测")的结果解包成多个参数值,生成测试用例@pytest.mark.parametrize("a,b,expect", get_div_data("错误推测")[0], ids=get_div_data("错误推测")[1])# 定义一个测试除法的方法,接收3个参数:a, b, expectdef test_div_type_error(self, a, b, expect):# 记录测试用例参数的日志信息logger.info(f"a={a}, b={b}, expect={expect}")# 捕获预期的异常with pytest.raises(eval(expect)) as e:# 设置allure报告的测试步骤with allure.step(f"1. 调用被测程序进行计算{a}/{b}={expect}"):# 测试步骤:调用被测应用进行计算result = self.calculator.div(a, b)# 记录计算结果的日志信息logger.info(f"实际计算结果为:{result}")# 记录捕获的异常信息logger.info(f"类型错误为:{e}")# 设置allure报告的测试步骤with allure.step(f"2. 断言{e.type} == {TypeError}"):assert e.type == TypeError# 设置测试用例的执行顺序@pytest.mark.run(order=5)# 设置allure报告的用户故事@allure.story("除法-被除数为0的用例")# 使用 pytest的参数化装饰器,将get_div_datas("被除数为0")的结果解包成多个参数值,生成测试用例@pytest.mark.parametrize("a, b, expect", get_div_data("被除数为0")[0], ids=get_div_data("被除数为0")[1])# 定义一个测试除法的方法,接收3个参数:a, b, expectdef test_div_zero(self, a, b, expect):# 记录测试用例参数的日志信息logger.info(f"a={a}, b={b}, expect={expect}")# 捕获预期的异常with pytest.raises(eval(expect)) as e:# 设置allure报告的测试步骤with allure.step(f"1. 调用被测程序进行计算{a}/{b}={expect}"):# 测试步骤:调用被测应用进行计算result = self.calculator.div(a, b)# 记录计算结果的日志信息logger.info(f"实际计算结果为:{result}")# 记录捕获的异常信息logger.info(f"类型错误为:{e}")# 设置allure报告的测试步骤with allure.step(f"2. 断言{e.type} == ZeroDivisionError"):assert e.type == ZeroDivisionError# 设置测试用例的执行顺序@pytest.mark.run(order=8)# 设置始终跳过的测试用例@pytest.mark.skipdef test_error_message(self):print("详细提示信息未完成开发,暂不测试。")assert True# 设置测试用例的执行顺序@pytest.mark.run(order=7)# 设置特定条件下跳过的测试用例@pytest.mark.skipif(sys.platform == "darwin", reson = "不做mac的兼容")def test_sys(self):print("Mac系统不做兼容测试")assert True# 设置测试用例的执行顺序@pytest.mark.run(order=6)# 预期失败的测试用例@pytest.mark.xfaildef test_fail(self):print("标记期望失败的案例,还没想好哪些失败。。。")assert True
  • conftest.py
import pytest
import yaml# 解决用例描述中的中文乱码问题
# 定义一个pytest的钩子函数,接收3个参数 session, config, items,返回值类型都为 None
# 主要用于在收集测试用例后,对其进行修改
def pytest_collection_modifyitems(session, config, items):# 循环遍历所有收集到的测试用例的 itemsfor item in items:# 对每个 item的 name进行编码和解码# item.name.encode('utf-8')是将 item按照 UTF-8格式编码# decode("unicode-escape")是将编码后的字符串按照 unicode-escape格式解码,以便正确显示中文字符。item.name = item.name.encode("utf-8").decode("unicode-escape")# 对每个 item的 _nodeid进行编码和解码item._nodeid = item._nodeid.encode("utf-8").decode("unicode-escape")
  • pytest.ini
[pytest]# 日志开关 true false
log_cli = true
# 日志级别
log_cli_level = info
# 使用4个并发进程运行测试
# 打印详细日志,相当于命令行加 -vs
# 在第3个失败的测试后停止执行
addopts = -n 4 --capture=no --maxfail=3
# 日志格式
log_cli_format = %(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s)
# 日志时间格式
log_cli_date_format = %Y-%m-%d %H:%M:%S
# 日志文件位置
log_file = ./log/test.log
# 日志文件等级
log_file_level = info
# 日志文件格式
log_file_format = %(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s)
# 日志文件日期格式
log_file_date_format = %Y-%m-%d %H:%M:%# 设置执行的路径
testpaths = tests
# 匹配测试文件的命名模式
python_files = test_*.py
# 匹配测试类的命名模式
python_classes = Test*
# 匹配测试函数的命名模式
python_functions = test_*
markers =run: specify order of test exection
  • log_util.py
import logging
import osfrom logging.handlers import RotatingFileHandler# 绑定绑定句柄到logger对象
logger = logging.getLogger(__name__)
# 获取当前工具文件所在的路径
root_path = os.path.dirname(os.path.abspath(__file__))
# 拼接当前要输出日志的路径
log_dir_path = os.sep.join([root_path, '..', f'/logs'])
if not os.path.isdir(log_dir_path):os.mkdir(log_dir_path)
# 创建日志记录器,指明日志保存路径,每个日志的大小,保存日志的上限
file_log_handler = RotatingFileHandler(os.sep.join([log_dir_path, 'log.log']), maxBytes=1024 * 1024, backupCount=10)
# 设置日志的格式
date_string = '%Y-%m-%d %H:%M:%S'
formatter = logging.Formatter('[%(asctime)s] [%(levelname)s] [%(filename)s]/[line: %(lineno)d]/[%(funcName)s] %(message)s ', date_string)
# 日志输出到控制台的句柄
stream_handler = logging.StreamHandler()
# 将日志记录器指定日志的格式
file_log_handler.setFormatter(formatter)
stream_handler.setFormatter(formatter)
# 为全局的日志工具对象添加日志记录器
# 绑定绑定句柄到logger对象
logger.addHandler(stream_handler)
logger.addHandler(file_log_handler)
# 设置日志输出级别
logger.setLevel(level=logging.INFO)

3.2.6 Allure报告

  • 在线Allure报告



  • 静态Allure报告

在这里插入图片描述

推荐学习

【霍格沃兹测试开发】7天软件测试快速入门带你从零基础/转行/小白/就业/测试用例设计实战

【霍格沃兹测试开发】最新版!Web 自动化测试从入门到精通/ 电子商务产品实战/Selenium (上集)

【霍格沃兹测试开发】最新版!Web 自动化测试从入门到精通/ 电子商务产品实战/Selenium (下集)

【霍格沃兹测试开发】明星讲师精心打造最新Python 教程软件测试开发从业者必学(上集)

【霍格沃兹测试开发】明星讲师精心打造最新Python 教程软件测试开发从业者必学(下集)

【霍格沃兹测试开发】精品课合集/ 自动化测试/ 性能测试/ 精准测试/ 测试左移/ 测试右移/ 人工智能测试

【霍格沃兹测试开发】腾讯/ 百度/ 阿里/ 字节测试专家技术沙龙分享合集/ 精准化测试/ 流量回放/Diff

【霍格沃兹测试开发】Pytest 用例结构/ 编写规范 / 免费分享

【霍格沃兹测试开发】JMeter 实时性能监控平台/ 数据分析展示系统Grafana/Docker 安装

【霍格沃兹测试开发】接口自动化测试的场景有哪些?为什么要做接口自动化测试?如何一键生成测试报告?

【霍格沃兹测试开发】面试技巧指导/ 测试开发能力评级/1V1 模拟面试实战/ 冲刺年薪百万!

【霍格沃兹测试开发】腾讯软件测试能力评级标准/ 要评级表格的联系我

【霍格沃兹测试开发】Pytest 与Allure2 一键生成测试报告/ 测试用例断言/ 数据驱动/ 参数化

【霍格沃兹测试开发】App 功能测试实战快速入门/adb 常用命令/adb 压力测试

【霍格沃兹测试开发】阿里/ 百度/ 腾讯/ 滴滴/ 字节/ 一线大厂面试真题讲解,卷完拿高薪Offer !

【霍格沃兹测试开发】App自动化测试零基础快速入门/Appium/自动化用例录制/参数配置

【霍格沃兹测试开发】如何用Postman 做接口测试,从入门到实战/ 接口抓包(最新最全教程)

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

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

相关文章

【GD32】---- 使用GD32调试串口并实现printf打印输出

1 复制工程模板 直接复制工程模板里的系统文件和固件库文件到新的工程文件01_USART_Printf 2 新建keil工程 参考上一篇博文&#xff1a;【GD32】---- 移植工程模板及点灯测试 3 编写代码 3.1 创建USART文件 创建一个USART.c文件&#xff0c;放于05_UserDriver文件夹中 …

Rust 赋能前端:PDF 分页/关键词标注/转图片/抽取文本/抽取图片/翻转...

❝ 我从不幻想成功。我只会为了成功努力实践 大家好&#xff0c;我是柒八九。一个专注于前端开发技术/Rust及AI应用知识分享的Coder ❝ 此篇文章所涉及到的技术有 WebAssembly Mupdf Pdf操作( 分页展示/文本抽离/文本标注/获取超链接/Pdf转图片/翻转/截取) 因为&#xff0c;行文…

新型PyPI攻击技术可能导致超2.2万软件包被劫持

一种针对 Python 软件包索引&#xff08;PyPI&#xff09;注册表的新型供应链攻击技术已在野外被利用&#xff0c;并且目前正试图渗透到下游组织中。 软件供应链安全公司 JFrog 将其代号定为Revival Hijack&#xff0c;并称这种攻击方法可用于劫持 2.2万个现有 PyPI 软件包&am…

6、LVGL控件-线条、图片、按钮矩阵

本篇文章目录导航 ♠♠ LVGL控件-线条、图片、按钮矩阵 ♣♣♣♣ 一、LVGL 线条部件 ♦♦♦♦♦♦♦♦ 1.1 线条部件组成部分 ♦♦♦♦♦♦♦♦ 1.2 线条部件基本API ♦♦♦♦♦♦♦♦ 1.3 实验小演示 ♣♣♣♣ 二、LVGL 图片部件 ♦♦♦♦♦♦♦♦ 2.1 图片部件组成部分 ♦♦…

前端框架有哪些?

前言 用户体验是每个开发网站的企业中的重中之重。无论后台有多方面的操作和功能&#xff0c;用户的视图和体验都必须是无缝的最友好的。这需要使用前端框架来简化交互式、以用户为中心的网站的开发。 前端框架是一种用于简化Web开发的工具&#xff0c;它提供了一套预定义的代…

基于蜣螂优化最小二乘支持向量机的数据分类预测Matlab程序DBO-LSSVM 多特征输入多类别输出 含基础程序

基于蜣螂优化最小二乘支持向量机的数据分类预测Matlab程序DBO-LSSVM 多特征输入多类别输出 含基础程序 文章目录 一、基本原理DBO&#xff08;Dung Beetle Optimization&#xff09;算法原理LSSVM&#xff08;Least Squares Support Vector Machine&#xff09;模型原理DBO-LSS…

C语言 | Leetcode C语言题解之第388题文件的最长绝对路径

题目&#xff1a; 题解&#xff1a; #define MAX(a, b) ((a) > (b) ? (a) : (b))int lengthLongestPath(char * input){int n strlen(input);int pos 0;int ans 0;int * level (int *)malloc(sizeof(int) * (n 1));memset(level, 0, sizeof(int) * (n 1));while (po…

iOS——Block与内存管理

需要内存管理的情况 1、对象类型的auto变量。 2、引用了 __block 修饰符的变量。 三种block类型 全局类型 &#xff08;NSGlobalBlock&#xff09; 如果一个block里面没有访问普通局部变量(也就是说block里面没有访问任何外部变量或者访问的是静态局部变量或者访问的是全局…

SpringBoot+Vue实现大文件上传(断点续传-后端控制(一))

SpringBootVue实现大文件上传&#xff08;断点续传&#xff09; 1 环境 SpringBoot 3.2.1&#xff0c;Vue 2&#xff0c;ElementUI&#xff0c;spark-md5 2 问题 在前一篇文章&#xff0c;我们写了通过在前端控制的断点续传&#xff0c;但是有两个问题&#xff0c;第一个问题&…

AUTOSAR Adaptive与智能汽车E/E架构发展趋势

AUTOSAR Adaptive是一个面向现代汽车应用需求的标准&#xff0c;特别适用于那些需要高计算能力和灵活性的应用。以下是AUTOSAR Adaptive的典型特性&#xff1a; 高计算能力&#xff1a;AUTOSAR Adaptive支持使用MPU&#xff08;微处理器&#xff09;&#xff0c;这些处理器的性…

嵌入式开发学习路线(25届校招学习) 嵌入式学习路线七年规划:从大一小白到校招大佬 (学习路线汇总)

嵌入式开发学习路线&#xff08;25届校招可以参考&#xff09; 嵌入式系统作为当前最热门且最有发展前途的IT应用领域之一&#xff0c;吸引了大量有志于从事该行业的学习者。为了系统地掌握嵌入式开发技能&#xff0c;以下是一条详细的学习路线&#xff0c;旨在帮助初学者逐步…

CodeSys中动态切换3D模型

文章目录 需求研究结果 需求 在前面的【CodeSys开发3d机械臂显示控件】中&#xff0c;我们已经实现了一个可以显示3d模型的控件。但是这个控件是和使用的3d模型绑定死的&#xff0c;在安装这个控件时就已经将模型文件于控件一起安装到codesys中。 假如我想在不同的工程中&…

智能家居系统(基于STM32F103C8T6标准库+FreeRTOS+Qt串口开发实现)

视频演示&#xff1a;基于STM32F103C8T6标准库FreeRTOSQt串口开发实现的智能家居项目_哔哩哔哩_bilibili 基于STM32F103C8T6标准库FreeRTOSQt串口开发实现的智能家居项目: https://pan.baidu.com/s/1f41gAfOOnlcQoKoMx3o84A?pwd6j2g 提取码: 6j2g 注&#xff1a;本项目为学习完…

Meta关闭Spark AR平台:未来规划与影响分析

Meta宣布将关闭其移动AR创作平台Spark AR&#xff0c;这一消息在业界引起了广泛关注。尽管Snap和TikTok在AR滤镜领域取得了巨大成功&#xff0c;但Meta却选择了另一条发展道路。本文将探讨这一决策背后的可能原因及其对未来的影响。 关闭Spark AR平台的背后 硬件为主&#xff…

计算机网络(三) —— 简单Udp网络程序

目录 一&#xff0c;初始化服务器 1.0 辅助文件 1.1 socket函数 1.2 填充sockaddr结构体 1.3 bind绑定函数 1.4 字符串IP和整数IP的转换 二&#xff0c;运行服务器 2.1 接收 2.2 处理 2.3 返回 三&#xff0c;客户端实现 3.1 UdpClient.cc 实现 3.2 Main.cc 实现 …

【Mysql】系统服务启动访问报错问题处理:this is incompatible with sql_mode=only_full_group_by

一、背景&#xff1a; 本来已经正常运行的平台&#xff0c;突然有一天由于对服务器进行部分操作迁移&#xff0c;发现jar可以正常启动&#xff0c;但是访问功能一直报错&#xff0c;监控后台日志后&#xff0c;发现了问题&#xff1a; 报错的具体信息如下&#xff1a; Caused…

Linux编译器--gcc/g++使用

目录 一、预编译指令 1.1预处理功能 1.2指令 1.3问题扩展 二、编译&#xff08;生成汇编&#xff09; 三、汇编&#xff08;生成二进制机器语言&#xff09; 四、链接&#xff08;生成可执行文件或库文件&#xff09; 4.1库文件 4.2目标文件和库的链接 4.3动态库和静态…

【Django-Minio-Storage 使用教程】

Django-Minio-Storage 使用教程 安装 Django-Minio-Storage配置 Django 项目官方文档 安装 Django-Minio-Storage 使用 pip 安装 Django-Minio-Storage pip install django-minio-storage配置 Django 项目 在 Django 项目的 settings.py 文件中进行以下配置 INSTALLED_APPS…

【mysql】mysql修改sql_mode之后无法启动

现象&#xff1a;修改后mysql无法启动&#xff0c;不报错 原因&#xff1a;MySQL在8以后sql_mode已经取消了NO_AUTO_CREATE_USER这个关键字。去掉这个关键字后&#xff0c;启动就可以了 修改前&#xff1a; sql_modeSTRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR…

Bootstrap前端框架Glyphicons字体图标

115工具网收集提供Bootstrap前端框架Glyphicons字体图标库对照表​​​​​​​&#xff0c;Bootstrap前端UI,Glyphicons字体图标调用,Bootstrap按钮字体图标对照表,包括250多个来自Glyphicon Halflings的字体图标.项目中引用Bootstrap相关文件后即可直接调用下列图标class&quo…