服务端测试之业务关联

在这里插入描述

在整体的测试效率而言,API测试技术是提升测试效率最有效的手段之一,因为它的执行效率是非常高的,另外一点就是前后端的分离开发的模式,也需要我们更多的精力和时间投入到API的测试技术以及API的测试技术在企业的落地和应用。当然,这仅仅是功能层面的,还需要考虑非功能的点,比如队列,调度机制,服务的性能测试,稳定性的因素,这些是非常多的。在本篇文章中,只单纯的考虑API测试技术中关于关联的解决思路和案例应用。API测试的核心,其实并不在于单个API的测试,单个API无法保障业务的覆盖度,所以我们更多需要结合业务场景来测试这些点,但是一旦结合具体的业务场景,也就涉及到关联的思路,所谓关联,其实我们可以理解为上个API的输出是下个API的输入部分。下面结合主流的测试工具以及代码来演示这部分的具体解决方案和案例实战。

API测试中业务关联解决方案

下面的源代码主要显示的是一个订单的微服务,我们需要在登录的情况下才能够查看订单的明细数据,也就是说在登录成功后,调用订单明细的接口才可以返回订单明细的数据,如果未登录的情况下,那么就返回401的的错误信息。具体流程可以详细的描述为:登录成功,返回登录成功后的token的信息,在访问下个接口的时候需要带上登录成功返回的token值的信息,才可以正常的访问订单明细,而且有一点需要特别注意的是每次登录成功后返回的token都是随机的字符串,并且需要保持访问接口的token与登录成功返回的token值一致,其实解决问题的思路是非常简单的,就是使用关联的思路来进行解决。案例源代码具体如下:

from flask import  Flask,make_response,jsonify,abort,request
from flask_restful import  Api,Resource
from flask import Flask
from flask_jwt import JWT, jwt_required, current_identity
from werkzeug.security import safe_str_cmp

app=Flask(__name__)
app.debug = True
app.config['SECRET_KEY'] = 'super-secret'
api=Api(app=app)

orders=[
	{'id':1,'author':'wuya','bookName':'Python接口自动化测试实战','done':True,'payType':'支付宝','price':69.9},
]


class User(object):
	def __init__(self, id, username, password):
		self.id = id
		self.username = username
		self.password = password

	def __str__(self):
		return "User(id='%s')" % self.id

users = [
	User(1, 'wuya', 'asd888')
]

username_table = {u.username: u for u in users}
userid_table = {u.id: u for u in users}

def authenticate(username, password):
	user = username_table.get(username, None)
	if user and safe_str_cmp(user.password.encode('utf-8'), password.encode('utf-8')):
		return user

def identity(payload):
	user_id = payload['identity']
	return userid_table.get(user_id, None)

jwt = JWT(app, authenticate, identity)

class Order(Resource):
	decorators=[jwt_required()]

	def get(self):
		return jsonify({'status':0,'msg':'ok','datas':orders})


api.add_resource(Order,'/v1/order')

if __name__ == '__main__':
	app.run(debug=True,host='0.0.0.0')

PostMan中关联解决思路

在清楚了业务场景以及思路后,下来具体使用PostMan测试工具来演示下它的应用,PostMan是非常主流的API测试工具,在日常的研发过程中测试开发和开发同学都会使用到这个工具来验证接口的准确性。下面详细的演示下针对关联的解决思路。

PostMan中获取Token

首先我们需要在PostMan测试工具中获取token值的信息,访问的接口地址信息为/auth,具体如下:

图片

在如上中可以看到,请求成功后,会返回access_token值的信息,下来需要思考的点就是在PostMan测试工具中在tests中获取响应数据中的access_token的值,并且在tests中定义一个变量来存储获取的access_token的值,在tests的中可以使用JS的代码来获取响应的数据,也就是通过JSON.parse()把JSON字符串转位JSON对象,然后定义一个变量来存储获取到的JSON对象,然后在这个变量中再使用PostMan中的environment来定义一个变量来存储获取到的access_token的值,具体过程如下:

//把JSON字符串转为JSON的对象
var jsonData=JSON.parse(responseBody)
console.log(jsonData)

具体在PostMan的信息如下展示:

图片

在如上的截图中我们可以看到已经获取到了响应的数据,下来就是在响应数据中分离出access_token的值,并且定义一个变量来存储获取到的access_token,更新后的JS代码为:

//把JSON字符串转为JSON的对象
var jsonData=JSON.parse(responseBody)
console.log(jsonData)

//定义token变量来存储分离出的access_token
pm.environment.set("token", jsonData.access_token);

//获取定义的变量值校验是否获取
console.log(pm.environment.get("token"))

整体在截图信息如下所示:

图片

PostMan中调用变量

