当前位置: 首页 > news >正文

python excel接口自动化测试框架!

今天采用Excel继续写一个接口自动化测试框架。

设计流程图

这张图是我的excel接口测试框架的一些设计思路。

首先读取excel文件,得到测试信息,然后通过封装的requests方法,用unittest进行测试。

其中,接口关联的参数通过正则进行查找和替换,为此我专门开辟了一个全局变量池,用于管理各种各样的变量。

最后通过HTMLrunner生成测试报告。如果执行失败,发送测试报告结果邮件。

图片

Excel和结果预览

这个时excel的测试测试用例组织结构图。

图片

这个是运行之后生成的HTML测试报告。

图片

这个时运行之后生成的excel报告。可以看到我故意在预期正则中设置了错误的值,然后用例失败的同时也把失败的预期值标记出来了。

图片

测试失败之后收到的邮件

图片

好了上面就是一些简单的介绍,我们开始进入正题把。

框架结构

首先,要开发这样一个excel接口自动化测试项目必须有一个设计清晰的思路,这样我们在开发框架的过程中才会明白自己要干什么。【关注我的vx公众号:程序员小濠免费获取一份13G的软件测试资源】

图片

Excel相关

用例设计

本次依然采用的是智学网登录接口。使用了智学网中的登录接口和登录验证接口,这两个接口之间有依赖的参数。

配置文件

在项目的根目录创建config.py,把你能想到的配置信息,全部丢在这个文件中进行统一的管理。

#!/usr/bin/env python3
# coding=utf-8
import osclass CF:"""配置文件"""# 项目目录BASE_DIR = os.path.abspath(os.path.dirname(__file__))# Excel首行配置NUMBER = 0NAME = 1METHOD = 2URL = 3ROUTE = 4HEADERS = 5PARAMETER = 6  # 参数EXPECTED_CODE = 7  # 预期响应码EXPECTED_REGULAR = 8  # 预期正则EXPECTED_VALUE = 9  # 预期结果值SPEND_TIME = 10  # 响应时间TEST_RESULTS = 11  # 测试结果EXTRACT_VARIABLE = 12  # 提取变量RESPONSE_TEXT = 13  # 响应文本# 字体大小FONT_SET = "微软雅黑"FONT_SIZE = 16# 颜色配置COLOR_PASSED = "90EE90"COLOR_FAILED = "FA8072"# 邮箱配置EMAIL_INFO = {'username': '1084502012@qq.com','password': 2,'smtp_host': 'smtp.qq.com','smtp_port': 465}# 收件人ADDRESSEE = ['1084502012@qq.com']if __name__ == '__main__':print(CF.EXPECTED_CODE)

读取/写入excel

在common目录中新建excelset.py文件,在这个文件中我们要实现,读取excel中的用例,写入测试结果并绘制相应的颜色,写入测试耗费时长。

#!/usr/bin/env python
# coding=utf-8
import shutil
import openpyxl
from config import CF
from openpyxl.styles import Font
from openpyxl.styles import PatternFill
from common.variables import VariablePoolclass ExcelSet:"""Excel配置"""def __init__(self):shutil.copyfile(VariablePool.get('excel_input'), VariablePool.get('excel_output'))self.path = VariablePool.get('excel_output')self.wb = openpyxl.load_workbook(self.path)self.table = self.wb.activedef get_cases(self, min_row=2):"""获取用例"""all_cases = []for row in self.table.iter_rows(min_row=min_row):all_cases.append((self.table.cell(min_row, CF.NAME + 1).value,min_row, [cell.value for cell in row]))min_row += 1return all_casesdef write_color(self, row_n, col_n, color=CF.COLOR_FAILED):"""写入颜色"""cell = self.table.cell(row_n, col_n + 1)fill = PatternFill("solid", fgColor=color)cell.fill = filldef write_results(self, row_n, col_n, value, color=True):"""写入结果"""cell = self.table.cell(row_n, col_n + 1)cell.value = valuefont = Font(name=CF.FONT_SET, size=CF.FONT_SIZE)cell.font = fontif color:if value.lower() in ("fail", 'failed'):fill = PatternFill("solid", fgColor=CF.COLOR_FAILED)cell.fill = fillelif value.lower() in ("pass", "ok"):fill = PatternFill("solid", fgColor=CF.COLOR_PASSED)cell.fill = fillself.wb.save(self.path)excel_set = ExcelSet()
if __name__ == '__main__':print(excel_set.get_cases())

