自主研发接口测试框架

测试任务:将以前完成的所有的脚本统一改写为unitest框架方式

1、需求原型

1.1 框架目录结构

V1.0:一般的设计思路分为配置层、脚本层、数据层、结果层,如下图所示

V 2.0:加入驱动层testdriver

1.2 框架各层需要完成的工作

1、配置层:config

设计配置文件.csv:由配置文件来控制此次测试执行,以及需要调用哪些测试脚本。

2、脚本层:script

ind_interface:存放独立接口测试脚本、一个类中有一个测试方法、完成一个接口的测试。

mul_interface:存放接口联调测试脚本、一个类中有多个测试方法、完成接口联调的测试。

注意:脚本文件的名称有一定的规范性。

3、测试数据文件层:testdatafile

ind_interface:存放独立接口测试脚本对应的测试数据文件

mul_interface:存放接口联调测试脚本对应的测试数据文件

注意:数据文件的命名 ind_、 mul_

4、测试报告文件层:testresultfile

fram_result:测试框架报告

ind_interface:存放独立接口测试报告文档

mul_interface:存放联调接口测试报告文档

注意:报告文件命名 fram_  、ind_rep_  、mul_rep_

5、框架驱动层

存放测试框架的驱动程序

1.3  框架的测试执行过程

1、由框架驱动层中的框架驱动程序运行。

2、依据配置层相关的设置是否执行及执行顺序,调用对应脚本层的程序,进行执行。

3、相关的脚本运行时,如果需要测试数据,则在数据层进行文件的读取。

4、测试脚本执行结束后,会写明相关的测试报告文件,并存入测试报告层。

1.4 最终目标

2、测试框架前期准备

1、依据框架需求搭建框架项目及模块

2、接口测试数据文件向框架转移

3、框架脚本的研发

3.1 重构测试脚本

更新用户信息接口测试,在框架对应的分层下创建新的python文件,注意符合命名规范,test_updateuser

3.1.1  更新用户信息接口V1.0

V1.0版本
    S1:导入unittest
    S2:定义一个类,继承unittest
    S3:传入固定的接口测试数据(一组)
    S4:assert进行判断

# 对更新用户信息的脚本进行测试,使用unittest框架技术,V1.0版本,传入一组固定的测试数据,进行接口测试
# 接口说明:
# 接口访问地址:   http://localhost:8080/jwshoplogin/user/update_information.do
# 接口传入参数:1、email: 2、phone:3、answer: 4、question:
# 接口预期返回结果:
# 1、email已存在, 请更换email再尝试更新 2、更新个人信息成功  3、更新个人信息失败"
#*****************************************************************************
# 脚本实现:
# 导入相关类库
import unittest
import requests# 定义测试类,继承unittest框架
class test_updateuser(unittest.TestCase):# 通过setup方法实现登录接口的调用def setUp(self):url="http://localhost:8080/jwshoplogin/user/login.do"userinfo={"username":"程勇4","password":"123456"}response=requests.post(url,data=userinfo)self.sessionID=dict(response.cookies)['JSESSIONID']print(self.sessionID)# V1.0版本,传入一组固定的测试数据,进行接口测试def test_case1(self):# 传入指定的接口测试数据url="http://localhost:8080/jwshoplogin/user/update_information.do"userinfo={"email":"1234561@qq.com","phone":"13311095555","question": "苹果","answer":"最喜欢的水果"}session={"JSESSIONID":self.sessionID}# 进行接口调用response=requests.post(url,data=userinfo,cookies=session).textprint(response)self.assertIn("更新个人信息成功",response)def tearDown(self):passif __name__ == '__main__':unittest.main()

3.1.2  更新用户信息接口V2.0

S1:是否需要测试数据文件
    对测试数据文件进行设计
        测试用例的设计
    更新接口测试分析
        正常
            只更新一个数据
                1、只更新email
                    email不冲突
                2、只更新phone
                3、只更新answer
                4、只更新问题question
            更新更多数据
                更新2组数据
                    更新email和phone
                        email不冲突
                    更新question和answer
                    更新...
                更新3组数据
                    更新email和phone和question
            更新全部数据
                1、email
                    email不冲突
                2、phone
                3、answer
                4、question
        异常
            1、未登录更新
            2、邮箱冲突
            3、电话的长度不正确
            4、问题为空
            5、答案为空
S2:把数据文件中的内容传入脚本

