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

接口自动化测试框架(pytest+allure+aiohttp+ 用例自动生成)

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快

近期准备优先做接口测试的覆盖,为此需要开发一个测试框架,经过思考,这次依然想做点儿不一样的东西。

  • 接口测试是比较讲究效率的,测试人员会希望很快能得到结果反馈,然而接口的数量一般都很多,而且会越来越多,所以提高执行效率很有必要
  • 接口测试的用例其实也可以用来兼做简单的压力测试,而压力测试需要并发
  • 接口测试的用例有很多重复的东西,测试人员应该只需要关注接口测试的设计,这些重复劳动最好自动化来做pytest和allure太好用了,新框架要集成它们
  • 接口测试的用例应该尽量简洁,最好用yaml,这样数据能直接映射为请求数据,写起用例来跟做填空题一样,便于向没有自动化经验的成员推广 加上我对Python的协程很感兴趣,也学了一段时间,一直希望学以致用,所以http请求我决定用aiohttp来实现。 但是pytest是不支持事件循环的,如果想把它们结合还需要一番功夫。于是继续思考,思考的结果是其实我可以把整个事情分为两部分。 第一部分,读取yaml测试用例,http请求测试接口,收集测试数据。 第二部分,根据测试数据,动态生成pytest认可的测试用例,然后执行,生成测试报告。 这样一来,两者就能完美结合了,也完美符合我所做的设想。想法既定,接着 就是实现了。

第一部分(整个过程都要求是异步非阻塞的)

读取yaml测试用例

一份简单的用例模板我是这样设计的,这样的好处是,参数名和aiohttp.ClientSession().request(method,url,**kwargs)是直接对应上的,我可以不费力气的直接传给请求方法,避免各种转换,简洁优雅,表达力又强。

args:- post- /xxx/add
kwargs:-caseName: 新增xxxdata:name: ${gen_uid(10)}
validator:-json:successed: True

异步读取文件可以使用aiofiles这个第三方库,yaml_load是一个协程,可以保证主进程读取yaml测试用例时不被阻塞,通过await yaml_load()便能获取测试用例的数据

async def yaml_load(dir='', file=''):"""异步读取yaml文件,并转义其中的特殊值:param file::return:"""if dir:file = os.path.join(dir, file)async with aiofiles.open(file, 'r', encoding='utf-8', errors='ignore') as f:data = await f.read()data = yaml.load(data)# 匹配函数调用形式的语法pattern_function = re.compile(r'^\${([A-Za-z_]+\w*\(.*\))}$')pattern_function2 = re.compile(r'^\${(.*)}$')# 匹配取默认值的语法pattern_function3 = re.compile(r'^\$\((.*)\)$')def my_iter(data):"""递归测试用例,根据不同数据类型做相应处理,将模板语法转化为正常值:param data::return:"""if isinstance(data, (list, tuple)):for index, _data in enumerate(data):data[index] = my_iter(_data) or _dataelif isinstance(data, dict):for k, v in data.items():data[k] = my_iter(v) or velif isinstance(data, (str, bytes)):m = pattern_function.match(data)if not m:m = pattern_function2.match(data)if m:return eval(m.group(1))if not m:m = pattern_function3.match(data)if m:K, k = m.group(1).split(':')return bxmat.default_values.get(K).get(k)return datamy_iter(data)return BXMDict(data)

可以看到,测试用例还支持一定的模板语法,如${function}、$(a:b)等,这能在很大程度上拓展测试人员用例编写的能力

http请求测试接口

http请求可以直接用aiohttp.ClientSession().request(method,url,**kwargs),http也是一个协程,可以保证网络请求时不被阻塞,通过await http()便可以拿到接口测试数据

async def http(domain, *args, **kwargs):"""http请求处理器:param domain: 服务地址:param args::param kwargs::return:"""method, api = argsarguments = kwargs.get('data') or kwargs.get('params') or kwargs.get('json') or {}# kwargs中加入tokenkwargs.setdefault('headers', {}).update({'token': bxmat.token})# 拼接服务地址和apiurl = ''.join([domain, api])async with ClientSession() as session:async with session.request(method, url, **kwargs) as response:res = await response_handler(response)return {'response': res,'url': url,'arguments': arguments}

收集测试数据

