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

python+requests实现的接口自动化测试

点击文末小卡片免费获取软件测试全套资料资料在手涨薪更快框架详细教程前段时间由于公司测试方向的转型由原来的web页面功能测试转变成接口测试之前大多都是手工进行利用postman和jmeter进行的接口测试后来组内有人讲原先web自动化的测试框架移驾成接口的自动化框架使用的是java语言但对于一个学java却在学python的我来说觉得python比起java更简单些所以我决定自己写python的接口自动化测试框架由于本人也是刚学习python这套自动化框架目前已经基本完成了于是进行一些总结便于以后回顾温习有许多不完善的地方也遇到了许多的问题希望大神们多多指教。下面我就进行今天的主要内容吧。初学者的成功之路哈哈哈~~1、首先我们先来理一下思路。正常的接口测试流程是什么脑海里的反应是不是这样的确定测试接口的工具 — 配置需要的接口参数 — 进行测试 — 检查测试结果有的需要数据库辅助 — 生成测试报告html报告那么我们就根据这样的过程来一步步搭建我们的框架。在这个过程中我们需要做到业务和数据的分离这样才能灵活达到我们写框架的目的。只要好好做一定可以成功。这也是我当初对自己说的。接下来我们来进行结构的划分。我的结构是这样的大家可以参考下​​​​​​ common存放一些共通的方法result执行过程中生成的文件夹里面存放每次测试的结果testCase用于存放具体的测试casetestFile存放测试过程中用到的文件包括上传的文件测试用例以及 数据库的sql语句caselisttxt文件配置每次执行的case名称config配置一些常量例如数据库的相关信息接口的相关信息等readConfig 用于读取config配置文件中的内容runAll用于执行case既然整体结构有了划分接下来就该一步步的填充整个框架了首先我们先来看看config.ini和readConfig.py两个文件从他们入手个人觉得比较容易走下去哒。我们来看下文件的内容是什么样子的[DATABASE] host 50.23.190.57 username xxxxxx password ****** port 3306 database databasename [HTTP] # 接口的url baseurl http://xx.xxxx.xx port 8080 timeout 1.0 [EMAIL] mail_host smtp.163.com mail_user xxx163.com mail_pass ********* mail_port 25 sender xxx163.com receiver xxxxqq.com/xxxxqq.com subject python content All interface test has been complited\nplease read the report file about the detile of result in the attachment. testuser Someone on_off 1相信大家都知道这样的配置文件没错所有一成不变的东西我们都可以放到这里来。哈哈怎么样不错吧。现在我们已经做好了固定的“仓库”。来保存我们平时不动的东西那么我们要怎么把它拿出来为我所用呢这时候readConfig.py文件出世了它成功的帮我们解决了这个问题下面就让我们来一睹它的庐山真面目吧。import os import codecs import configparser proDir os.path.split(os.path.realpath(__file__))[0] configPath os.path.join(proDir, config.ini) class ReadConfig: def __init__(self): fd open(configPath) data fd.read() # remove BOM if data[:3] codecs.BOM_UTF8: data data[3:] file codecs.open(configPath, w) file.write(data) file.close() fd.close() self.cf configparser.ConfigParser() self.cf.read(configPath) def get_email(self, name): value self.cf.get(EMAIL, name) return value def get_http(self, name): value self.cf.get(HTTP, name) return value def get_db(self, name): value self.cf.get(DATABASE, name) return value怎么样是不是看着很简单啊我们定义的方法根据名称取对应的值是不是so easy当然了这里我们只用到了get方法还有其他的例如set方法有兴趣的同学可以自己去探索下。话不多说我们先来看下common到底有哪些东西。既然配置文件和读取配置文件我们都已经完成了也看到了common里的内容接下来就可以写common里的共通方法了从哪个下手呢今天我们就来翻“Log.py”的牌吧因为它是比较独立的我们单独跟他打交道也为了以后它能为我们服务打下良好基础。这里呢我想跟大家多说两句对于这个log文件呢我给它单独启用了一个线程这样在整个运行过程中我们在写log的时候也会比较方便看名字大家也知道了这里就是我们对输出的日志的所有操作了主要是对输出格式的规定输出等级的定义以及其他一些输出的定义等等。总之你想对log做的任何事情都可以放到这里来。我们来看下代码没有比这个更直接有效的了。import logging from datetime import datetime import threading首先我们要像上面那样引入需要的模块才能进行接下来的操作。class Log: def __init__(self): global logPath, resultPath, proDir proDir readConfig.proDir resultPath os.path.join(proDir, result) # create result file if it doesnt exist if not os.path.exists(resultPath): os.mkdir(resultPath) # defined test result file name by localtime logPath os.path.join(resultPath, str(datetime.now().strftime(%Y%m%d%H%M%S))) # create test result file if it doesnt exist if not os.path.exists(logPath): os.mkdir(logPath) # defined logger self.logger logging.getLogger() # defined log level self.logger.setLevel(logging.INFO) # defined handler handler logging.FileHandler(os.path.join(logPath, output.log)) # defined formatter formatter logging.Formatter(%(asctime)s - %(name)s - %(levelname)s - %(message)s) # defined formatter handler.setFormatter(formatter) # add handler self.logger.addHandler(handler)现在我们创建了上面的Log类在__init__初始化方法中我们进行了log的相关初始化操作。具体的操作内容注释已经写得很清楚了英文有点儿差大家看得懂就行嘿嘿……这样log的基本格式已经定义完成了至于其他的方法就靠大家自己发挥了毕竟每个人的需求也不同我们就只写普遍的共用方法啦。接下来就是把它放进一个线程内了请看下面的代码class MyLog: log None mutex threading.Lock() def __init__(self): pass staticmethod def get_log(): if MyLog.log is None: MyLog.mutex.acquire() MyLog.log Log() MyLog.mutex.release() return MyLog.log看起来是不是没有想象中的那样复杂啊哈哈哈就是这样简单python比java简单了许多这也是我为什么选择它的原因虽然小编我也是刚刚学习还有很多不懂的地方。下面我们继续搭建这次要做的是configHttp.py的内容。没错我们开始配置接口文件啦终于写到接口了是不是很开心啊~下面是接口文件中主要部分的内容让我们一起来看看吧。import requests import readConfig as readConfig from common.Log import MyLog as Log localReadConfig readConfig.ReadConfig() class ConfigHttp: def __init__(self): global host, port, timeout host localReadConfig.get_http(baseurl) port localReadConfig.get_http(port) timeout localReadConfig.get_http(timeout) self.log Log.get_log() self.logger self.log.get_logger() self.headers {} self.params {} self.data {} self.url None self.files {} def set_url(self, url): self.url host url def set_headers(self, header): self.headers header def set_params(self, param): self.params param def set_data(self, data): self.data data def set_files(self, file): self.files file # defined http get method def get(self): try: response requests.get(self.url, paramsself.params, headersself.headers, timeoutfloat(timeout)) # response.raise_for_status() return response except TimeoutError: self.logger.error(Time out!) return None # defined http post method def post(self): try: response requests.post(self.url, headersself.headers, dataself.data, filesself.files, timeoutfloat(timeout)) # response.raise_for_status() return response except TimeoutError: self.logger.error(Time out!) return None这里我们就挑重点来说吧。首先可以看到小编这次是用python自带的requests来进行接口测试的相信有心的朋友已经看出来了pythonrequests这个模式是很好用的它已经帮我们封装好了测试接口的方法用起来很方便。这里呢我就拿get和post两个方法来说吧。平时用的最多的就是这两个方法了其他方法大家可以仿照着自行扩展get方法接口测试中见到最多的就是get方法和post方法其中get方法用于获取接口的测试说白了就是说使用get的接口都不会对后台数据进行更改而且get方法在传递参数后url的格式是这样的http://接口地址?key1value1key2value2是不是看起来很眼熟啊~反正我看着它很眼熟~\(≧▽≦)/~啦啦啦那我们要怎么使用它呢请继续往下看。对于requests提供的get方法有几个常用的参数url显而易见就是接口的地址url啦headers定制请求头headers例如content-type application/x-www-form-urlencodedparams用于传递测试接口所要用的参数这里我们用python中的字典形式keyvalue进行参数的传递。timeout设置接口连接的最大时间超过该时间会抛出超时错误现在各个参数我们已经知道是什么意思了剩下的就是往里面填值啦是不是机械式的应用啊哈哈小编我就是这样机械般的学习的啦~举个栗子url‘http://api.shein.com/v2/member/logout’ header{‘content-type’ application/x-www-form-urlencoded} param{‘user_id’ 123456,‘email’ 123456163.com} timeout0.5 requests.geturl, headersheader, paramsparam, timeouttimeoutpost方法与get方法类似只要设置好对应的参数就可以了。下面就直接举个栗子直接上代码吧url‘http://api.shein.com/v2/member/login’ header{‘content-type’ application/x-www-form-urlencoded} data{‘email’ 123456163.com,‘password’ 123456} timeout0.5 requests.posturl, headersheader, datadata, timeouttimeout怎么样是不是也很简单啊。这里我们需要说明一下post方法中的参数我们不在使用params进行传递而是改用data进行传递了。哈哈哈终于说完啦下面我们来探了讨解下接口的返回值。依然只说常用的返回值的操作。text获取接口返回值的文本格式json()获取接口返回值的json()格式status_code返回状态码成功为200headers返回完整的请求头信息headers[name]返回指定的headers内容encoding返回字符编码格式url返回接口的完整url地址以上这些就是常用的方法啦大家可自行取之。关于失败请求抛出异常我们可以使用“raise_for_status()”来完成那么当我们的请求发生错误时就会抛出异常。在这里提醒下各位朋友如果你的接口在地址不正确的时候会有相应的错误提示有时也需要进行测试这时千万不能使用这个方法来抛出错误因为python自己在链接接口时就已经把错误抛出那么后面你将无法测试期望的内容。而且程序会直接在这里当掉以错误来计。别问我怎么知道的因为我就是测试的时候发现的好了。接口文件也讲完了是不是感觉离成功不远了呢嗯如果各位已经看到了这里那么恭喜大家下面还有很长的路要走~哈哈哈就是这么任性。毕竟小编我为了让各位和我差不多的小白能够更容易理解也是使出了体内的洪荒之力啦慢慢地长叹一口气继续下面的内容。。。快我想学看习看common.py里的内容。import os from xlrd import open_workbook from xml.etree import ElementTree as ElementTree from common.Log import MyLog as Log localConfigHttp configHttp.ConfigHttp() log Log.get_log() logger log.get_logger() # 从excel文件中读取测试用例 def get_xls(xls_name, sheet_name): cls [] # get xls files path xlsPath os.path.join(proDir, testFile, xls_name) # open xls file file open_workbook(xlsPath) # get sheet by name sheet file.sheet_by_name(sheet_name) # get one sheets rows nrows sheet.nrows for i in range(nrows): if sheet.row_values(i)[0] ! ucase_name: cls.append(sheet.row_values(i)) return cls # 从xml文件中读取sql语句 database {} def set_xml(): if len(database) 0: sql_path os.path.join(proDir, testFile, SQL.xml) tree ElementTree.parse(sql_path) for db in tree.findall(database): db_name db.get(name) # print(db_name) table {} for tb in db.getchildren(): table_name tb.get(name) # print(table_name) sql {} for data in tb.getchildren(): sql_id data.get(id) # print(sql_id) sql[sql_id] data.text table[table_name] sql database[db_name] table def get_xml_dict(database_name, table_name): set_xml() database_dict database.get(database_name).get(table_name) return database_dict def get_sql(database_name, table_name, sql_id): db get_xml_dict(database_name, table_name) sql db.get(sql_id) return sql上面就是我们common的两大主要内容了什么还不知道是什么吗让我告诉你吧。我们利用xml.etree.Element来对xml文件进行操作然后通过我们自定义的方法根据传递不同的参数取得不想同要的值。利用xlrd来操作excel文件注意啦我们是用excel文件来管理测试用例的。听起来会不会有点儿懵小编刚学时也很懵看文件就好理解了。excel文件xml文件至于具体的方法我就不再一点点讲解了总觉得大家都懂小编刚学望谅解只是我个人需要详细记录以后容易温习。接下来我们看看数据库和发送邮件吧也可根据需要不写该部分内容先看老朋友“数据库”吧。小编这次使用的是MySQL数据库所以我们就以它为例吧。import pymysql import readConfig as readConfig from common.Log import MyLog as Log localReadConfig readConfig.ReadConfig() class MyDB: global host, username, password, port, database, config host localReadConfig.get_db(host) username localReadConfig.get_db(username) password localReadConfig.get_db(password) port localReadConfig.get_db(port) database localReadConfig.get_db(database) config { host: str(host), user: username, passwd: password, port: int(port), db: database } def __init__(self): self.log Log.get_log() self.logger self.log.get_logger() self.db None self.cursor None def connectDB(self): try: # connect to DB self.db pymysql.connect(**config) # create cursor self.cursor self.db.cursor() print(Connect DB successfully!) except ConnectionError as ex: self.logger.error(str(ex)) def executeSQL(self, sql, params): self.connectDB() # executing sql self.cursor.execute(sql, params) # executing by committing to DB self.db.commit() return self.cursor def get_all(self, cursor): value cursor.fetchall() return value def get_one(self, cursor): value cursor.fetchone() return value def closeDB(self): self.db.close() print(Database closed!)这就是完整的数据库的文件啦。因为小编的需求对数据库的操作不是很复杂所以这些已基本满足要求啦。注意下啦在此之前请朋友们先把pymysql装起来pymysql装起来pymysql装起来重要的事情说三遍安装的方法很简单由于小编是使用pip来管理python包安装的所以只要进入python安装路径下的pip文件夹下执行以下命令即可pip install pymysql哈哈哈这样我们就可以利用python链接数据库啦~鼓个掌庆祝下小伙伴们发现没在整个文件中我们并没有出现具体的变量值哦为什么呢没错因为前面我们写了config.ini文件所有的数据库配置信息都在这个文件内哦是不是感觉很方便呢以后就算变更数据库了也只要修改config.ini文件的内容就可以了结合前面测试用例的管理excel文件sql语句的存放xml文件还有接下来我们要说的businessCommon.py和存放具体case的文件夹那么我们就已经将数据和业务分开啦哈哈哈想想以后修改测试用例内容sql语句神马的工作再也不用每个case都修改只要改几个固定的文件是不是顿时开心了呢嗯想笑就大声的笑吧回归上面的configDB.py文件内容很简单相信大家都能看得懂就是连接数据库执行sql获取结果最后关闭数据库没有什么不一样的地方。该谈谈邮件啦你是不是也遇到过这样的问题每次测试完之后都需要给开发一份测试报告。那么对于我这样的懒人是不愿意老是找人家开发的所以我就想每次测试完我们可以让程序自己给开发人员发一封email告诉他们测试已经结束了并且把测试报告以附件的形式通过email发送给开发者的邮箱这样岂不是爽哉所以configEmail.py应运而生。当当当当……请看import os import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from datetime import datetime import threading import readConfig as readConfig from common.Log import MyLog import zipfile import glob localReadConfig readConfig.ReadConfig() class Email: def __init__(self): global host, user, password, port, sender, title, content host localReadConfig.get_email(mail_host) user localReadConfig.get_email(mail_user) password localReadConfig.get_email(mail_pass) port localReadConfig.get_email(mail_port) sender localReadConfig.get_email(sender) title localReadConfig.get_email(subject) content localReadConfig.get_email(content) self.value localReadConfig.get_email(receiver) self.receiver [] # get receiver list for n in str(self.value).split(/): self.receiver.append(n) # defined email subject date datetime.now().strftime(%Y-%m-%d %H:%M:%S) self.subject title date self.log MyLog.get_log() self.logger self.log.get_logger() self.msg MIMEMultipart(mixed) def config_header(self): self.msg[subject] self.subject self.msg[from] sender self.msg[to] ;.join(self.receiver) def config_content(self): content_plain MIMEText(content, plain, utf-8) self.msg.attach(content_plain) def config_file(self): # if the file content is not null, then config the email file if self.check_file(): reportpath self.log.get_result_path() zippath os.path.join(readConfig.proDir, result, test.zip) # zip file files glob.glob(reportpath \*) f zipfile.ZipFile(zippath, w, zipfile.ZIP_DEFLATED) for file in files: f.write(file) f.close() reportfile open(zippath, rb).read() filehtml MIMEText(reportfile, base64, utf-8) filehtml[Content-Type] application/octet-stream filehtml[Content-Disposition] attachment; filenametest.zip self.msg.attach(filehtml) def check_file(self): reportpath self.log.get_report_path() if os.path.isfile(reportpath) and not os.stat(reportpath) 0: return True else: return False def send_email(self): self.config_header() self.config_content() self.config_file() try: smtp smtplib.SMTP() smtp.connect(host) smtp.login(user, password) smtp.sendmail(sender, self.receiver, self.msg.as_string()) smtp.quit() self.logger.info(The test report has send to developer by email.) except Exception as ex: self.logger.error(str(ex)) class MyEmail: email None mutex threading.Lock() def __init__(self): pass staticmethod def get_email(): if MyEmail.email is None: MyEmail.mutex.acquire() MyEmail.email Email() MyEmail.mutex.release() return MyEmail.email if __name__ __main__: email MyEmail.get_email()这里就是完整的文件内容了不过可惜的是小编我遇到一个问题至今未解在这里提出希望大神给出解决办法跪求啦问题使用163免费邮箱服务器进行邮件的发送但是每次发送邮件都会被163邮件服务器退信抛出的错误码是554官方说明如下但是howeverbut……小编在整合email进本框架之前写的发送email的小demo是可以正常发送邮件的。这个问题困扰着我目前仍没有解决望大神赐教。离成功不远了简单说明下HTMLTestRunner.py文件这个文件呢也不是小编写的小编只是它的搬运工哈哈哈这个文件是从网上下载的大神写好的用于生成html格式的测试报告什么想知道生成测试报告的样子好这就满足好奇的你看上去不错吧嗯聪明的你们也可以自己去探索下这个文件修改修改变成你自己的style好了重头戏来了就是我们的runAll.py啦。请看主角登场。这是我们整个框架运行的入口上面内容完成后这是最后一步啦写完它我们的框架就算是完成了。鼓掌撒花~import unittest import HTMLTestRunner def set_case_list(self): fb open(self.caseListFile) for value in fb.readlines(): data str(value) if data ! and not data.startswith(#): self.caseList.append(data.replace(\n, )) fb.close() def set_case_suite(self): self.set_case_list() test_suite unittest.TestSuite() suite_model [] for case in self.caseList: case_file os.path.join(readConfig.proDir, testCase) print(case_file) case_name case.split(/)[-1] print(case_name.py) discover unittest.defaultTestLoader.discover(case_file, patterncase_name .py, top_level_dirNone) suite_model.append(discover) if len(suite_model) 0: for suite in suite_model: for test_name in suite: test_suite.addTest(test_name) else: return None return test_suite def run(self): try: suit self.set_case_suite() if suit is not None: logger.info(********TEST START********) fp open(resultPath, wb) runner HTMLTestRunner.HTMLTestRunner(streamfp, titleTest Report, descriptionTest Description) runner.run(suit) else: logger.info(Have no case to test.) except Exception as ex: logger.error(str(ex)) finally: logger.info(*********TEST END*********) # send test report by email if int(on_off) 0: self.email.send_email() elif int(on_off) 1: logger.info(Doesnt send report email to developer.) else: logger.info(Unknow state.)上面我贴出了runAll里面的主要部分首先我们要从caselist.txt文件中读取需要执行的case名称然后将他们添加到python自带的unittest测试集中最后执行run()函数执行测试集。关于python的unittest需要学的内容还是很多的所以这里小编就不细讲了。终于呢整个接口自动化框架已经讲完了大家是不是看明白了呢什么之前的之前贴出的目录结构中的文件还有没说到的嘿嘿相信不用小编多说大家也大概知道了剩下文件夹的作用了。嗯~思索万千还是决定简单谈谈吧。直接上图简单明了result文件夹会在首次执行case时生成并且以后的测试结果都会被保存在该文件夹下同时每次测试的文件夹都是用系统时间命名里面包含了两个文件log文件和测试报告。testCase文件夹下存放我们写的具体的测试case啦上面这些就是小编写的一些。注意喽所有的case名称都要以test开头来命名哦这是因为unittest在进行测试时会自动匹配testCase文件夹下面所有test开头的.py文件testFile文件夹下放置我们测试时用来管理测试用例的excel文件和用于数据库查询的sql语句的xml文件哦。最后就是caselist.txt文件了就让你们瞄一眼吧凡是没有被注释掉的都是要被执行的case名称啦。在这里写上你要执行的case名称就可以啦。最后感谢每一个认真阅读我文章的人礼尚往来总是要有的虽然不是什么很值钱的东西如果你用得到的话可以直接拿走这些资料对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库这个仓库也陪伴我走过了最艰难的路程希望也能帮助到你凡事要趁早特别是技术行业一定要提升技术功底。