# V2.0 通过csv文件进行更新测试数据的读取# 接口说明:
# 接口访问地址:   http://localhost:8080/jwshoplogin/user/update_information.do
# 接口传入参数:1、email: 2、phone:3、answer: 4、question:
# 接口预期返回结果:
# 1、email已存在, 请更换email再尝试更新 2、更新个人信息成功  3、更新个人信息失败"
#*****************************************************************************
# 脚本实现:
# 导入相关类库
import os
import unittest
import requests
import csv# 定义测试类,继承unittest框架
class test_updateuser_V2(unittest.TestCase):# 通过setup方法实现登录接口的调用def setUp(self):# # 从csv测试数据文件中读取url和登录测试数据path=os.getcwd()print(path)# p1=os.path.abspath(os.path.dirname(path)+os.path.sep+".")# print(p1)p2 = os.path.abspath(os.path.dirname(path) + os.path.sep + "..")self.fpath=p2+"\\testdatafile\\ind_interface\\test_updateuser_V21.csv"# print(fpath)userinfo={}file1=open(self.fpath,'r')table=csv.reader(file1)for row in table:print(row[0])url=row[0]userinfo[row[3]]=row[4]userinfo[row[5]]=row[6]print(userinfo)break  # 读完一行就退出response=requests.post(url,data=userinfo)self.sessionID=dict(response.cookies)['JSESSIONID']print(self.sessionID)# V2.0版本,读取指定的测试数据文件中对应的内容,进行接口测试def test_case1(self):# 打开对应的文件file1=open(self.fpath,'r')# 如何从指定行开始读取table=csv.reader(file1)userinfo={}num=0for row in table:num=num+1if num>1:url=row[0]expresult=row[2]j=int(row[1])for i in range(3,j*2+3,2):userinfo[row[i]]=row[i+1]print(userinfo)session={"JSESSIONID":self.sessionID}print(session)response=requests.post(url,data=userinfo,cookies=session).textprint(response)userinfo={}self.assertIn("更新个人信息成功",response)if __name__ == '__main__':unittest.main()

工作小结:需要注意的事项
    1、文件位置的读取
        import os
        获取当前路径
            path=os.getcwd()
        获取上一级路径
            p1=os.path.abspath(os.path.dirname(path)+os.path.sep+".")
        获取前两级路径
            p2 = os.path.abspath(os.path.dirname(path) + os.path.sep + "..")
    2、测试数据文件的设计
        可以把固定的内容放在前面的列中
        把不定项的参数可以放在后面的列中
        通过手工加入参数个数。方便进行循环读取
        不要用拖拽的方式拷贝数据,防止数据出错
        先设计正确的数据,保证脚本调试通过
        再设计错误的数据
            也可以考虑放在不同的文件
    3、从指定的某一行开始读取内容
        num=0
        for row in table:
        追加
            num=num+1
        例如:我们想从第四行读起
            if num>4
            从指定的行开始进行读取

3.1.3  更新用户信息接口V3.0

生成HTML格式的测试报告

步骤
    1、下载HTML格式的测试报告
        步骤
            1、下载HTMLTestRunner.py
                http://tungwaiyip.info/software/HTMLTestRunner.html
            2、拷贝到项目文件夹下
            3、导入HTMLReport包
                from HTMLTestRunner import HTMLTestRunner
            4、生成测试报告的脚本
                脚本
                    做好测试执行前的准备工作
                        指定要执行的测试用例
                    S1:以wb(二进制写文件)模式打开测试报告文件
                    S2:使用HTMLTestRunner方法创建HTML文件
                    S3:执行测试
                    S4:关闭文件
    工作小结
        在main()函数中来生成html的测试报告
            1、获取测试报告文件应放置的路径
            2、给定具体的测试报告文件名
            3、以wb的方式打开文件
            4、设置测试套,并添加要 测试的方法
            5、生成HTML报告
                runner=HTMLTestRunner(stream=file,title="标题",description="描述")
            6、调用runner对象执行测试套
                runner.run(suite)
            7、关闭测试报告文件