日志封装

logger.py

在一个项目中日志是必不可少的东西,可以第一时间反馈问题。

#!/usr/bin/env python3
# coding=utf-8
import os
import logging
from config import CF
from datetime import datetimeclass Logger:def __init__(self):self.logger = logging.getLogger()if not self.logger.handlers:self.logger.setLevel(logging.DEBUG)# 创建一个handler,用于写入日志文件fh = logging.FileHandler(self.log_path, encoding='utf-8')fh.setLevel(logging.DEBUG)# 创建一个handler,用于输出到控制台ch = logging.StreamHandler()ch.setLevel(logging.INFO)# 定义handler的输出格式formatter = logging.Formatter(self.fmt)fh.setFormatter(formatter)ch.setFormatter(formatter)# 给logger添加handlerself.logger.addHandler(fh)self.logger.addHandler(ch)@propertydef log_path(self):logs_path = os.path.join(CF.BASE_DIR, 'logs')if not os.path.exists(logs_path):os.makedirs(logs_path)now_month = datetime.now().strftime("%Y%m")return os.path.join(logs_path, '{}.log'.format(now_month))@propertydef fmt(self):return '%(levelname)s %(asctime)s %(filename)s:%(lineno)d %(message)s'log = Logger().logger
if __name__ == '__main__':log.info("你好")

正则操作

regular.py

在接口关联参数的提取和传参中的起到了决定性的作用。

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import re
from utils.logger import log
from common.variables import VariablePool
from core.serialize import is_json_strclass Regular:"""正则类"""def __init__(self):self.reg = re.compiledef finds(self, string):return self.reg(r'\{{(.*?)}\}').findall(string)def subs(self, keys, string):result = Nonelog.info("提取变量:{}".format(keys))for i in keys:if VariablePool.has(i):log.info("替换变量:{}".format(i))comment = self.reg(r"\{{%s}}" % i)result = comment.sub(VariablePool.get(i), string)log.info("替换结果:{}".format(result))return resultdef find_res(self, exp, string):"""在结果中查找"""if is_json_str(string):return self.reg(r'\"%s":"(.*?)"' % exp).findall(string)[0]else:return self.reg(r'%s' % exp).findall(string)[0]if __name__ == '__main__':a = "{'data': {'loginName': 18291900215, 'password': '{{dd636482aca022}}', 'code': None, 'description': 'encrypt'}}"print(Regular().finds(a))

核心操作

定义变量池

variables.py

全局变量池来了,是不是很简单,但是作用确实很巨大的。

#!/usr/bin/env python3
# -*- coding:utf-8 -*-class VariablePool:"""全局变量池"""@staticmethoddef get(name):"""获取变量"""return getattr(VariablePool, name)@staticmethoddef set(name, value):"""设置变量"""setattr(VariablePool, name, value)@staticmethoddef has(name):return hasattr(VariablePool, name)if __name__ == '__main__':VariablePool.set('name', 'wxhou')print(VariablePool.get('name'))

封装requests

request.py

最最核心的部分,对于python requests库的二次封装。用以实现接口的请求和返回结果的获取。

#!/usr/bin/env python
# coding=utf-8
import urllib3
import requests
from config import CF
from utils.logger import log
from common.regular import Regular
from common.setResult import replace_param
from core.serialize import deserialization
from requests.exceptions import RequestException
from common.variables import VariablePoolurllib3.disable_warnings()class HttpRequest:"""二次封装requests方法"""http_method_names = 'get', 'post', 'put', 'delete', 'patch', 'head', 'options'def __init__(self):self.r = requests.session()self.reg = Regular()def send_request(self, case, **kwargs):"""发送请求:param case: 测试用例:param kwargs: 其他参数:return: request响应"""if case[CF.URL]:VariablePool.set('url', case[CF.URL])if case[CF.HEADERS]:VariablePool.set('headers', deserialization(case[CF.HEADERS]))method = case[CF.METHOD].upper()url = VariablePool.get('url') + case[CF.ROUTE]self.r.headers = VariablePool.get('headers')params = replace_param(case)if params: kwargs = paramstry:log.info("Request Url: {}".format(url))log.info("Request Method: {}".format(method))log.info("Request Data: {}".format(kwargs))def dispatch(method, *args, **kwargs):if method in self.http_method_names:handler = getattr(self.r, method)return handler(*args, **kwargs)else:raise AttributeError('request method is ERROR!')response = dispatch(method.lower(), url, **kwargs)log.info(response)log.info("Response Data: {}".format(response.text))return responseexcept RequestException as e:log.exception(format(e))except Exception as e:raise e