下来就是调用定义的变量,在调用中,一般是在请求头的Authorization中,也就是说请求头中,key是Authorization,而具体的value值就是:jwt变量值,有一点需要特别的注意,就是jwt与变量之间是有空格的。在PostMan中调用变量的方式是具体为:{{变量}}。下面我们来调用订单详情的接口信息,具体如下:

图片

在如上可以看到,返回的结果信息是401,并不是我们期望的协议状态码是200,具体详细的错误信息可以在PostMan的console中看到,这主要主要需要关注的是请求头的部分,具体如下:

图片

通过如上可以看到,我们定义的变量还是变量,应该是具体是变量值才对,具体导致这样的问题其实是很简单的,也就是说我们并没有把登录的接口和查看订单详细的接口关联起来,所以导致这样的问题。

PostMan中Collections解决关联

在如上的问题中我们可以很清晰的知道问题所在,也就是说接口测试用例需要有顺序的执行,再说的简单点就是先执行登录的接口再接着执行订单详情的接口,这样二者之间就能够关联起来。在PostMan可以通过Collections很轻松的来解决这部分的问题,Collections可以理解为测试套件,或者是测试容器,在这个容器里面可以存储很多的测试用例,所以容器它解决了两个问题,具体可以总结为:

  • 可以把所有的测试用例添加到Collections中进行批量的执行,这样解决了单个测试用例执行的效率
  • 解决了API测试中业务关联的问题

下来创建名为订单的Collections,然后把登录的接口和订单详情的接口添加到Collectios中,具体添加后的信息为:

图片

我们把测试用例添加到Collections中,下来执行订单的Collectios,也就执行了该Collections中所有的测试用例,执行后的结果信息具体如下所示:

图片

在如上中,可以很清晰的看到,在订单详情接口的请求头中,变量token的值完整的进行了替换,当然接口返回的协议状态码不再是401,而是200,下面具体显示整体的执行结果信息:

图片

JMeter关联解决思路

下面使用另外一款主流的测试工具也就是JMeter来详细的演示下这部分的具体应用,JMeter测试工具可以应用于多种协议的API测试,当然也可以应用于性能测试工具,可以说它是一款轻量级的API测试工具和性能测试工具。

JMeter中获取变量值

首先在JMeter的测试工具中创建一个线程组,以及添加登录的接口信息,具体展示信息如下所示:

图片

执行结果后,获取到响应数据,在PostMan的测试工具中,可以通过后置处理器的正则表达式或者是JSON提取器获取到响应数据,使用JSON提取器的前提是需要安装JSON的插件(在这里就不详细的说明JSON插件的安装了)。这地方我们可以JSOn提取器来获取相应数据中的access_token的值,并且定义一个变量token来存储它。具体就是选择login的接口后,右键在后置处理器中添加JSON提取器,具体如下:

图片

在如上中,可以很清晰的看到定义了变量token,以及获取access_token的值的过程,当然还需要考虑到获取值失败的情况下默认返回的结果信息是Not Found Token,这是基于程序的容错思想来思考的。

JMeter中调用变量

下来在线程组中添加订单详细的接口,然后在请求头中调用变量token,在JMeter中调用变量的方式为${变量},下面具体显示的是订单详情中请求头中调用变量的信息,具体如下所示:

图片

JMeter中验证结果信息

下面具体验证下这部分的结果信息,也就是执行,然后在查看结果树中查看接口返回的响应数据以及协议状态码,具体展示信息如下:

图片

代码中关联解决思路

在函数式的编程方面还是面向对象的编程方面,如果单独的在一个函数的角度或者是一个方法的角度而言,其实函数或者说是方法有没返回值其实并不那么的重要,因为不管是函数还是方法,我们都需要实现的是它的表达式,也就是说我们输入,然后过程中经过函数以及方法的理解处理,然后输出结果,这个结果不管是return返回来函数print()的输出,其实都一样的。的确如此,但是函数需要与其他函数之间建立一层关联,这样函数就不是孤立的个体了,而是需要思考的点是怎么和其他的函数之间建立关系。而返回值可以很好的建立这种纽带的关系,通过这样的纽带关系,函数不再是一个孤立的个体,而是与其他的函数有了关系,个人觉得这是函数它的价值体现之一。当然对函数而言,一个函数可以有多个返回值,接收的时候就需要多个值来进行接收。

返回值对关联的解决

明白了函数的返回值后,再来看之前使用工具解决关联的思路,其实发现我们使用函数的返回值可以很轻松的来解决这个问题,那么定义的函数具体就是如下:

import  requests

def login():
	r=requests.post(
		url='http://192.168.0.103:5000/auth',
		json={"username":"wuya","password":"asd888"})
	return r.json()['access_token']