# v3.0  创建HTML格式的测试报告文件# 接口说明:
# 接口访问地址:   http://localhost:8080/jwshoplogin/user/update_information.do
# 接口传入参数:1、email: 2、phone:3、answer: 4、question:
# 接口预期返回结果:
# 1、email已存在, 请更换email再尝试更新 2、更新个人信息成功  3、更新个人信息失败"
#*****************************************************************************
# 脚本实现:
# 导入相关类库
import os
import unittest
import requests
import csv
from HTMLTestRunner import HTMLTestRunner# 定义测试类,继承unittest框架
class test_updateuser_V3(unittest.TestCase):# 通过setup方法实现登录接口的调用def setUp(self):# # 从csv测试数据文件中读取url和登录测试数据path=os.getcwd()# print(path)# p1=os.path.abspath(os.path.dirname(path)+os.path.sep+".")# print(p1)p2 = os.path.abspath(os.path.dirname(path) + os.path.sep + "..")print(p2)self.fpath=p2+"\\testdatafile\\ind_interface\\test_updateuser_V21.csv"# print(fpath)userinfo={}file1=open(self.fpath,'r')table=csv.reader(file1)for row in table:print(row[0])url=row[0]userinfo[row[3]]=row[4]userinfo[row[5]]=row[6]print(userinfo)breakresponse=requests.post(url,data=userinfo)self.sessionID=dict(response.cookies)['JSESSIONID']print(self.sessionID)def test_case1(self):# 打开对应的文件file1=open(self.fpath,'r')# 如何从指定行开始读取table=csv.reader(file1)userinfo={}num=0for row in table:num=num+1if num>1:url=row[0]expresult=row[2]j=int(row[1])for i in range(3,j*2+3,2):userinfo[row[i]]=row[i+1]print(userinfo)session={"JSESSIONID":self.sessionID}print(session)response=requests.post(url,data=userinfo,cookies=session).textprint(response)userinfo={}self.assertIn("更新个人信息成功",response)if __name__ == '__main__':# unittest.main()# 定义测试报告文件path=os.getcwd()p2 = os.path.abspath(os.path.dirname(path) + os.path.sep + "..")filename=p2+"\\testresultfile\\ind_interface\\test_updatauser_report.html"# 加载测试套suite=unittest.TestSuite()suite.addTest(test_updateuser_V3("test_case1"))# 以wb的方式打开文件file=open(filename,"wb")# 调用HTML测试报告的报告生成测试报告runner=HTMLTestRunner(stream=file,title="更新用户接口测试",description="接口测试报告")print("测试报告")runner.run(suite)file.close()

3.1.4 遇到问题分析

更新用户的接口,需要先进行登录
   1、测试场景1:未登录,进行更新
        提示:用户未登录
   2、 测试场景2:先登录,再进行更新
        需要解决的问题
            解决方案
                方案1
                    在当前的测试类中,追加一个setup方法
                        登录的测试脚本写入setup中
                        用的比较多
                方案2:
                    在当前的测试类中,追加一个新的测试方法
                        test_case1
                            完成登录的调用
                        把原来的更新测试方法改为test_case2
                方案3:
                    在当前的测试类及测试方法中
                        前面追加一段代码
                            完成登录的调用
                方案4:
                    另外创建一个脚本文件,来实现登录,通过测试框架进行接口测试联调
    3、遇到的问题
        即使已经发送了登录请求,在调用更新接口时提示"用户未登录"
    问题分析
        sessionID
            服务器端发送给客户端一个随机的认证号码
        方法1:
            使用postman工具
                先登录
                再修改个人信息是否可行
        方法2:
            通过工具获取JESSIONID
            再把相关的JESSION传入代码中
            问题:
                1、JessionID有时间限制
                2、如果关闭tomcat服务重新启动,session自动失效了
                3、用工具过去的session ID和登录脚本没有任何关系
        方法3
            在用户登录之后获取到对应的JESSIONID
                dict(response.cookie)["JSESSIONID"]
            把这个JESSIONID当成传输参数传递给更新脚本
                self.sessionID
            要解决的问题
                如何在登录后获取对应的JESSIONID

4、设计及实现框架驱动程序

4.1 框架驱动程序V1.0

在配置文件中写入一个测试文件进行执行


    S1:设计一个配置文件
        脚本名称
        脚本所在路径
    S2:读取配置文件的内容
    S3:找到对应的脚本文件进行调用
    工作小结
        工作思路
            由简到繁
                选择一种框架调用模式
                    defaultloader方式
                        unittest.defaultTestLoader.discover(路径,pattern=脚本名称)
                先用常量值进行脚本的调试
                在把常量值改为变量值
                    逐个替换
                    不要全部替换
                再把变量改为从文件读取
            发现问题,添加print语句进行分析
                问题:路径不一致
                    级别关系发生了变化
                        print(path)
                调整脚本中对应的路径级别