协程的并发真的很快,这里为了避免服务响应不过来导致熔断,可以引入

async def entrace(test_cases, loop, semaphore=None):"""http执行入口:param test_cases::param semaphore::return:"""res = BXMDict()# 在CookieJar的update_cookies方法中,如果unsafe=False并且访问的是IP地址,客户端是不会更新cookie信息# 这就导致session不能正确处理登录态的问题# 所以这里使用的cookie_jar参数使用手动生成的CookieJar对象,并将其unsafe设置为Trueasync with ClientSession(loop=loop, cookie_jar=CookieJar(unsafe=True), headers={'token': bxmat.token}) as session:await advertise_cms_login(session)if semaphore:async with semaphore:for test_case in test_cases:data = await one(session, case_name=test_case)res.setdefault(data.pop('case_dir'), BXMList()).append(data)else:for test_case in test_cases:data = await one(session, case_name=test_case)res.setdefault(data.pop('case_dir'), BXMList()).append(data)return resasync def one(session, case_dir='', case_name=''):"""一份测试用例执行的全过程,包括读取.yml测试用例,执行http请求,返回请求结果所有操作都是异步非阻塞的:param session: session会话:param case_dir: 用例目录:param case_name: 用例名称:return:"""project_name = case_name.split(os.sep)[1]domain = bxmat.url.get(project_name)test_data = await yaml_load(dir=case_dir, file=case_name)result = BXMDict({'case_dir': os.path.dirname(case_name),'api': test_data.args[1].replace('/', '_'),})if isinstance(test_data.kwargs, list):for index, each_data in enumerate(test_data.kwargs):step_name = each_data.pop('caseName')r = await http(session, domain, *test_data.args, **each_data)r.update({'case_name': step_name})result.setdefault('responses', BXMList()).append({'response': r,'validator': test_data.validator[index]})else:step_name = test_data.kwargs.pop('caseName')r = await http(session, domain, *test_data.args, **test_data.kwargs)r.update({'case_name': step_name})result.setdefault('responses', BXMList()).append({'response': r,'validator': test_data.validator})return result

事件循环负责执行协程并返回结果,在最后的结果收集中,我用测试用例目录来对结果进行了分类,这为接下来的自动生成pytest认可的测试用例打下了良好的基础

def main(test_cases):"""事件循环主函数,负责所有接口请求的执行:param test_cases::return:"""loop = asyncio.get_event_loop()semaphore = asyncio.Semaphore(bxmat.semaphore)# 需要处理的任务# tasks = [asyncio.ensure_future(one(case_name=test_case, semaphore=semaphore)) for test_case in test_cases]task = loop.create_task(entrace(test_cases, loop, semaphore))# 将协程注册到事件循环,并启动事件循环try:# loop.run_until_complete(asyncio.gather(*tasks))loop.run_until_complete(task)finally:loop.close()return task.result()

第二部分

动态生成pytest认可的测试用例

首先说明下pytest的运行机制,pytest首先会在当前目录下找conftest.py文件,如果找到了,则先运行它,然后根据命令行参数去指定的目录下找test开头或结尾的.py文件,如果找到了,如果找到了,再分析fixture,如果有session或module类型的,并且参数autotest=True或标记了pytest.mark.usefixtures(a...),则先运行它们;再去依次找类、方法等,规则类似。大概就是这样一个过程。

可以看出,pytest测试运行起来的关键是,必须有至少一个被pytest发现机制认可的testxx.py文件,文件中有TestxxClass类,类中至少有一个def testxx(self)方法。

现在并没有任何pytest认可的测试文件,所以我的想法是先创建一个引导型的测试文件,它负责让pytest动起来。可以用pytest.skip()让其中的测试方法跳过。然后我们的目标是在pytest动起来之后,怎么动态生成用例,然后发现这些用例,执行这些用例,生成测试报告,一气呵成。

# test_bootstrap.py
import pytest
class TestStarter(object):def test_start(self):pytest.skip('此为测试启动方法, 不执行')

我想到的是通过fixture,因为fixture有setup的能力,这样我通过定义一个scope为session的fixture,然后在TestStarter上面标记use,就可以在导入TestStarter之前预先处理一些事情,那么我把生成用例的操作放在这个fixture里就能完成目标了。