序列化与反序列化

serialize.py

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import json
from json.decoder import JSONDecodeErrordef deserialization(content: json):"""反序列化json对象 -> python数据类型"""return json.loads(content)def serialization(content, ensure_ascii=True):"""序列化python数据类型 -> json对象"""return json.dumps(content, ensure_ascii=ensure_ascii)def is_json_str(string):"""判断是否是json格式字符串"""if isinstance(string, str):try:json.loads(string)return Trueexcept JSONDecodeError:return Falsereturn Falseif __name__ == '__main__':a = "{'data': {'loginName': 18291900215, 'password': 'dd636482aca022', 'code': None, 'description': 'encrypt'}}"print(is_json_str(a))

检查结果

checkResult.py

在这个文件中,我们将对测试返回的结果进行预期的验证。

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import re
from config import CF
from utils.logger import log
from requests import Response
from common.excelset import excel_setdef check_result(r: Response, number, case):"""获取结果"""results = []excel_set.write_results(number, CF.SPEND_TIME, r.elapsed.total_seconds(), color=False)if case[CF.EXPECTED_CODE]:res = int(case[CF.EXPECTED_CODE]) == r.status_coderesults.append(res)if not res: excel_set.write_color(number, CF.EXPECTED_CODE)log.info(f"预期响应码:{case[CF.EXPECTED_CODE]},实际响应码:{r.status_code}")if case[CF.EXPECTED_VALUE]:res = case[CF.EXPECTED_VALUE] in r.textresults.append(res)if not res: excel_set.write_color(number, CF.EXPECTED_VALUE)log.info(f"预期响应值:{case[CF.EXPECTED_VALUE]},实际响应值:{r.text}")if case[CF.EXPECTED_REGULAR]:res = r'%s' % case[CF.EXPECTED_REGULAR]ref = re.findall(res, r.text)results.append(ref)if not ref: excel_set.write_color(number, CF.EXPECTED_REGULAR)log.info(f"预期正则:{res},响应{ref}")if all(results):excel_set.write_results(number, CF.TEST_RESULTS, 'Pass')log.info(f"用例【{case[CF.NAME]}】测试成功!")else:excel_set.write_results(number, CF.TEST_RESULTS, 'Failed')assert all(results), f"用例【{case[CF.NUMBER]}{case[CF.NAME]}】测试失败:{results}"

设置参数

setResult.py

在这个文件中我们实现了接口返回值的提取,实现了接口传递参数的函数。

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from requests import Response
from utils.logger import log
from common.regular import Regular
from common.excelset import excel_set
from common.variables import VariablePool
from core.serialize import is_json_str, deserialization
from config import CFreg = Regular()def get_var_result(r: Response, number, case):"""替换变量"""if case[CF.EXTRACT_VARIABLE]:for i in case[CF.EXTRACT_VARIABLE].split(','):result = reg.find_res(i, r.text)VariablePool.set(i, result)log.info(f"提取变量{i}={result}")if not VariablePool.get(i):excel_set.write_results(number, CF.EXTRACT_VARIABLE, f"提变量{i}失败")excel_set.write_results(number, CF.RESPONSE_TEXT,f"ResponseCode:{r.status_code}\nResponseText:{r.text}")def replace_param(case):"""传入参数"""if case[CF.PARAMETER]:if is_json_str(case[CF.PARAMETER]):is_extract = reg.finds(case[CF.PARAMETER])if is_extract:return deserialization(reg.subs(is_extract, case[CF.PARAMETER]))return deserialization(case[CF.PARAMETER])

测试操作

test_api.py

我们采用unittest进行测试,在前置条件和后置条件中我们对封装的HttpRequest方法进行了初始化和关闭会话操作。