# 测试框架驱动程序V1.0版本
# 只是从配置文件中读取一个脚本文件进行调用
import csv
import unittest
if __name__ == '__main__':# 指定对应的脚本路径,从csv文件中读取相关路径和文件名file=open("D:\python\interfacefram\config\config1.csv","r")table=csv.reader(file)num=0for row in table:if num>0:testdir=row[0]fname=row[1]print(testdir,fname)num=num+1discover=unittest.defaultTestLoader.discover(testdir,pattern=fname)# # 定义一个运行对象runner=unittest.TextTestRunner()runner.run(discover)

4.2 框架驱动程序V2.0

在配置文件中写入两个测试文件进行执行

S1:修改配置文件

S2:进行脚本的修改

# 测试框架驱动程序V2.0版本
# 只是从配置文件中读取两个脚本文件进行调用
import csv
import unittest
if __name__ == '__main__':# 指定对应的脚本路径,从csv文件中读取相关路径和文件名file=open("D:\python\interfacefram\config\config2.csv","r")table=csv.reader(file)num=0for row in table:if num>0:testdir=row[0]fname=row[1]print(testdir,fname)discover = unittest.defaultTestLoader.discover(testdir, pattern=fname)# # 定义一个运行对象runner = unittest.TextTestRunner()runner.run(discover)num=num+1

4.3 框架驱动程序V3.0

在配置文件中针对不同的运行状态进行文件的执行
    S1:升级改造配置文件
        加入一状态列
            状态表示
                0/1不运行/运行
                RUN/NORUN
                No/Yes
    S2:脚本的调整
        加入条件判断

# v3.0  创建HTML格式的测试报告文件# 接口说明:
# 接口访问地址:   http://localhost:8080/jwshoplogin/user/update_information.do
# 接口传入参数:1、email: 2、phone:3、answer: 4、question:
# 接口预期返回结果:
# 1、email已存在, 请更换email再尝试更新 2、更新个人信息成功  3、更新个人信息失败"
#*****************************************************************************
# 脚本实现:
# 导入相关类库
import os
import unittest
import requests
import csv
from HTMLTestRunner import HTMLTestRunner# 定义测试类,继承unittest框架
class test_updateuser_V3(unittest.TestCase):# 通过setup方法实现登录接口的调用def setUp(self):# # 从csv测试数据文件中读取url和登录测试数据path=os.getcwd()# print(path)# p1=os.path.abspath(os.path.dirname(path)+os.path.sep+".")# print(p1)p2 = os.path.abspath(os.path.dirname(path) + os.path.sep + "..")print(p2)self.fpath=p2+"\\testdatafile\\ind_interface\\test_updateuser_V21.csv"# print(fpath)userinfo={}file1=open(self.fpath,'r')table=csv.reader(file1)for row in table:print(row[0])url=row[0]userinfo[row[3]]=row[4]userinfo[row[5]]=row[6]print(userinfo)breakresponse=requests.post(url,data=userinfo)self.sessionID=dict(response.cookies)['JSESSIONID']print(self.sessionID)def test_case1(self):# 打开对应的文件file1=open(self.fpath,'r')# 如何从指定行开始读取table=csv.reader(file1)userinfo={}num=0for row in table:num=num+1if num>1:url=row[0]expresult=row[2]j=int(row[1])for i in range(3,j*2+3,2):userinfo[row[i]]=row[i+1]print(userinfo)session={"JSESSIONID":self.sessionID}print(session)response=requests.post(url,data=userinfo,cookies=session).textprint(response)userinfo={}self.assertIn("更新个人信息成功",response)if __name__ == '__main__':# unittest.main()# 定义测试报告文件path=os.getcwd()p2 = os.path.abspath(os.path.dirname(path) + os.path.sep + "..")filename=p2+"\\testresultfile\\ind_interface\\test_updatauser_report.html"# 加载测试套suite=unittest.TestSuite()suite.addTest(test_updateuser_V3("test_case1"))# 以wb的方式打开文件file=open(filename,"wb")# 调用HTML测试报告的报告生成测试报告runner=HTMLTestRunner(stream=file,title="更新用户接口测试",description="接口测试报告")print("测试报告")runner.run(suite)file.close()

4.4 框架驱动程序V4.0