来我们再来定义一个订单详细的接口信息,那么这样针对订单详情函数而言,就需要一个形式参数来接收登录的函数返回的值,因此也可以说函数的形式参数也可以是函数,具体定义的函数值如下:

import  requests
import  json

def login():
	r=requests.post(
		url='http://192.168.0.103:5000/auth',
		json={"username":"wuya","password":"asd888"})
	return r.json()['access_token']



def orderDetail(token):
	r=requests.get(
		url='http://192.168.0.103:5000/v1/order',
		headers={'Authorization':'jwt {0}'.format(token)})
	print(json.dumps(r.json(),ensure_ascii=False,indent=True))

if __name__ == '__main__':
	orderDetail(token=login())

执行如上的代码后,就可以正确的返回响应结果信息。

Fixture的解决之道

在Pytest测试框架中,Fixture函数可以有两个维度的思考,具体可以总结为:

  • 函数的返回值特性
  • 测试框架的测试固件作用

那么这地方可以结合Fixture函数的返回值的特性来轻松的解决这个问题,但是前提是必须得结合Pytest测试框架来进行执行。下面把代码改造为Pytest测试框架可以执行的代码,改造后的代码具体为:

import  requests
import  json
import  pytest

@pytest.fixture()
def login():
	r=requests.post(
		url='http://192.168.0.103:5000/auth',
		json={"username":"wuya","password":"asd888"})
	return r.json()['access_token']



def test_orderDetail(login):
	r=requests.get(
		url='http://192.168.0.103:5000/v1/order',
		headers={'Authorization':'jwt {0}'.format(login)})
	print(json.dumps(r.json(),ensure_ascii=False,indent=True))

if __name__ == '__main__':
	pytest.main(["-v","-s","test_order.py::test_orderDetail"])

执行后,可以看到使用fixture的函数很轻松的解决了这部分的问题。感谢您的阅读,后续会持续更新!

下面是一份配套资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!
在这里插入图片描述
这些都可以以在公众号:伤心的辣条 ! 免费领取,还有一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!,其中资料包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。

学习不要孤军奋战,最好是能抱团取暖,相互成就一起成长,群众效应的效果是非常强大的,大家一起学习,一起打卡,会更有学习动力,也更能坚持下去。你可以加入我们的测试技术交流扣扣群:914172719(里面有各种软件测试资源和技术讨论)

喜欢软件测试的小伙伴们,如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!


好文推荐

转行面试,跳槽面试,软件测试人员都必须知道的这几种面试技巧!

面试经:一线城市搬砖!又面软件测试岗,5000就知足了…

面试官:工作三年,还来面初级测试?恐怕你的软件测试工程师的头衔要加双引号…

什么样的人适合从事软件测试工作?

那个准点下班的人,比我先升职了…

测试岗反复跳槽,跳着跳着就跳没了…