使用parameterized库中的expend方法对excel中的用例进行参数化读取执行。

#!/usr/bin/env python
# coding=utf-8
import unittest
from parameterized import parameterized
from common.excelset import excel_set
from core.request import HttpRequest
from common.checkResult import check_result
from common.setResult import get_var_resultclass TestApi(unittest.TestCase):"""测试接口"""@classmethoddef setUpClass(cls) -> None:cls.req = HttpRequest()@classmethoddef tearDownClass(cls) -> None:cls.req.r.close()@parameterized.expand(excel_set.get_cases())def test_api(self, name, number, case):"""测试excel接口用例"""r = self.req.send_request(case)get_var_result(r, number, case)check_result(r, number, case)if __name__ == '__main__':unittest.main(verbosity=2)

测试报告发送邮件类

run.py

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import os
import platform
import argparse
import unittest
from common.variables import VariablePool
from utils.send_mail import send_report_mail
from utils.HTMLTestRunner import HTMLTestRunnerdef running(path):"""运行"""test_case = unittest.defaultTestLoader.discover('tests', 'test*.py')with open(path, 'wb') as fp:runner = HTMLTestRunner(stream=fp,title='Excel接口测试',description="用例执行情况",verbosity=2)result = runner.run(test_case)if result.failure_count:send_report_mail(path)def file_path(arg):"""获取输入的文件路径"""if 'Windows' in platform.platform():_dir = os.popen('chdir').read().strip()else:_dir = os.popen('pwd').read().strip()if _dir in arg:return argreturn os.path.join(_dir, arg)def main():"""主函数"""parser = argparse.ArgumentParser(description="运行Excel接口测试")parser.add_argument('-i', type=str, help='原始文件')parser.add_argument('-o', type=str, default='report.xlsx', help="输出文件")parser.add_argument('-html', type=str, default='report.html', help="报告文件")args = parser.parse_args()VariablePool.set('excel_input', file_path(args.i))VariablePool.set('excel_output', file_path(args.o))VariablePool.set('report_path', file_path(args.html))running(VariablePool.get('report_path'))if __name__ == '__main__':main()

运行

值得注意的是,运行测试时要关闭office打开该excel文件。

最后的文件中我是使用了argparse进行了命令行管理,意味着我们可以通过命令行进行测试而无需关心excel在那个目录下存放着。

python run.py -i data\usercase.xlsx

输入下面的命令执行一下。