按照测试人员指定的顺序来执行相应的测试文件
    S1:升级改造配置文件
        加入执行顺序
    S2:修改脚本

# v4.0  执行任意指定路径下的任意相关命名的python测试脚本
# 脚本实现:
import unittest
import requestsif __name__ == '__main__':#**********************************************#以文件的方式来进行框架的执行#声明文件所在路径testdir='./'discover=unittest.defaultTestLoader.discover(testdir,pattern='test_updateser_v1.py')#声明测试运行对象runner=unittest.TextTestRunner()runner.run(discover)

4.5 按照测试顺序和是否运行来确定要执行哪些测试V5.0

其实框架难的地方也就是在驱动的处理这。

按照测试顺序和是否运行来确定要执行哪些测试
    复杂程序的编写思路
        分解任务,逐个击破
        逐步合并,分段调试
        脚本设计思路
            突破点
                python提供的数据字典的排序
                    脚本名
                    脚本路径
                    执行顺序
                    是相关的一组数据,不是无关的
                    import operator
                    sorted(数据字典,key=operator.itemgetter(下标或标签))


            试验1
                给定一些字典的具体数据
                    dic={"testA":3,"testC":1,"testB:4,"testD:2}
                    dicn=sorted(dic.items(),key=operator.itemgetter(1))
                    print(dicn)
                    for fn in dicn:
                    print(fn[0])
                排序算法是否可行
            试验2
                把csv配置文件的一行内容导入到字典中
                代码部分实现
                        file=open("D:\python\interfacefram\config\config4.csv","r")
                        table=csv.reader(file)
                        dic={}
                        listd=[]
                        line=0
                        for row in table:
                        if line>0:
                            跳过第一行
                        #把文件中读取的数据放入字典
                            dic={}
                                每读一行,字典清空一次
                            dic[row[1]]=row[0]
                            dic["num"]=int(row[3])
                                文件执行顺序
                            print("dicn",dicn)
            试验3
                把csv配置文件的多行内容导入到字典列表中
                    listd=[]
                    line=line+1
                    if dic!={}:
                         listd.append(dic)
                    dicn=sorted(listd,key=operator.itemgetter("num"))


            试验4
                检验读取顺序是否正确,能否正确执行
                    for i in range(0,line-1):
                    n=0
                    for content in dicn[i].items():
                        if n==0:
                            fname=content[0]
                            fdir=content[1]
                            print("fname",fname,"fdir",fdir)
                            # 调用脚本程序进行执行
                            discover = unittest.defaultTestLoader.discover(fdir, pattern=fname)
                            # # 定义一个运行对象
                            runner = unittest.TextTestRunner()
                            runner.run(discover)
                        n=n+1
            试验5
                加入对状态的判断
                    解决问题1
                        把状态内容也要追加到字典列表中
                            dic["state"]=row[2]
                    解决问题2
                        在确定执行前,把状态要取出来
                        从字典列表中取出
                    代码
                        if n==2:
                            state=content[1]
                            # print("state",state)
                            if state=="Yes":
                                # 调用脚本程序进行执行
                                 print("最终运行的程序",fname)
                                discover = unittest.defaultTestLoader.discover(fdir, pattern=fname)
                                 # # 定义一个运行对象
                                 runner = unittest.TextTestRunner()
                                runner.run(discover)
                列表字典
                    [{"testa":"d:\\sdfs","num":3,"state":"Yes"},{"testa":"d:\\sdfs","num":1,"state":"Yes"},{"testa":"d:\\sdfs","num":2,"state":"Yes"}]

# V5.0版本  把所有配置文件中的内容全部进行读取#***********************************V5.0驱动脚本程序*******************************************************
import unittest
import csv
import operator
if __name__ == '__main__':# 打开对应的配置文件进行读取# 以只读方式打卡file=open("D:\python\interfacefram\config\config4.csv","r")table=csv.reader(file)dic={}listd=[]# line=len(open("D:\python\interfacefram\config\config4.csv").readlines())line=0print(line)for row in table:print(row[0])if line>0:# 把文件中读取的数据放入字典dic={}dic[row[1]]=row[0]dic["num"]=int(row[3])#把脚本运行状态加入字典数据dic["state"]=row[2]print("dic",dic)line=line+1if dic!={}:listd.append(dic)# print(listd)print("n行数=",line)dicn=sorted(listd,key=operator.itemgetter("num"))print("dicn",dicn)for i in range(0,line-1):n=0for content in dicn[i].items():if n==0:print("content",content)fname=content[0]fdir=content[1]print("fname",fname,"fdir",fdir)if n==2:print("content2", content)state=content[1]# print("state",state)if state=="Yes":# 调用脚本程序进行执行print("最终运行的程序",fname)discover = unittest.defaultTestLoader.discover(fdir, pattern=fname)# # 定义一个运行对象runner = unittest.TextTestRunner()runner.run(discover)n=n+1

