那些经常被问到的接口测试面试题
1、json和字典的区别?Json是轻量级的数据交互格式,以key-value的键值对形式来保存数据,结构清晰,可以说是目前互联网项目开发中最常用的一种数据交互格式。字典,同样是以key-value的键值对来保存数据,是python中的一种数据类型。
1) json是一个字符串格式,不是字典格式。
2) json中true、false、null,需要双引号;字典中是True、False、None,单引号/双引号都可以。
3) json.loads()是json转字典;json.dumps( ),是字典转json。
2、做接口自动化测试时,测试数据放哪里?
对于一些基础配置比如数据库配置可以放到properties文件(yaml文件,没用过就别拓展了)。
接口测试需要用到的数据可以放数据库表,也可以放到excel中。
3、什么是数据驱动?
数据驱动就是通过excel,或者xml,数据库等数据结构来维护测试数据,通过相应的技术去处理,拿到测试数据用于测试,从而实现测试数据与代码的解耦,数据驱动测试的本质是高级的参数化。
将测试用例放在excel中,使用数据驱动(如ddt)遍历每一条用例, 然后传递给被装饰的方法的一个参数,有几条数据 就执行几次用例。
·代码复用率高。同一测试逻辑编写一次,可以被多条测试数据复用,提高了测试代码的复用率,同时可以提高测试脚本的编写效率。
·异常排查效率高。测试框架依据测试数据,每条数据生成一条测试用例,用例执行过程相互隔离,在其中一条失败的情况下,不会影响其他的测试用例。
·代码的可维护性高。清晰的测试框架,利于其他测试工程师阅读,提高了代码的可维护性。
4、excel中如何设计你的用例?
1) 所有的接口信息维护在一个表单。
2) 关于接口的用例数据维护在一个表单。
3) 接口传参一列来传,通过构造json格式的字符串即可解决传多个参数的问题,同时提升了用例的可维护性。
用例内容:
5、excel中的数据怎么拿出来?
通过第三方库openpyxl来完成,项目只需要引入openpyxl库,通过它提供的api即可完成对于excel的操作,甚至于我们自己也可以做一些二次封装,使得操作更方便。一行数据就是一个用例。
6、如果有些接口做了鉴权(需要鉴定权限),怎么实现这些接口的自动化测试?
在测试其他接口的时候需要先登录,并获取token,将token放在测试接口的请求头中一同传递。
首先需要明确接口是通过什么机制来实现的鉴权。
1) 如果是通过会话id(JSESSIONID)来实现鉴权的,那么先调用完登录接口--》拿到它返回的这个数据--》存储起来--》后面再调用其他接口的时候直接带上这个数据过去就可以了。
2) 如果是通过token来实现鉴权的,那么同样只需要在调用完登录接口--》拿到它返回的这个数据--》存储起来,后面操作同上。
先回答上面的一个基本实现步骤,然后再补充以下一些实现细节:
a. 怎么取到这个JSESSIONID或者token
这个信息怎么取首先得明白它是怎么返回来的,可能为以下两种方式:
1) 登录接口的响应头
2) 登录接口的响应报文
需要找开发确认,不同方式不同取法。
b. 怎么存储这个JSESSIONID或者token
1) 文件中(excel、properties文件都可以)
2) 数据库
3) 代码里面自己定义的公共静态变量,作为一个共享的数据
c. 请求其他需要鉴权的接口时,怎么带过去这个数据
先找开发人员确认,再调用需要鉴权的这些接口怎么携带这个鉴权的信息(票)。一般不外乎这么几种:
1) 拼接在url上传过去用于服务器验证
2) 设置到请求体中
3) 通过请求头带过去
弄明白怎么传过去以后,就设法从保存了这个鉴权信息的地方取出来--》传过去。
7、什么是会话?
所谓会话就是session,而session是一种服务器的缓存技术,由服务器端创建,用户登录了系统,一般就会把登录用户的信息保存到这个session对象中,然后把此会话对应的id(JSESSIONID)返回,因此大部分系统都会用到session机制来实现鉴权。Session保存数据方式也是以key-value的形式。
8、什么是token?
所谓token其实就是服务器端返回的一个字符串(有点类似于:xys73494954sdhcdr83435这么一串),这个数据是基于什么算法生成的需要找开发确认,一般这个数据是唯一的,服务器每次返回的token都会不一样。
Token之所以可以用来做鉴权,原理如下:用户a调用了登录接口–》登录了系统b–》服务器端生成了一个唯一的token信息(假设为c),然后会拿用户的编号id(假设为d)做了一个映射:c-d,然后将这样的映射关系存到数据库或redis等缓存中,然后再返回这个token给客户端–》客户端再调用其他需要鉴权的接口时,只需要将缓存起来的这个token带过去验证–》服务器根据此token检查是否有登录用户信息来判断此请求是否是一个已登录授权的用户。
9、某个接口请求,参数依赖上个接口的返回数据,怎么处理(接口关联)?
场景:b接口在调用的时候参数依赖于a接口的返回数据。
处理方案:a接口调用完–》从响应中取出b依赖的这个参数–》保存起来–》b调用的时候,取出这个信息–》当做参数传过去即可。
10、接口调用依赖第三方的接口b,而b接口还未提供给你,如何处理?
通过mock框架搭建自己的mock系统/平台(其实就是自己开发接口),模拟这个第三方接口mock一个出来即可,这样就解决了这个依赖。
11、接口测试的垃圾数据如何清理?
可以自己准备单独的环境(独立的数据库),这样接口调用产生的数据可以在整个套件执行完后(@AfterSuite)通过执行sql脚本,来完成数据删除。
12、你做接口自动化,项目用的是什么数据库,用什么来操作的这个数据库
Mysql,可以通过jdbc来实现数据库的增删查改等操作。
13、你做接口自动化时怎么做的数据验证
数据验证主要包括两个方面:
1) 接口响应报文的验证
利用jsonpath取出响应数据(大多数情况是json)中的关键字段的值,通过Assert断言这些关键字段的值是否符合预期。预期值和jsonpath取值表达式可以配置在excel中。
2) 数据库表数据的验证
做表数据验证要先明白两点:
a. 表数据验证首先得明白这个接口的基本业务,会影响到哪些表,哪些字段的数据,然后才能准备查询sql去有针对性的查数据。
b. 并不是所有用例的执行都会操作数据库,影响到表数据,因此只有影响到了表数据的用例,才准备查询脚本。
具体做法:
Excel用例准备aa,bb,cc三列,aa传脚本,bb,cc两列分别用来回写用例执行前的sql查询结果和用例执行后的sql查询结果,两个数据对比即可知道数据变化是否满足预期。
14、如何提升测试套件的执行效率
1) 减少excel读写,减少不必要的io操作
2) excel数据读取测试数据,全部存储到静态变量中)。
3) excel数据回写,尽量通过批量方式去写。
我的作答:测试套件就是将测试用例集合在一个套件中执行。那么测试用例的数量和每一个测试用例代码中的数量决定着测试套件的执行效率。那么优化代码,提高代码的可复用性就能够显著的提高测试套件的执行效率。
15、你用过单元测试框架吗,是什么框架,有哪些常用操作?
用过,unittest,pytest(不熟可以不说),这些测试框架都支持我们去定义测试套件,
达到管理我们测试用例代码的作用,同时这些测试框架提供的一些丰富注解不仅能很方便的控制测试用例的执行顺序来控制整个测试流程,
还能为各种测试场景的实现提供支撑。
常用操作:
seutp,teardown,适合单个测试用例的初始化、环境清理。
seutpClass,teardownClass:适合测试类的全局初始化、环境清理。
assertXXXX: 各种断言方式
testLoader的discover: 用来发现测试用例
testSuite的addTests: 用来装载测试用例
@ddt 数据驱动
htmlTestRunner:用来生成html测试报告
16、说说你对接口的理解
接口是服务,是功能点实现,是数据传递的通道,也是服务器端的一个实现了某种协议(比如http协议…)和映射机制(当访问一个url时就会通过服务器端的映射处理机制解析后,落到对应的处理函数)的函数,接口参数就是函数的参数,接口的响应数据就是函数的返回值。
17、做过接口测试吗,有哪些熟悉的工具。
熟悉的工具:可视化工具比如:jmeter,postman,soapui等(用过哪些说哪些)代码:requests发包技术来实现接口测试。
18、接口常见的请求方法有哪些?
接口使用http协议,常见的请求方法有get、post。另外还有Patch,Put,delete。get:发送请求获取服务器上的资源。
post:向服务器提交数据
patch:局部更新数据
put:整体更新数据
delete:删除数据
19、请简单说一说get、post这两种请求方法的区别?
功能上的区别:get用于向服务器请求资源,post用来提交资源给服务器。
格式上的区别:get发送的参数显式的放在了url之后。post请求参数放在了请求体中。
安全性:由于get请求格式的特性,能够被轻易的查看到参数中的相应数据,所以不安全,一般用于能够展示给用户的数据请求。post则因为参数在请求体中,安全性稍胜一筹,但是对于重要数据仍然需要加密传输。
执行效率:get的执行效率要快于post
传递的数据量:get可以传递的参数数据量是有限的(因为一般参数是拼接在url上,而浏览器对于url的长度是有限制的。);但是post的参数因为放在请求体中,所以可以提交的数据量不受限制。
参考答案:
Get:
a. 一般对于从服务器取数据的请求可以设置为get方式
b. Get方式在传递参数的时候,一般都会把参数直接拼接在url上(例如:http://xxx?id=1&type=2)
c. Get请求方法可以传递的参数数据量是有限的(因为一般参数是拼接在url上,而浏览器对于url的长度是有限制的)
d. Get请求因为是直接将数据拼接在url上,所以安全性不如post强(相对),但是get的执行效率要快于post
Post:
a. 一般往服务器提交数据的请求会设置为post方式
b. Post方式传递参数一般都会把参数放在请求体,而不会拼接在url
c. Post请求方法可以提交的数据量不受限制
d. Post请求传参相对于get要安全(相对不是绝对),但是post的执行效率不如get。
20、在浏览器中输入URL,回车之后发生了什么?
(1)URL 解析
(2)DNS 查询
(3)TCP 连接
(4)处理请求
(5)接受响应
(6)渲染页面
21、将列表a = ["h","e","l","l","o"]拼接成字符串,请用多种方法实现
# 方式一 字符串函数调用
print("".join(a))
# 方式二 for循环
s = ""
for item in a:
s += item
print(s)22、存在一个名称为data.log的文件,data.log中的内容是以逗号作为分隔符的,依次存储了一次测试的TestID,TestTime,Success(0成功;1失败)。文件 中数据均为非负整数。请写一段程序(不限语言),对所有成功(Success=0)的测试,输出: 1)打印最大、最小TestTime;
2)打印平均TestTime,保留小数点2位数。
data.log的内容格式如下:
TestID,TestTime,Success
0,149,0
1,69,0
2,45,0
3,18,1
4,18,1
"""
打开data.log文件 。除了第一行,剩下的第一行都是数据。
只需要按行解析数据,将success对应的值为0的提取出来,将TestTime放在一个新的列表当中。取这个列表当中,最大的值,和最小的值。
同时,对这个列表的所有数据进行取平均值即可。
"""
import os
def anaysis_data():
test_times = []
# 打开data.log文件
with open(os.getcwd() + "/data.log") as fs:
for line in fs.readlines(): # 按行读取
temp = line.strip("\n").split(",") # 去掉换行符之后,再按,分割
print("temp",temp)
if temp[-1] == str(0): # 筛选success字段为0的TestTime
test_times.append(int(temp[-2]))
if len(test_times) > 0:
avg_time = sum(test_times) / len(test_times) # 平均值
max_time = max(test_times)
min_time = min(test_times)
print("最大的TestTime: ",max_time,",最小的TestTime: ",min_time,",平均TestTime: ",avg_time)
if __name__ == '__main__':
anaysis_data()
"""
输出结果为:
temp ['TestID', 'TestTime', 'Success']
temp ['0', '149', '0']
temp ['1', '69', '0']
temp ['2', '45', '0']
temp ['3', '18', '1']
temp ['4', '18', '1']
最大的TestTime: 149 ,最小的TestTime: 45 ,平均TestTime: 87.67
"""
页:
[1]