INFO 2020-07-30 22:07:52,713 request.py:40 Request Url: https://www.zhixue.com/weakPwdLogin/?from=web_login
INFO 2020-07-30 22:07:52,714 request.py:41 Request Method: POST
INFO 2020-07-30 22:07:52,715 request.py:42 Request Data: {'data': {'loginName': 18291900215, 'password': 'dd636482aca022', 'code': None, 'descriptio
n': 'encrypt'}}
INFO 2020-07-30 22:08:17,204 request.py:55 <Response [200]>
INFO 2020-07-30 22:08:17,204 request.py:56 Response Data: {"data":"1500000100070008427","result":"success"}
INFO 2020-07-30 22:08:17,207 setResult.py:20 提取变量data=1500000100070008427
INFO 2020-07-30 22:08:17,307 checkResult.py:18 预期响应码:200,实际响应码:200
INFO 2020-07-30 22:08:17,308 checkResult.py:23 预期响应值:"result":"success",实际响应值:{"data":"1500000100070008427","result":"success"}
INFO 2020-07-30 22:08:17,310 checkResult.py:29 预期正则:[\d]{16},响应['1500000100070008']
INFO 2020-07-30 22:08:17,356 checkResult.py:32 用例【登录】测试成功!
ok test_api_0__ (test_api.TestApi)
INFO 2020-07-30 22:08:17,358 regular.py:20 提取变量:['data']
INFO 2020-07-30 22:08:17,359 regular.py:23 替换变量:data
INFO 2020-07-30 22:08:17,361 regular.py:26 替换结果:{"data": {"userId": "1500000100070008427"}}
INFO 2020-07-30 22:08:17,363 request.py:40 Request Url: https://www.zhixue.com/loginSuccess/
INFO 2020-07-30 22:08:17,366 request.py:41 Request Method: POST
INFO 2020-07-30 22:08:17,367 request.py:42 Request Data: {'data': {'userId': '1500000100070008427'}}
INFO 2020-07-30 22:08:20,850 request.py:55 <Response [200]>
INFO 2020-07-30 22:08:20,851 request.py:56 Response Data: {"result":"success"}
INFO 2020-07-30 22:08:20,932 checkResult.py:18 预期响应码:200,实际响应码:200
INFO 2020-07-30 22:08:20,933 checkResult.py:23 预期响应值:"result":"success",实际响应值:{"result":"success"}
INFO 2020-07-30 22:08:20,935 checkResult.py:29 预期正则:11,响应[]
F  test_api_1__ (test_api.TestApi)Time Elapsed: 0:00:28.281434
测试结果邮件发送成功!

执行规则

(venv) C:\Users\hoou\PycharmProjects\httptest-excel>python run.py -h
usage: run.py [-h] [-i I] [-o O] [-html HTML]运行Excel接口测试optional arguments:-h, --help  show this help message and exit-i I        原始文件-o O        输出文件-html HTML  报告文件

在命令行输入python run.py excel路径 新excel路径 报告路径

如果不输入新excel路径 和报告路径,会在run.py所在目录生成两个report.xlsx,report.html。

本篇的excel测试框架就完成了。

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走! 

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

相关文章:

python excel接口自动化测试框架!

今天采用Excel继续写一个接口自动化测试框架。 设计流程图 这张图是我的excel接口测试框架的一些设计思路。 首先读取excel文件&#xff0c;得到测试信息&#xff0c;然后通过封装的requests方法&#xff0c;用unittest进行测试。 其中&#xff0c;接口关联的参数通过正则进…...

mybatis:You have an error in your SQL syntax;

完整报错You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near false, false, false, false, false, false, false, false, false, false, false, at line 1 SQL: INSERT INTO user …...

使用 Maven 开发 IntelliJ IDEA 插件

使用 Maven 开发 IntelliJ IDEA 插件的完整流程 1. 创建 Maven 项目 1.1 使用 IntelliJ 创建 Maven 项目 打开 IntelliJ IDEA&#xff0c;点击 File > New > Project。选择 Maven&#xff0c;填写项目名称和 GroupId&#xff0c;例如&#xff1a; GroupId: com.exampl…...

Windows修复SSL/TLS协议信息泄露漏洞(CVE-2016-2183) --亲测

漏洞说明&#xff1a; 打开链接&#xff1a;https://docs.microsoft.com/zh-cn/troubleshoot/windows-server/windows-security/restrict-cryptographic-algorithms-protocols-schannel 可以看到&#xff1a; 找到&#xff1a;应通过配置密码套件顺序来控制 TLS/SSL 密码 我们…...

uniapp生命周期:应用生命周期和页面生命周期

文章目录 1.应用的生命周期2.页面的生命周期 1.应用的生命周期 生命周期的概念&#xff1a;一个对象从创建、运行、销毁的整个过程被称为生命周期 生命周期函数&#xff1a;在生命周期中每个阶段会伴随着每一个函数的出发&#xff0c;这些函数被称为生命周期函数 所有页面都…...

基于SSM的婴幼儿用品商城系统+LW示例参考

1.项目介绍 功能模块&#xff1a;管理员&#xff08;产品管理、产品分类、会员管理、订单管理、秒杀活动、文章管理、数据统计等&#xff09;、普通用户&#xff08;登录注册、个人中心、购物车、我的收藏、各类信息查看等&#xff09;技术选型&#xff1a;SSM&#xff0c;jsp…...

【工具变量】城市供应链创新试点数据(2007-2023年)

一、测算方式&#xff1a;参考C刊《经济管理》沈坤荣和乔刚老师&#xff08;2024&#xff09;的做法&#xff0c;使用“供应链创新与应用试点”的政策虚拟变量&#xff08;TreatPost&#xff09;表征。若样本城市为试点城市&#xff0c;则赋值为 1&#xff0c;否则为 0&#xf…...

【carla生成车辆时遇到的问题】carla显示的坐标和carlaworld中提取的坐标y值相反

项目需要重新运行了一下generate_car.py的脚本&#xff0c;发现死活生成不了&#xff0c;研究了半天&#xff0c;发现脚本里面生成车辆的坐标值y和carla_ros_bridge_with_example_ego_vehicle.launch脚本打开的驾驶操控界面里面的y值正好是相反数! y1-y2 因为&#xff0c;我运行…...

Jira使用笔记二 ScriptRunner 验证问题创建角色

背景 最近在对公司Jira工作流改造&#xff0c;收到这么一个要求&#xff1a;某些问题类型只有某些角色可以创建。本来是想通过Jira内建的权限控制来处理的。结果点到权限页面&#xff0c;心都凉透了。 好吧&#xff0c;那只能上脚本了。最终使用ScriptRunner的Simple scripte…...

Java线程的使用

Java中的线程是用来实现多任务并发执行的机制。在Java中&#xff0c;主要有两种方式来创建和使用线程&#xff1a;实现Runnable接口和继承Thread类。 实现Runnable接口&#xff1a; 创建一个类&#xff0c;实现Runnable接口&#xff0c;并重写run()方法。在run()方法中定义线程…...

自动化测试工具Ranorex Studio(四十三)-RANOREXPATH编辑器5

代码示例 下面的代码示例将讲解如何使用Ranorex API来编写代码模块&#xff0c;或者是使用用户代码来扩展录制的模块。 在代码中使用对象库 使用对象库等待UI元素 建立Adapter来访问更多的属性和方法 为对象库元素建立一组Adapter 使用Validate类 强制一个测试用例失败 设置aut…...

超高流量多级缓存架构设计!

文章内容已经收录在《面试进阶之路》&#xff0c;从原理出发&#xff0c;直击面试难点&#xff0c;实现更高维度的降维打击&#xff01; 文章目录 电商-多级缓存架构设计多级缓存架构介绍多级缓存请求流程负载均衡算法的选择轮询负载均衡一致性哈希负载均衡算法选择 应用层 Ngi…...

数据结构(Java)—— ArrayList

1.线性表 线性表&#xff08; linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列... 线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直线。但是在…...

实习冲刺第三十三天

102.二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]]示例…...