5、接口测试的总结

5.1 自主框架总体框图设计

5.2 接口测试的得与失

1、从独立接口测试脚本->接口联调测试脚本->接口测试框架都是独立研发的,不仅该项目可以用,也可以移植复用到其他项目中。

2、测试框架的技术不仅可以用于接口测试,其他以python+unittest+自动化测试的项目都可以继续沿用,具有较强的通用性。

3、一定程度上降低了由于界面或需求不断变更而造成的测试脚本修改或返工。

4、接口测试开展的有些晚,建议今后的接口测试最好安排在接口代码完成后就可以开始。

5、接口测试的相关设计文档还不是很完备,建议进行完善,避免测试的误解和返工。

6、接口测试的联调设计需要产品和开发的配合,确保设计的联调流程和实际应用相一致。

5.3 接口测试工作流程总结

S1:解读接口设计,形成接口测试文档。

S2:使用postman工具快速学习接口并进行首轮接口冒烟测试。

S3:独立接口测试脚本的设计及研发。

S4:接口联调脚本的设计及研发。

S5:测试框架的设计及研发。

S6:接口测试工作的改进及优化

愿每个测试都能成为测试开发,提高职业技能,成为前1%的存在,为社会创造更大的价值,为公司节约更多的成本,为自己和家庭谋求更高的收入,所有人不受职业年龄限制,越老越吃香,直至财富自由;愿测试技术越来越进步,软件质量进一步得到提高,效率提高。愿祖国更加美好,人民更加幸福。多喜乐,常安宁。

​​​​​​​拨云见日终有时,学无止境勤可达。

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

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

相关文章

Fast DDS library windows 下源码编译(cmake)

目录 编译环境: 编译需要的源码文件: Fast DDS编译: 注意事项: 参考文档: 基于Fast DDS 的源码来编译相关的库,然后可以通过python 来调用库文件实现dds 数据通信,本文就详细的介绍编译过程…

机器学习筑基篇,容器调用显卡计算资源,Ubuntu 24.04 快速安装 NVIDIA Container Toolkit!...

[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路 ] Ubuntu 24.04 安装 NVIDIA Container Toolkit 什么是 NVIDIA Container Toolkit? 描述:NVIDIA Container Toolkit(容器工具包)使用户能够构建和运行 GPU 加速的容器,该工具包括一个容器运行时库和实用程序,用于自动…

石油巨头受冲击!埃克森美孚、BP接连发出盈利预警

KlipC报道:近日,BP(英国石油)预计其第二季度将面临10亿至20亿美元的减值费用,并发出警告称其炼油利润率“大幅下降”,石油交易收益预计出现疲软。消息公布后,其股价下跌超4%。 由于中间馏分油利…

JavaScript(8)——函数

函数 function,是被设计执行特定任务的代码块。 函数可以把具有相同或相似逻辑的代码包裹起来,通过函数调用执行这些代码,这么做的优势有利于精简代码方便复用。类似于alert(),prompt()和console.log(),这些都是js函数,不过已经…

STL(一)