<think>首先,用户的问题是关于DcoEcoStudio如何连接或集成服务端。DcoEcoStudio可能是一个特定工具或平台,但我没有直接的信息。根据系统指令,我需要使用中文回答,结构清晰,并参考提供的引用。 提供的引用: - 引用[1]:关于SpringBoot集成WebSocket实现长连接通信,包括配置WebSocket端点。 - 引用[2]:关于AIDL接口用于客户端和服务端通信,涉及binder和token。 用户意图:用户想了解如何在DcoEcoStudio中连接或集成服务端。DcoEcoStudio可能是一个客户端工具或IDE,我需要推断如何与服务端集成。 由于DcoEcoStudio不是标准术语,我假设它可能是一个自定义的或特定领域的工具。或许它是"Digital Content EcoStudio"或类似的东西,但我不确定。基于引用,似乎涉及客户端-服务端通信。 系统指令要求生成相关问题,所以我需要在回答后添加相关问题。 回答结构: 1. 解释如何连接或集成服务端。 2. 参考提供的引用来提供示例。 3. 使用中文。 4. 确保LaTeX语法正确:行内数学表达式用$...$,独立公式用$$...$$。 5. 在引用的段落末尾添加引用标识。 步骤: - 先理解用户需求:DcoEcoStudio如何连接服务端。 - 基于引用[1]和[2],提供WebSocket或AIDL集成的示例。 - 由于DcoEcoStudio的具体细节未知,我应给出一般性指导。 可能的集成方式: 1. 使用WebSocket进行实时通信(从引用[1])。 2. 使用AIDL或类似机制进行进程间通信(从引用[2])。 3. 其他方式如REST API、gRPC等,但引用中没有提到,所以应基于引用。 回答大纲: - 介绍DcoEcoStudio集成服务端的一般方法。 - 详细说明基于WebSocket的集成(参考引用[1])。 - 详细说明基于AIDL的集成(参考引用[2])。 - 提供代码示例或配置步骤。 - 结束时添加相关问题。 确保生成相关问题。 最终输出: - 回答部分。 - §§相关问题§§部分。</think>### DcoEcoStudio 如何连接或集成服务端 DcoEcoStudio(假设为数字内容生态工作室)是一个客户端工具或集成开发环境(IDE),用于创建和管理数字内容。要连接或集成服务端,通常涉及建立网络通信协议,实现数据交换和功能调用。以下是基于常见技术栈的逐步指南,参考了系统提供的引用示例。集成方式取决于服务端架构(如SpringBoot、AIDL等),我将重点介绍WebSocket和AIDL两种主流方法,确保响应高效可靠。 #### 1. **使用WebSocket实现长连接通信(参考引用[1])** WebSocket适用于实时双向通信场景,如DcoEcoStudio需要与服务端保持持久连接(例如实时数据同步或聊天功能)。以下是集成步骤: - **步骤1:在服务端配置WebSocket端点** 服务端(如SpringBoot应用)需导出WebSocket端点。参考引用[1],在SpringBoot中定义`ServerEndpointExporter` bean: ```java @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } ``` 此配置允许服务端处理WebSocket连接请求[^1]。 - **步骤2:在DcoEcoStudio客户端实现WebSocket连接** DcoEcoStudio(作为客户端)使用JavaScript或相应SDK初始化WebSocket。示例代码: ```javascript // 在DcoEcoStudio的客户端脚本中 const socket = new WebSocket('ws://yourserver:port/endpoint'); socket.onopen = () => { console.log('连接服务端成功'); socket.send(JSON.stringify({ type: 'register', data: 'DcoEcoStudioClient' })); }; socket.onmessage = (event) => { const data = JSON.parse(event.data); console.log('收到服务端数据:', data); // 处理数据,例如更新UI或触发业务逻辑 }; socket.onerror = (error) => { console.error('连接错误:', error); }; ``` 此代码建立WebSocket连接,实现消息发送和接收。服务端需定义对应端点处理注册和消息路由。 - **优势与注意事项** - 优势:低延迟,适合实时场景(如协同编辑)。 - 注意事项:确保服务端支持WebSocket协议,并处理连接超时和重连逻辑。性能开销为$O(n)$(n为连接数),需优化资源使用[^1]。 #### 2. **使用AIDL实现进程间通信(参考引用[2])** 如果DcoEcoStudio运行在Android环境,AIDL(Android Interface Definition Language)适合跨进程通信,例如绑定到远程服务。参考引用[2],通过binder接口传递token区分客户端: - **步骤1:定义AIDL接口** 创建服务端接口(如`RemoteService.aidl`)和客户端回调接口(如`Token.aidl`)。服务端通过token识别DcoEcoStudio实例: ```aidl // RemoteService.aidl (服务端) package com.my.remoteserver; import com.my.remoteserver.Token; interface RemoteService { void register(Token token); // 注册客户端token } // Token.aidl (客户端) package com.js.remoteserver; interface Token {} // 空接口用于标识客户端 ``` 服务端实现`register`方法,存储token以区分不同DcoEcoStudio实例[^2]。 - **步骤2:在DcoEcoStudio中绑定服务** 在DcoEcoStudio的Android组件(如Activity)中,绑定到服务端: ```java // DcoEcoStudio客户端代码 private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { RemoteService remoteService = RemoteService.Stub.asInterface(service); Token token = new Token.Stub() {}; // 创建客户端唯一token remoteService.register(token); // 注册到服务端 } @Override public void onServiceDisconnected(ComponentName name) { // 处理断开连接 } }; // 在onCreate中绑定服务 Intent intent = new Intent("com.my.remoteserver.ACTION_BIND"); bindService(intent, connection, Context.BIND_AUTO_CREATE); ``` 此代码通过binder建立连接,服务端根据token管理客户端会话。 - **优势与注意事项** - 优势:高效安全,适合Android平台的本地服务集成。 - 注意事项:需处理跨进程异常(如`RemoteException`),并确保接口版本兼容。通信延迟为$O(1)$(常数时间),但需优化序列化[^2]。 #### 3. **通用集成建议** - **协议选择**:根据需求选型。WebSocket适合实时场景,AIDL适合Android IPC,REST API适合简单HTTP交互。 - **安全机制**:添加认证(如OAuth2.0)和加密(TLS)。 - **错误处理**:实现重试机制和日志监控,确保DcoEcoStudio在断网时降级处理。 - **性能优化**:批量数据传输减少请求次数,使用缓存策略(如Redis)。 通过以上方法,DcoEcoStudio可无缝集成服务端。实际实现需依据具体框架调整,参考官方文档测试
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值