# test_bootstrap.py
import pytest@pytest.mark.usefixtures('te', 'test_cases')
class TestStarter(object):def test_start(self):pytest.skip('此为测试启动方法, 不执行')

pytest有个--rootdir参数,该fixture的核心目的就是,通过--rootdir获取到目标目录,找出里面的.yml测试文件,运行后获得测试数据,然后为每个目录创建一份testxx.py的测试文件,文件内容就是content变量的内容,然后把这些参数再传给pytest.main()方法执行测试用例的测试,也就是在pytest内部再运行了一个pytest!最后把生成的测试文件删除。注意该fixture要定义在conftest.py里面,因为pytest对于conftest中定义的内容有自发现能力,不需要额外导入。

# conftest.py
@pytest.fixture(scope='session')
def test_cases(request):"""测试用例生成处理:param request::return:"""var = request.config.getoption("--rootdir")test_file = request.config.getoption("--tf")env = request.config.getoption("--te")cases = []if test_file:cases = [test_file]else:if os.path.isdir(var):for root, dirs, files in os.walk(var):if re.match(r'\w+', root):if files:cases.extend([os.path.join(root, file) for file in files if file.endswith('yml')])data = main(cases)content = """
import allure
from conftest import CaseMetaClass
@allure.feature('{}接口测试({}项目)')
class Test{}API(object, metaclass=CaseMetaClass):test_cases_data = {}
"""test_cases_files = []if os.path.isdir(var):for root, dirs, files in os.walk(var):if not ('.' in root or '__' in root):if files:case_name = os.path.basename(root)project_name = os.path.basename(os.path.dirname(root))test_case_file = os.path.join(root, 'test_{}.py'.format(case_name))with open(test_case_file, 'w', encoding='utf-8') as fw:fw.write(content.format(case_name, project_name, case_name.title(), data.get(root)))test_cases_files.append(test_case_file)if test_file:temp = os.path.dirname(test_file)py_file = os.path.join(temp, 'test_{}.py'.format(os.path.basename(temp)))else:py_file = varpytest.main(['-v',py_file,'--alluredir','report','--te',env,'--capture','no','--disable-warnings',])for file in test_cases_files:os.remove(file)return test_cases_files

可以看到,测试文件中有一个TestxxAPI的类,它只有一个test_cases_data属性,并没有testxx方法,所以还不是被pytest认可的测试用例,根本运行不起来。那么它是怎么解决这个问题的呢?答案就是CaseMetaClass。

function_express = """
def {}(self, response, validata):with allure.step(response.pop('case_name')):validator(response,validata)"""class CaseMetaClass(type):"""根据接口调用的结果自动生成测试用例"""def __new__(cls, name, bases, attrs):test_cases_data = attrs.pop('test_cases_data')for each in test_cases_data:api = each.pop('api')function_name = 'test' + apitest_data = [tuple(x.values()) for x in each.get('responses')]function = gen_function(function_express.format(function_name),namespace={'validator': validator, 'allure': allure})# 集成allurestory_function = allure.story('{}'.format(api.replace('_', '/')))(function)attrs[function_name] = pytest.mark.parametrize('response,validata', test_data)(story_function)return super().__new__(cls, name, bases, attrs)

CaseMetaClass是一个元类,它读取test_cases_data属性的内容,然后动态生成方法对象,每一个接口都是单独一个方法,在相继被allure的细粒度测试报告功能和pytest提供的参数化测试功能装饰后,把该方法对象赋值给test+api的类属性,也就是说,TestxxAPI在生成之后便有了若干testxx的方法,此时内部再运行起pytest,pytest也就能发现这些用例并执行了。

def gen_function(function_express, namespace={}):"""动态生成函数对象, 函数作用域默认设置为builtins.__dict__,并合并namespace的变量:param function_express: 函数表达式,示例 'def foobar(): return "foobar"':return:"""builtins.__dict__.update(namespace)module_code = compile(function_express, '', 'exec')function_code = [c for c in module_code.co_consts if isinstance(c, types.CodeType)][0]return types.FunctionType(function_code, builtins.__dict__)

在生成方法对象时要注意namespace的问题,最好默认传builtins.__dict__,然后自定义的方法通过namespace参数传进去。