书写形式:string (const string& str, size_t pos, size_t len npos); 举例: int main(){ string url("https://mp.csdn.net/mp_blog/creation/editor?spm1000.2115.3001.4503") string sub1(url,0,5);//从下标为0开始向后5个字符&…

如何在 Python 中创建一个类似于 MS 计算器的 GUI 计算器

问题背景 假设我们需要创建一个类似于微软计算器的 GUI 计算器。这个计算器应该具有以下功能: 能够显示第一个输入的数字。当按下运算符时,输入框仍显示第一个数字。当按下第二个数字时,第一个数字被替换。 解决方案 为了解决这个问题&am…

Spring中的适配器模式和策略模式

1. 适配器模式的应用 1.1适配器模式(Adapter Pattern)的原始定义是:将一个类的接口转换为客户期望的另一个接口,适配器可以让不兼容的两个类一起协同工作。 1.2 AOP中的适配器模式 在Spring的AOP中,使用Advice&#…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第一篇 嵌入式Linux入门篇-第十九章 Linux 工具之make 工具和 makefile 文件

i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

集群管理脚本

虚拟机集群管理脚本 文章目录 虚拟机集群管理脚本一、远程调用脚本(remote_call.sh)二、远程复制目录脚本(remote_copy.sh) 一、远程调用脚本(remote_call.sh) 如果有传命令参数,则执行该命令;如果没有传命令参数,则不执行。 #!/bin/bashcm…

【嵌入式Linux】<知识点> GDB调试(更新中)

文章目录 前言 一、GDB调试预备工作 二、GDB的启动与退出 三、GDB中查看源代码 四、GDB断点操作 五、GDB调试指令 前言 在专栏【嵌入式Linux】应用开发篇_Linux打工仔的博客中,我们已经写了大量的源程序。但是在调试这些程序时我们都是通过printf大法和肉眼除…

评估指标:精确率(Precision)、召回率(Recall)、F1分数(F1 Score)

评估指标:精确率(Precision)、召回率(Recall)、F1分数(F1 Score) 前言相关介绍1. 准确率(Accuracy)2. 精确率(Precision)3. 召回率(Re…

Cadence23打开与关闭飞线,修改位号丝印大小

打开与关闭所有飞线: 显示部分飞线: 单独显示网络飞线尤为好用,点击上图中的网络,之后鼠标点击器件中你想高亮的网络即可单独打开部分飞线。 这里的关闭部分网络的飞线也很好用,可以临时关闭讨厌的GND飞线&#xff1a…

virturalBox+K8S部署jaeger-all-in-one

pod的yaml如下:这里使用的是主机host模式 apiVersion: apps/v1 kind: Deployment metadata:name: jaegerlabels:app: jaeger spec:replicas: 1selector:matchLabels:app: jaegertemplate:metadata:labels:app: jaegerspec:hostNetwork: truecontainers:- name: jae…

TF卡病毒是什么?如何防范和应对?

在存储芯片及存储卡领域,TF卡病毒是一个备受关注的话题。在本文中,拓优星辰将详细解释TF卡病毒的含义、来源以及如何防范和应对这一问题,帮助客户更好地了解和处理TF卡病毒的风险。 1. TF卡病毒的含义 TF卡病毒是指针对TF存储卡(T…

05:定时器中断

中断 1、定时器T0中断2、案例:通过定时器T0中断来实现灯间隔1s亮灭 1、当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后,再回到原来被中断的地方…

【数据结构】一文了解七大排序算法

文章目录 前言一.直接插入排序插入排序思想插入排序代码实现插入排序总结 二.希尔排序希尔排序思想希尔排序代码实现希尔排序总结 三.选择排序选择排序思想选择排序代码实现选择排序总结 四.堆排序堆排序思想堆排序代码实现堆排序总结 五、冒泡排序冒泡排序思想冒泡排序代码实现…

Dify 与 Xinference 最佳组合 GPU 环境部署全流程

背景介绍 在前一篇文章 RAG 项目对比 之后,确定 Dify 目前最合适的 RAG 框架。本次就尝试在本地 GPU 设备上部署 Dify 服务。 Dify 是将模型的加载独立出去的,因此需要选择合适的模型加载框架。调研一番之后选择了 Xinference,理由如下&…

易我分区大师18.8.0更新:两大功能改进

近日,易我分区大师18.8.0更新上线。此次更新重点改进了系统克隆功能,支持从第二块系统盘(从盘)克隆系统;同时,软件支持将分区的文件系统格式从FAT转换成exFAT。 01、系统克隆 系统克隆功能旨在帮助用户在…

pinia学习

conuter.ts <template><div><!-- 显示当前的计数 --><p>Count: {{ count }}</<!-- 显示计算的双倍计数 --><p>Double Count: {{ doubleCount }}</p><!-- 点击按钮以增加计数 --><button click"increment">…

基于红黑树对map和set的封装

前言 前面我们已经对红黑树做了介绍和实现&#xff0c;本期我们来对红黑树进一步改造&#xff0c;然后基于改造后的红黑树封装出map和set&#xff01; 本期内容介绍 • 红黑树的改造 • 红黑树的迭代器实现 • map的封装 • set的封装 • 全部源码 ● 红黑树的改造 我们目前…