相关文章:

python+requests实现的接口自动化测试

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 框架详细教程前段时间由于公司测试方向的转型,由原来的web页面功能测试转变成接口测试,之前大多都是手工进行,利用postman和jme…...

draw.io桌面版架构解析:基于Electron的跨平台图表编辑实现

draw.io桌面版架构解析:基于Electron的跨平台图表编辑实现 【免费下载链接】drawio-desktop Official electron build of draw.io 项目地址: https://gitcode.com/GitHub_Trending/dr/drawio-desktop draw.io桌面版是基于Electron框架构建的专业图表编辑工具…...

甲方爸爸要的PPT展示功能,我用Unity3d + Aspose.Slides搞定了(附打包避坑指南)

Unity3D与Aspose.Slides实战:高效集成PPT展示功能的完整方案 当甲方提出"在Unity项目中嵌入PPT展示"的需求时,许多开发者第一反应可能是寻找现成的插件或考虑导出为图片序列。但真正经历过项目交付的老手都知道,这两种方案要么功能…...

从零到一:三极管功放电路实战设计与关键参数剖析

1. 三极管功放电路设计基础 三极管功率放大电路是电子工程师必须掌握的核心技能之一。我第一次接触三极管功放是在大学电子设计竞赛时,当时需要驱动一个8Ω扬声器,但成品功放模块价格昂贵且参数固定,于是决定自己动手设计。三极管功放看似简单…...