后续(yml测试文件自动生成)

至此,框架的核心功能已经完成了,经过几个项目的实践,效果完全超过预期,写起用例来不要太爽,运行起来不要太快,测试报告也整的明明白白漂漂亮亮的,但我发现还是有些累,为什么呢?
我目前做接口测试的流程是,如果项目集成了swagger,通过swagger去获取接口信息,根据这些接口信息来手工起项目创建用例。这个过程很重复很繁琐,因为我们的用例模板已经大致固定了,其实用例之间就是一些参数比如目录、用例名称、method等等的区别,那么这个过程我觉得完全可以自动化。

因为swagger有个网页啊,我可以去提取关键信息来自动创建.yml测试文件,就像搭起架子一样,待项目架子生成后,我再去设计用例填传参就可以了。

于是我试着去解析请求swagger首页得到的HTML,然后失望的是并没有实际数据,后来猜想应该是用了ajax,打开浏览器控制台的时,我发现了api-docs的请求,一看果然是json数据,那么问题就简单了,网页分析都不用了。

import re
import os
import sysfrom requests import Sessiontemplate ="""
args:- {method}- {api}
kwargs:-caseName: {caseName}{data_or_params}:{data}
validator:-json:successed: True
"""def auto_gen_cases(swagger_url, project_name):"""根据swagger返回的json数据自动生成yml测试用例模板:param swagger_url::param project_name::return:"""res = Session().request('get', swagger_url).json()data = res.get('paths')workspace = os.getcwd()project_ = os.path.join(workspace, project_name)if not os.path.exists(project_):os.mkdir(project_)for k, v in data.items():pa_res = re.split(r'[/]+', k)dir, *file = pa_res[1:]if file:file = ''.join([x.title() for x in file])else:file = dirfile += '.yml'dirs = os.path.join(project_, dir)if not os.path.exists(dirs):os.mkdir(dirs)os.chdir(dirs)if len(v) > 1:v = {'post': v.get('post')}for _k, _v in v.items():method = _kapi = kcaseName = _v.get('description')data_or_params = 'params' if method == 'get' else 'data'parameters = _v.get('parameters')data_s = ''try:for each in parameters:data_s += each.get('name')data_s += ': \n'data_s += ' ' * 8except TypeError:data_s += '{}'file_ = os.path.join(dirs, file)with open(file_, 'w', encoding='utf-8') as fw:fw.write(template.format(method=method,api=api,caseName=caseName,data_or_params=data_or_params,data=data_s))os.chdir(project_)

现在要开始一个项目的接口测试覆盖,只要该项目集成了swagger,就能秒生成项目架子,测试人员只需要专心设计接口测试用例即可,我觉得对于测试团队的推广使用是很有意义的,也更方便了我这样的懒人。

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

这些资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!凡事要趁早,特别是技术行业,一定要提升技术功底。

相关文章:

接口自动化测试框架(pytest+allure+aiohttp+ 用例自动生成)

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 近期准备优先做接口测试的覆盖,为此需要开发一个测试框架,经过思考,这次依然想做点儿不一样的东西。 接口测试是比较讲究效率的…...

FastAPI在 Nginx 和 Docker 环境中的部署

目录 实现示例1. 项目结构2. FastAPI 应用 (app/main.py)3. 依赖文件 (app/requirements.txt)4. Dockerfile5. Nginx 配置 (nginx/nginx.conf)6. Docker Compose 配置 (docker-compose.yml) 使用方法修改代码后更新 实现示例 接下来创建一个简单的示例项目,展示如何…...

08 接口自动化-用例管理框架pytest之fixtrue,conftest.py,allure报告以及logo定制

文章目录 一、使用fixture实现部分前后置1.function级别:在每个函数的前后执行2.class级别:在每个类的前后执行一次3.module级别:在每个模块的前后执行一次4.package、session级别,一般是和connftest.py文件一起使用 二、当fixture的级别为pa…...

Appium+python自动化(二)- 环境搭建—下

简介 我这里已经将android的测试开发环境已经搭建准备完毕。上一篇android测试开发环境已经准备好, 那么接下来就是appium的环境安装和搭建了。 搭建环境安装过程中切勿浮躁,静下心来一个一个慢慢地按照步骤一个个来。 环境装好后,可以用真机…...