Uniapp开发下拉刷新功能onPullDownRefresh/onReachBottom

文章目录 1.onPullDownRefresh2.onReachBottom 1.onPullDownRefresh 在 js 中定义 onPullDownRefresh 处理函数&#xff08;和onLoad等生命周期函数同级&#xff09;&#xff0c;监听该页面用户下拉刷新事件。 需要在 pages.json 里&#xff0c;找到的当前页面的pages节点&am…...

什么是 C++ 中的函数对象?函数对象与普通函数有什么区别?如何定义和使用函数对象?

1) 什么是 C 中的函数对象&#xff1f;它有什么特点&#xff1f; 在 C 中&#xff0c;函数对象&#xff08;也称为仿函数或 functor&#xff09;是一种重载了 operator() 的对象。这意味着这些对象可以像函数一样被调用。函数对象通常用于需要传递行为&#xff08;即代码&…...

PointNet++论文复现

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…...

【VUE】el-table表格内输入框或者其他控件规则校验实现

1、封装组件 1、规则校验一般基于form表单实现&#xff0c;因此需要给具体控件套一层form表单 新建组件input-required.vue&#xff0c;内容如下 <template><div><el-form ref"formRef" :model"form" :rules"formRules" label-…...

django开发中html继承模板样式

存在问题&#xff1a; django开发中&#xff0c;不同页面样式相同&#xff0c;如何共用一套母版&#xff0c;避免每个页面都重复写样式&#xff1b; 解决方案&#xff1a; 添加一个母版&#xff0c;如“layout.html”&#xff0c;在需要继承的位置添加{% block content %}{% e…...

MT6769/MTK6769核心板规格参数_联发科安卓主板开发板方案

MT6769安卓核心板具有集成的蓝牙、FM、WLAN和GPS模块&#xff0c;是一个高度集成的基带平台&#xff0c;结合了调制解调器和应用处理子系统&#xff0c;以支持LTE/LTE-A和C2K智能手机应用。 该芯片集成了两个工作频率高达2.0GHz的ARMCortex-A75内核、六个工作频率高达1.70GHz的…...

【2024最新】Polars 2.0清洗效率提升417%实测报告:从default配置到生产就绪配置的7阶演进路径