从相位缠绕到高程图:InSAR干涉测量核心原理全解析

1. InSAR技术初探:从雷达回波到三维地表 第一次接触InSAR技术时,我被它神奇的能力震撼到了——居然能用卫星拍的照片算出地面的高度变化!这就像用普通相机拍两张照片,就能测量出建筑物的精确高度一样不可思议。InSAR全称是干涉合…...

STAP旁瓣干扰抑制:从原理到对抗仿真的实战解析

1. STAP技术入门:空时滤波的降噪艺术 想象一下你在嘈杂的鸡尾酒会上试图听清某个人的谈话。传统方法就像用手捂住一只耳朵(空域滤波),而STAP技术则是同时用手捂住耳朵并配合对方说话的节奏点头(空时联合滤波&#xff0…...

哔咔漫画下载器终极指南:打造个人离线漫画图书馆的简单方法

哔咔漫画下载器终极指南:打造个人离线漫画图书馆的简单方法 【免费下载链接】picacomic-downloader 哔咔漫画 picacomic pica漫画 bika漫画 PicACG 多线程下载器,带图形界面 带收藏夹,已打包exe 下载速度飞快 项目地址: https://gitcode.co…...

STC15单片机驱动LCD12864显示汉字和图片,串行接口比并行接口省多少IO口?

STC15单片机驱动LCD12864显示:串行接口如何极致节省IO资源 在嵌入式设备开发中,IO口资源常常成为制约功能扩展的瓶颈。以STC15W408AS驱动LCD12864液晶屏为例,当我们需要在小型温湿度计或仪表中实现汉字和图形显示时,串行接口相比并…...

imFile下载管理器深度解析:为什么它能成为你的全能下载解决方案?

imFile下载管理器深度解析:为什么它能成为你的全能下载解决方案? 【免费下载链接】imfile-desktop A full-featured download manager. 项目地址: https://gitcode.com/gh_mirrors/im/imfile-desktop 你是否曾经为下载大型文件而烦恼?…...

告别依赖地狱!Ubuntu 20.04/22.04 安装 ITK-SNAP 3.8.0 最全避坑指南(含libpng12终极解决方案)

医学影像处理利器:Ubuntu系统ITK-SNAP 3.8.0安装全攻略与疑难解析 在医学影像研究领域,ITK-SNAP作为一款开源的图像分割与可视化工具,凭借其强大的功能和友好的交互界面,成为众多科研工作者的首选。然而,当我们在较新…...

TRNSYS新手入门:从零开始搭建你的第一个建筑能耗模型(附Type56模块详解)

TRNSYS新手实战指南:Type56建筑能耗建模全流程解析 第一次打开TRNSYS时,面对数百个模块图标在画布上铺开,那种手足无措的感觉我至今记忆犹新。作为建筑能耗模拟领域的工业级软件,TRNSYS的强大之处恰恰在于其模块化设计——但这也成…...

3分钟完成Windows和Office激活:KMS_VL_ALL_AIO智能激活工具终极指南

3分钟完成Windows和Office激活:KMS_VL_ALL_AIO智能激活工具终极指南 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为Windows系统频繁弹出激活提示而烦恼吗?Office文…...

别再手动调间距了!用Matlab的tiledlayout函数搞定论文级多图排版(附代码)

告别繁琐排版:用Matlab tiledlayout打造学术级多图布局 还在为论文中的多图排版焦头烂额?每次调整subplot位置都要耗费半小时?Matlab R2019b引入的tiledlayout功能彻底改变了这一局面。这个被严重低估的工具,能让你的科研图表排版…...

nanobot保姆级教程:Qwen3-4B tokenizer分词结果可视化、special token作用解析

nanobot保姆级教程:Qwen3-4B tokenizer分词结果可视化、special token作用解析 1. 引言 如果你正在使用大语言模型,尤其是像Qwen这样的开源模型,有没有好奇过模型到底是怎么“读”懂你输入的文字的?为什么有时候你输入一个词&am…...

别再只用箱线图了!用R的Raincloud Plots(云雨图)可视化你的纵向数据,附完整代码

用R语言打造科研级纵向数据可视化:云雨图全流程解析 第一次在学术会议上看到那张融合了散点、箱线和小提琴图的幻灯片时,我正被自己单调的柱状图折磨得昏昏欲睡。那张图表像有魔力般,既展示了整体分布规律,又保留了每个受试者的个…...

PADS页面连接符更新失败?手把手教你解决原理图更新问题(含GND/PWR符号)

PADS页面连接符更新失败?手把手教你解决原理图更新问题(含GND/PWR符号) 在PCB设计流程中,原理图设计是至关重要的一环。作为行业标准工具之一,PADS Logic凭借其强大的功能和稳定的性能赢得了众多工程师的青睐。然而&am…...

MATLAB三维散点图进阶:scatter3函数参数详解与实战可视化技巧

1. scatter3函数基础:从零开始绘制三维散点图 第一次接触MATLAB的三维可视化功能时,我被scatter3函数的强大震撼到了。这个函数就像是一个三维空间的魔法笔,能够把枯燥的数据点变成直观的空间分布图。记得当时处理一组流体力学实验数据&#…...

服务器该如何防范网络攻击?

服务器作为网络系统的核心枢纽,存储着大量关键数据并支撑着各类业务运行,一旦遭受网络攻击,可能导致数据泄露、服务中断等严重后果。防火墙是服务器网络安全的第一道防线,它可以根据预设的规则,对进出网络的数据包进行…...

魔兽争霸III终极兼容性修复指南:让经典游戏在Windows 11上焕发新生

魔兽争霸III终极兼容性修复指南:让经典游戏在Windows 11上焕发新生 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为《魔兽争霸III》…...

【研报320】2026年北京车展核心看点前瞻:自主高阶智驾+自研芯片,合资拥抱中国方案

本报告提供限时下载,请查看文后提示以下仅为报告部分内容:摘要:2026年北京车展恰逢L3自动驾驶规模化商用元年,聚焦自主、新势力、合资三大阵营变革。自主品牌密集兑现技术,华为乾崑智驾全面下沉,比亚迪、吉…...

别再折腾FFmpeg了!用SRS流媒体服务器搞定海康摄像头Web实时监控(GB28181协议)

基于SRS的GB28181协议摄像头Web实时监控实战指南 每次调试海康摄像头的实时监控功能时,总会遇到各种技术难题。传统方案依赖FFmpeg进行流转换,不仅配置复杂,延迟问题也让人头疼。最近在智慧园区项目中,我们成功用SRS流媒体服务器实…...

如何用5分钟快速部署中医AI助手:构建专业中医大语言模型的完整指南

如何用5分钟快速部署中医AI助手:构建专业中医大语言模型的完整指南 【免费下载链接】CMLM-ZhongJing 首个中医大语言模型——“仲景”。受古代中医学巨匠张仲景深邃智慧启迪,专为传统中医领域打造的预训练大语言模型。 The first-ever Traditional Chine…...

重磅更新!植物大战僵尸杂交版 V0.19.1 完整版发布|PC + 安卓双端直装,一键转存即玩

各位 PVZ 爱好者、杂交版忠实玩家们久等了!全网热度爆表的植物大战僵尸杂交版 V0.19.1 正式发布版现已完整打包上传,本次带来电脑 PC 版(ZIP 压缩包) 手机安卓版(APK 直装) 双版本资源,无捆绑、…...

Dify租户ID注入漏洞实录(CVE-2024-XXXX已备案):如何用AST静态扫描+运行时Context Guard双锁防御

第一章:Dify租户ID注入漏洞实录(CVE-2024-XXXX已备案):如何用AST静态扫描运行时Context Guard双锁防御该漏洞源于 Dify v0.6.10 之前版本中 app/api/endpoints/chat.py 对 X-Tenant-ID 请求头的直接字符串拼接式 SQL 查询构造&…...

Hunyuan-MT-7B部署教程:像素语言传送门在阿里云PAI-EAS平台的弹性推理服务部署

Hunyuan-MT-7B部署教程:像素语言传送门在阿里云PAI-EAS平台的弹性推理服务部署 1. 项目概述 像素语言传送门(Pixel Language Portal)是一款基于腾讯Hunyuan-MT-7B大语言模型构建的创新翻译工具。与传统翻译软件不同,它将语言转换过程设计成一场16-bit像…...

告别手写链接脚本:用Vector vLinkGen 2.1.0为AUTOSAR项目自动生成内存布局

告别手写链接脚本:用Vector vLinkGen 2.1.0为AUTOSAR项目自动生成内存布局 在嵌入式开发领域,AUTOSAR架构已成为汽车电子系统的主流标准。面对多核MCU(如AURIX、S32K等)的复杂内存管理需求,传统手动编写链接脚本的方式…...

MIL-53(Al)修饰四氧化三铁纳米颗粒,MIL-53(Al)@Fe₃O₄ NPs,反应机制

MIL-53(Al)修饰四氧化三铁纳米颗粒,MIL-53(Al)Fe₃O₄ NPs,反应机制MIL-53(Al)Fe₃O₄ NPs(MIL-53(Al)修饰四氧化三铁纳米颗粒)是一类典型的磁性核–金属有机骨架壳层复合材料,其反应机制可从“表面活化—配位诱导成核…...

如何用BabelDOC轻松解决PDF翻译难题:5步完整指南

如何用BabelDOC轻松解决PDF翻译难题:5步完整指南 【免费下载链接】BabelDOC Yet Another Document Translator 项目地址: https://gitcode.com/GitHub_Trending/ba/BabelDOC 你是否曾为翻译PDF文档而烦恼?格式错乱、公式丢失、表格变形——这些问…...

Obsidian Weread插件:一键同步微信读书笔记到知识库的高效解决方案

Obsidian Weread插件:一键同步微信读书笔记到知识库的高效解决方案 【免费下载链接】obsidian-weread-plugin Obsidian Weread Plugin is a plugin to sync Weread(微信读书) hightlights and annotations into your Obsidian Vault. 项目地址: https://gitcode.c…...

用TCRT5000传感器改造玩具车:低成本搭建竞赛级Arduino循迹机器人

用TCRT5000传感器改造玩具车:低成本搭建竞赛级Arduino循迹机器人 去年校赛上,看到隔壁团队用废旧玩具车改装的循迹机器人以0.3秒优势夺冠时,我才意识到——硬件性能的差距完全可以用传感器策略和算法优化来弥补。本文将分享如何用每颗不到2元…...