浅谈测试驱动开发TDD

目录 1.什么是TDD 2.TDD步骤 3.TDD 的核心原则 4.TDD 与传统开发的对比 5.TDD中的单元测试和集成测试区别 6.总结 1.什么是TDD 测试驱动开发(Test-Driven Development,简称 TDD) 是一种软件开发方法论,核心思想是 “先写测试…...

MVC和MVVM架构的区别

MVC和MVVM都是前端开发中常用的设计模式,都是为了解决前端开发中的复杂性而设计的,而MVVM模式则是一种基于MVC模式的新模式。 MVC(Model-View-Controller)的三个核心部分:模型、视图、控制器相较于MVVM(Model-View-ViewModel)的三个核心部分…...

网络安全-等级保护(等保) 3-1-1 GB/T 28448-2019 附录A (资料性附录)测评力度附录C(规范性附录)测评单元编号说明

附录A (资料性附录)测评力度 A.1 概述 测评力度是在等级测评过程中实施测评工作的力度,体现为测评工作的实际投入程度,具体由测评的广度和深度来反映。测评广度越大,测评实施的范围越大,测评实施包含的测评对象就越多。测评深度…...

MySQL 可观测性最佳实践

MySQL 简介 MySQL 是一个广泛使用的开源关系型数据库管理系统(RDBMS),以其高性能、可靠性和易用性而闻名,适用于各种规模的应用,从小型网站到大型企业级系统。 监控 MySQL 指标是维护数据库健康、优化性能和确保数据…...

深入解析Spring Boot与Redis集成:高效缓存与性能优化

深入解析Spring Boot与Redis集成:高效缓存与性能优化 引言 在现代Web应用中,缓存技术是提升系统性能的重要手段之一。Redis作为一种高性能的内存数据库,广泛应用于缓存、会话管理和消息队列等场景。本文将详细介绍如何在Spring Boot项目中集…...

《C 语言字符串操作从入门到实战(下篇):strncpy/strncat/strstr 等函数原理与实现》

目录 七. strncpy函数的使用与模拟实现 7.1 strncpy函数理解 7.2 strncpy函数使用示例 7.3 strncpy函数模拟实现 八. strncat函数的使用与模拟实现 8.1 strncat函数理解 8.2 strncat函数使用示例 8.3 strncat函数模拟实现 九. strncmp函数的使用 9.1 strncmp函数理…...

百度智能云千帆AppBuilder RAG流程技术文档

一、概述 本文档旨在详细阐述百度智能云千帆AppBuilder的RAG(Retrieval-Augmented Generation,检索增强生成)流程,包括API对接、知识库维护以及文档资料管理等关键环节。通过本流程,开发者可以高效地构建基于大模型的…...

程序编辑器快捷键总结

程序编辑器快捷键总结 函数跳转 函数跳转 Creator : F2VSCode : F12visual Studio : F12...

MySQL中实现大数据量的快速插入

一、SQL语句优化​ 1. ​批量插入代替单条插入​ ​单条插入会频繁触发事务提交和日志写入,效率极低。​批量插入通过合并多条数据为一条SQL语句,减少网络传输和SQL解析开销。 -- 低效写法:逐条插入 INSERT INTO table (col1, col2) VALUE…...

从零基础到最佳实践:Vue.js 系列(8/10):《性能优化与最佳实践》

引言 Vue.js 是一个轻量、灵活且易于上手的现代前端框架,因其响应式数据绑定和组件化开发而广受欢迎。然而,随着项目规模的增长,性能问题逐渐显现,例如首屏加载缓慢、页面渲染卡顿、内存占用过高等。性能优化不仅能提升用户体验&…...

欧拉降幂(JAVA)蓝桥杯乘积幂次