第一章&#xff1a;Polars 2.0大规模数据清洗的性能跃迁本质Polars 2.0 的核心突破并非简单提速&#xff0c;而是通过内存布局重构、零拷贝计算图优化与原生并行执行引擎的深度融合&#xff0c;彻底重构了大规模数据清洗的底层范式。其性能跃迁的本质在于&#xff1a;将传统 Da…...

Python实战:利用SymPy与SciPy高效破解复杂非线性方程组

1. 为什么需要SymPy和SciPy解非线性方程组&#xff1f; 遇到工程计算或科研问题时&#xff0c;我们常需要解像这样的方程组&#xff1a;xy10且yz34。这种包含平方项、三角函数或指数函数的方程&#xff0c;传统手工计算不仅耗时还容易出错。我去年做机器人运动学分析时&#xf…...

不止是拆网卡:以联想ThinkCentre M7131z为例,聊聊老旧一体机的升级改造可能性

联想ThinkCentre M7131z改造指南&#xff1a;从拆网卡到全面性能升级 老旧商用一体机往往被贴上"性能瓶颈"的标签&#xff0c;但联想ThinkCentre M7131z系列却隐藏着令人惊喜的改造潜力。这台发布于2015年前后的商用一体机&#xff0c;凭借其模块化设计和充足的内部空…...

smart-mqtt v1.5.4发布,认证能力大升级

smart-mqtt v1.5.4正式发布&#xff0c;此次版本聚焦企业级连接认证能力升级&#xff0c;推出全新高级认证插件&#xff0c;在高性能底座上补齐企业级接入能力&#xff0c;还公布了获取方式与未来规划。版本核心亮点v1.5.4重点通过advanced-auth-plugin让连接认证更适配企业真实…...

input-overlay多语言支持:如何为全球观众轻松定制直播输入显示

input-overlay多语言支持&#xff1a;如何为全球观众轻松定制直播输入显示 【免费下载链接】input-overlay Show keyboard, gamepad and mouse input on stream 项目地址: https://gitcode.com/gh_mirrors/in/input-overlay 想要让全球观众都能轻松理解你的游戏操作吗&a…...

3D Face HRN效果验证:使用MeshLab量化评估3D重建PSNR与SSIM指标

3D Face HRN效果验证&#xff1a;使用MeshLab量化评估3D重建PSNR与SSIM指标 1. 项目背景与验证意义 3D人脸重建技术近年来取得了显著进展&#xff0c;但如何客观评估重建质量一直是个关键问题。传统的主观视觉评估方法存在明显局限性——不同观察者可能有不同的判断标准&…...

从PolarCTF一道Crypto题,聊聊如何用SageMath秒解自定义群运算的离散对数问题

从PolarCTF一道Crypto题看SageMath在离散对数问题中的实战应用 1. 密码学竞赛中的非标准群运算挑战 在CTF密码学题目中&#xff0c;自定义群运算的离散对数问题&#xff08;DLP&#xff09;是常见的高频考点。近期PolarCTF竞赛中出现了一道典型题目&#xff0c;要求参赛者在非…...

GitHub开源项目分享:SenseVoice-Small模型微调与领域适配工具链

GitHub开源项目分享&#xff1a;SenseVoice-Small模型微调与领域适配工具链 最近在语音识别领域&#xff0c;一个挺有意思的现象是&#xff0c;很多通用模型虽然能力很强&#xff0c;但一遇到专业领域的对话&#xff0c;比如医生讨论病例、律师分析法条&#xff0c;准确率就容…...

Mirage Flow 与卷积神经网络(CNN)的跨模态融合应用

Mirage Flow 与卷积神经网络&#xff08;CNN&#xff09;的跨模态融合应用 你有没有想过&#xff0c;让机器不仅能“看见”图片&#xff0c;还能像人一样“理解”并“描述”图片里的故事&#xff1f;比如&#xff0c;给一张复杂的医学影像&#xff0c;它不仅能圈出病灶&#x…...

springboot+vue基于web的网上考试系统的设计系统

目录同行可拿货,招校园代理 ,本人源头供货商系统功能模块划分题库管理模块在线考试模块自动阅卷模块技术实现要点扩展功能建议项目技术支持源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作同行可拿货,招校园代理 ,本人源头供货商 系统功能模…...