这个题可以使用欧拉降幂,1000000007是质数,所以欧拉函数值为1000000006. import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {Scanner scanner new Scanner(System…...

Mysql的MVCC机制

MySQL的MVCC机制主要通过以下几个关键要素来工作: 数据版本与隐藏列 - MySQL InnoDB存储引擎会在每行数据中添加几个隐藏列,用于实现MVCC。其中包括 DB_TRX_ID 列,记录最后一次修改该行数据的事务ID; DB_ROLL_PTR 列&#xff…...

spring中的BeanFactoryAware接口详解

一、接口定义与核心作用 BeanFactoryAware 是 Spring 框架提供的一个回调接口,允许 Bean 在初始化阶段获取其所属的 BeanFactory 实例。该接口定义如下: public interface BeanFactoryAware {void setBeanFactory(BeanFactory beanFactory) throws Bea…...

mysql 创建用户,创建数据库,授权

创建一个远程用户 create user test% identified by test1111; 创建一个数据库并指定编码 create database testdb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; 授权 grant all privileges on testdb.* to test%; 应用更改: FLUSH PRIVILEGES; 注意…...

Android 网络全栈攻略(三)—— 从三方库原理来看 HTTP

前面两篇文章我们介绍了 HTTP 协议的请求方法、请求码以及常用的请求头/响应头的知识。本篇会从 OkHttp 配置的角度来看这些框架是如何实现 HTTP 协议的,目的是加深对 HTTP 的理解,并学习协议是如何落地的。我们会选取 OkHttp 中与协议实现相关的源码作为…...

BlazeMeter录制jmeter脚本

文章目录 chrome安装blazeMeter插件开始录制 chrome安装blazeMeter插件 开始录制 1、点击重置按钮 2、输入名称 3、点击开始录制 4、打开浏览器操作 5、回到录制页面点击stop(注意,不要在第四步操作的那个窗口点停止) 6、点击save 7、保存jmeter脚本 8、将jmeter脚…...

SQL的RAND用法和指定生成随机数的范围

SQL中的RAND函数能够满足多种随机数生成的需求。通过合理地使用种子、结合一些SQL语句,我们可以实现灵活的随机数生成。在数据填充、数据处理、数据分析中经常需要用RAND生成的随机数。 用法1 生成随机浮点数,其返回值在0(包括0)…...

PHP7内核剖析 学习笔记 第七章 面向对象

面向对象编程,简称OOP,是一种程序设计思想。面向对象把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。面向对象一直是软件开发领域内比较热门的话题,它更符合人类看待事物的一般规律。与Java不同,PHP并…...

地信GIS专业关于学习、考研、就业方面的一些问题答疑

整理了地信GIS专业学生问得最多的几个问题:关于GIS专业学习、考研以及就业方面;大家可以一起来探讨一下。 学习方面 1、 作为一名GISer需要哪些核心素养或能力? 答:GIS是个交叉学科,涉及到地理学、地质学、测绘、遥感…...

构建可重复的系统 - SRE 的 IaC 与 CI/CD 基础

构建可重复的系统 - SRE 的 IaC 与 CI/CD 基础 还记得我们在第一篇提到的 SRE 核心原则之一——减少琐事 (Toil) 吗?想象一下手动配置服务器、部署应用程序、管理网络规则……这些任务不仅耗时、重复,而且极易出错。当系统规模扩大时,手动操作很快就会变得难以为继。SRE 的核…...

CQF预备知识:一、微积分 —— 1.2.2 函数f(x)的类型详解

文中内容仅限技术学习与代码实践参考,市场存在不确定性,技术分析需谨慎验证,不构成任何投资建议。 📖 数学入门全解 本教程为复习课程,旨在帮助读者复习数学知识。教程涵盖以下四个主题: 微积分线性代数微…...

PyQt学习系列03-动画与过渡效果

PyQt学习系列笔记(Python Qt框架) 第三课:PyQt的动画与过渡效果 一、动画与过渡效果概述 1.1 动画与过渡的区别 动画(Animation):用于描述对象属性随时间变化的过程(如位置、颜色、大小&…...

偏微分方程数值方法指南及AI推理

偏微分方程(PDE)是我们用来描述科学、工程和金融领域中各种现象的语言——从流体流动和热传递到波的传播和金融衍生品的定价。然而,这些方程的解析解通常难以获得,尤其是在处理复杂几何形状或非线性行为时。这时,数值方…...

flask允许跨域访问如何设置

flask允许跨域访问 在Flask中,允许跨域访问通常涉及到CORS(跨源资源共享)策略。Flask本身并不直接提供CORS支持,但你可以通过安装和使用第三方库如Flask-CORS来轻松实现跨域资源共享。 安装Flask-CORS 首先,你需要安装Flask-CORS。你可以使用pip来安装它: pip instal…...

深度学习模型部署:使用Flask将图像分类(5类)模型部署在服务器上,然后在本地GUI调用。(全网模型部署项目步骤详解:从模型训练到部署再到调用)

个人github对应项目链接: https://github.com/KLWU07/Image-classification-and-model-deployment 1.流程总览 2.图像分类的模型—Alexnet 3.服务器端部署及运行 4.本地PyCharm调用—GUI界面 一、流程总览 本项目方法还是使用Flask 库,与之前一篇机器学…...

在Pycharm中如何安装Flask

(推荐)方法一:在Pycharm中创建项目之后,再安装Flask 1:在创建Pycharm时,解释器类型选择第一个:项目venv(自动生成的虚拟环境),在左下角选择终端(…...

基于Scikit-learn与Flask的医疗AI糖尿病预测系统开发实战

引言 在精准医疗时代,人工智能技术正在重塑临床决策流程。本文将深入解析如何基于MIMIC-III医疗大数据集,使用Python生态构建符合医疗AI开发规范的糖尿病预测系统。项目涵盖从数据治理到模型部署的全流程,最终交付符合DICOM标准的临床决策支…...

解决前端路由切换导致Keycloak触发页面刷新问题

使用window.location.href进行页面跳转时,浏览器会完全刷新页面,这会导致当前的JavaScript上下文被清空。 如果你的登录状态依赖于某些临时存储(如LocalStorage或sessionStorage),而这些存储在页面刷新后未正确初始化或丢失,就会导致用户被认为未登录。触发keycloak再次登录导…...

基于大模型的胫腓骨干骨折全周期预测与治疗方案研究报告

目录 一、引言 1.1 研究背景与意义 1.2 研究目的与创新点 1.3 国内外研究现状 二、大模型技术原理与应用基础 2.1 大模型的基本架构与算法 2.2 医疗数据的收集与预处理 2.2.1 数据收集 2.2.2 数据预处理 2.3 模型训练与优化 2.3.1 模型训练过程 2.3.2 参数调整与超…...

智慧交通的核心引擎-车牌识别接口-车牌识别技术-新能源车牌识别

在数字化与智能化浪潮席卷交通运输领域的今天,车牌识别接口功能正以其精准、高效的特性,成为构建智慧交通体系的关键技术支撑。通过自动采集、识别车牌信息并实现数据互通,该功能已被深度融入交通管理、物流运输、出行服务等多个场景&#xf…...

小白的进阶之路系列之三----人工智能从初步到精通pytorch计算机视觉详解上

计算机视觉是教计算机看东西的艺术。 例如,它可能涉及构建一个模型来分类照片是猫还是狗(二元分类)。 或者照片是猫、狗还是鸡(多类分类)。 或者识别汽车出现在视频帧中的位置(目标检测)。 或者找出图像中不同物体可以被分离的位置(全视分割)。 计算机视觉应用在…...

手写简单的tomcat

首先,Tomcat是一个软件,所有的项目都能在Tomcat上加载运行,Tomcat最核心的就是Servlet集合,本身就是HashMap。Tomcat需要支持Servlet,所以有servlet底层的资源:HttpServlet抽象类、HttpRequest和HttpRespon…...

院校机试刷题第九天:P1042乒乓球、回顾代码随想录第二天

定位一下刷题计划:刷题全面——代码随想录过一遍,刷到模拟题——刷洛谷普及组-。所以还是每天刷一个代码随想录,外加两道洛谷,题目先从官方题单【算法1-1】开始。 一、P1042乒乓球 1.解题思路 关键点1:输入形式 输…...

如何在 Mac M4 芯片电脑上卸载高版本的 Node.js

文章目录 一、确认 Node.js 的安装方式二、卸载 Node.js 的通用步骤1. 通过官方安装包(.pkg)安装的 Node.js2. 通过 Homebrew 安装的 Node.js3. 通过 nvm 安装的 Node.js 三、验证是否卸载成功四、推荐使用 nvm 管理 Node.js 版本五、常见问题1. 卸载后仍…...

基础IO详解

FILE 1.FILE是文件的用户级数据结构,创建在堆上 2.FILE里有维护一个用户级缓冲区,这个用户级缓冲区是为了减少系统调用的次数 3.进程一般会有三个标准FILE*流,stdin,stdout,stderr,对应文件描述符一般是…...

QT入门基础

QT作为一个C的GUI框架,编程语法和C都差不多,上手还是比较快的。但是学习一个新的技术,总有一些新的概念是不清楚的,所以需要先了解一下这些概念。 1、QT软件系 QT:安装时会指定某个版本的QT,这个QT指QT库…...

【TI MSP430与SD NAND:心电监测的长续航解决方案】

在医疗科技飞速发展的今天,心电监测设备已成为守护人们心脏健康的关键防线。而在这一领域,Nordic、TI、ST、NXP 等行业巨头凭借其深厚的技术积累和创新精神,推出的主芯片与 SD NAND 存储组合方案,正引领着心电监测技术的变革&…...

中医方剂 - 理中汤

理中汤是中医经典方剂,出自《伤寒论》,由人参(或党参)、干姜、白术、炙甘草四味药组成。 一、核心功效与作用机理 1. 温中散寒(核心作用) 表现:脘腹冷痛、呕吐清水、腹泻完谷不化 现代对应&a…...

遨游三防科普:三防平板是什么?有什么特殊功能?

在极端环境作业与专业领域应用中,传统消费级电子设备往往因环境适应性不足而“折戟沉沙”。三防平板的诞生,正是为破解这一难题而生,它通过军用级防护标准与专业化功能设计,成为工业巡检、地质勘探、应急救援等场景的核心工具。所…...

关于数据仓库、数据湖、数据平台、数据中台和湖仓一体的概念和区别

我们谈论数据中台之前, 我们也听到过数据平台、数据仓库、数据湖、湖仓一体的相关概念,它们都与数据有关系,但他们和数据中台有什么样的区别, 下面我们将围绕数据平台、数据仓库、数据湖和数据中台的区别进行介绍。 一、相关概念…...

FPGA:CLB资源以及Verilog编码面积优化技巧

本文将先介绍Kintex-7系列器件的CLB(可配置逻辑块)资源,然后分享在Verilog编码时节省CLB资源的技巧。以下内容基于Kintex-7系列的架构特点,并结合实际设计经验进行阐述。 一、Kintex-7系列器件的CLB资源介绍 Kintex-7系列是Xilin…...

AUTOSAR AP 入门0:AUTOSAR_EXP_PlatformDesign.pdf

AUTOSAR AP官网:AUTOSAR Adaptive Platform设计AUTOSAR AP的目的,翻译版官方文档 AUTOSAR_EXP_PlatformDesign.pdf : https://mp.weixin.qq.com/s?__bizMzg2MzAyMDIzMQ&mid2247553050&idx2&sn786c3a1f153acf99b723bf4c9832acaf …...

WPF 常见坑:ContentControl 不绑定 Content 时,命令为何失效?

WPF 中的 Content“{Binding}” 到底有多重要?一次被忽视的绑定导致命令无法触发的案例分析 在使用 WPF 构建 UI 时,我们经常会使用 ContentControl、ItemsControl、DataTemplate 等机制进行灵活的界面布局。但很多开发者可能会在某些场景中遇到这样的问…...

【IC_Design】跨时钟域的寄存器更新后锁存

目录 设计逻辑框图场景概述总结电路使用注意事项***波形图代码 设计逻辑框图 场景概述 最典型的应用场景就是——在一个时钟域(比如 CPU/总线域)更新了一个多位配置字,需要把它安全地送到另一个时钟域(比如时钟发生器、串口、视频…...

腾讯2025年校招笔试真题手撕(三)

一、题目 今天正在进行赛车车队选拔,每一辆赛车都有一个不可以改变的速度。现在需要选取速度差距在10以内的车队(车队中速度的最大值减去最小值不大于10),用于迎宾。车队的选拔按照的是人越多越好的原则,给出n辆车的速…...

leetcode 83和84 Remove Duplicates from Sorted List 和leetcode 1836

目录 83. Remove Duplicates from Sorted List 82. Remove Duplicates from Sorted List II 1836. Remove Duplicates From an Unsorted Linked List 删除链表中的结点合集 83. Remove Duplicates from Sorted List 代码: /*** Definition for singly-linked l…...