接口自动化测试面试题
接口自动化测试面试题
前言
前面总结了一篇关于接口测试的常规面试题,现在接口自动化测试用的比较多,也是被很多公司看好。那么想做接口自动化测试需要具备哪些能力呢?也就是面试的过程中,面试官会考哪些问题,知道你是不是真的做过接口自动化测试?总的来说问的比较多的就是以下几个问题:
1. json 和字典的区别? -对基础数据类型的考察
json 本质上还是字符串,只是按 key:value 这种键值对的格式来的字符串
import json
# a 是字典 dict
a = {"a": 1, "b": 2, "c": True}
# b 是 json
b = '{"a": 1, "b": 2, "c": true}'
print(type(a))
print(json.dumps(a)) # a 转 json
运行结果
<class 'dict'>
{"a": 1, "b": 2, "c": true}
<class 'str'>
{'a': 1, 'b': 2, 'c': True}
2. 测试的数据你放在哪? -数据与脚本分离
首先测试的数据是分很多种的,有登录的账户数据,也有注册的账户数据,还有接口的参数,还有邮箱配置的数据等等等等,
所以这个题不能一概而论给答死了。要不然就是给自己挖坑。
以下两个大忌不能回答:
- 测试的数据是不能写死到代码里面的,这个是原则问题,也是写代码的大忌(你要是回答写在代码里面,估计就是回去等通知了)
- 测试数据放到.py 的开头,这种其实很方便,对于少量的,固定不变的数据其实是可以放的,但是面试时候,千万不能这样说,面试官喜欢装逼的方法
测试数据存放总结:
- 对于账号密码,这种管全局的参数,可以用命令行参数,单独抽出来,写的配置文件里(如 ini)
- 对于一些一次性消耗的数据,比如注册,每次注册不一样的数,可以用随机函数生成
- 对于一个接口有多组测试的参数,可以参数化,数据放 yaml,text,json,excel都可以
- 对于可以反复使用的数据,比如订单的各种状态需要造数据的情况,可以放到数据库,每次数据初始化,用完后再清理
- 对于邮箱配置的一些参数,可以用 ini 配置文件
- 对于全部是独立的接口项目,可以用数据驱动方式,用 excel/csv 管理测试的接口数据
- 对于少量的静态数据,比如一个接口的测试数据,也就 2-3 组,可以写到 py脚本的开头,十年八年都不会变更的
总之不同的测试数据,可以用不同的文件管理
3. 参数化 - 数据驱动模式
参数化和数据驱动的概念这个肯定要知道的,参数化的思想是代码用例写好了后,不需要改代码,只需维护测试数据就可以了,并且根据不同的测试数据生成多个用例
** python 里面用 unittest 框架**
import unittest
import ddt
# 测试数据
datas = [ {"user": "admin", "psw": "123", "result": "true"},
{"user": "admin1", "psw": "1234", "result": "true"},
{"user": "admin2", "psw": "1234", "result": "true"},
{"user": "admin3", "psw": "1234", "result": "true"},
{"user": "admin4", "psw": "1234", "result": "true"},
{"user": "admin5", "psw": "1234", "result": "true"},
{"user": "admin6", "psw": "1234", "result": "true"},
{"user": "admin7", "psw": "1234", "result": "true"},
{"user": "admin8", "psw": "1234", "result": "true"},
{"user": "admin9", "psw": "1234", "result": "true"},
{"user": "admin10", "psw": "1234", "result": "true"},
{"user": "admin11", "psw": "1234", "result": "true"}]
@ddt.ddt
class Test(unittest.TestCase):
@ddt.data(*datas)
def test_(self, d):
"""测试:{0}"""
print("测试数据:%s" % d)
if __name__ == "__main__":
unittest.main()
unittest 框架还有一个 paramunittest 也可以实现
import unittest
import paramunittest
import time
# python3.6
# 作者:测试
@paramunittest.parametrized(
{"user": "admin", "psw": "123", "result": "true"},
{"user": "admin1", "psw": "1234", "result": "true"},
{"user": "admin2", "psw": "1234", "result": "true"},
{"user": "admin3", "psw": "1234", "result": "true"},
{"user": "admin4", "psw": "1234", "result": "true"},
{"user": "admin5", "psw": "1234", "result": "true"},
{"user": "admin6", "psw": "1234", "result": "true"},
{"user": "admin7", "psw": "1234", "result": "true"},
{"user": "admin8", "psw": "1234", "result": "true"},
{"user": "admin9", "psw": "1234", "result": "true"},
{"user": "admin10", "psw": "1234", "result": "true"},
{"user": "admin11", "psw": "1234", "result": "true"},
)
class TestDemo(unittest.TestCase):
def setParameters(self, user, psw, result):
'''这里注意了,user, psw, result 三个参数和前面定义的字典一一
对应'''
self.user = user
self.user = psw
self.result = result
def testcase(self):
print("开始执行用例:--------------")
time.sleep(0.5)
print("输入用户名:%s" % self.user)
print("输入密码:%s" % self.user)
print("期望结果:%s " % self.result)
time.sleep(0.5)
self.assertTrue(self.result == "true")
if __name__ == "__main__":
unittest.main(verbosity=2)
如果用的是 pytest 框架,也能实现参数化
# content of test_canshu1.py
# coding:utf-8
import pytest
@pytest.mark.parametrize("test_input,expected",
[ ("3+5", 8),
("2+4", 6),
("6 * 9", 42),
])
def test_eval(test_input, expected):
assert eval(test_input) == expected
if __name__ == "__main__":
pytest.main(["-s", "test_canshu1.py"])
pytest 里面还有一个更加强大的功能,获得多个参数化参数的所有组合,可以堆叠参数化装饰器
import pytest
@pytest.mark.parametrize("x", [0, 1])
@pytest.mark.parametrize("y", [2, 3])
def test_foo(x, y):
print("测试数据组合:x->%s, y->%s" % (x, y))
if __name__ == "__main__":
pytest.main(["-s", "test_canshu1.py"])
4. 下个接口请求参数依赖上个接口的返回数据 - 参数关联
这个很容易,不同的接口封装成不同的函数或方法,需要的数据 return 出来,用一个中间变量 a 去接受,后面的接口传 a 就可以了
参考这篇 python 接口自动化 26-参数关联和 JSESSIONID(上个接口返回数据作为下个接口请求参数
5. 依赖于登录的接口如何处理 -token 和 session 的管理
登录接口依赖 token 的,可以先登录后,token 存到一个 yaml 或者 json,或者ini 的配置文件里面,后面所有的请求去拿这个数据就可以全局使用了
参考之前分享的一篇 python 接口自动化 24-有 token 的接口项目使用 unittest框架设计
如果是 cookies 的参数,可以用 session 自动关联s=requests.session()后面请求用 s.get()和 s.post()就可以自动关联 cookies 了
6. 依赖第三方的接口如何处理 -mock 模拟数据返回
这个需要自己去搭建一个 mock 服务,模拟接口返回数据,参考python 笔记25-mock-server 之 moco
moco 是一个开源的框架,在 github 上可以下载到传送
moco 服务搭建需要自己能够熟练掌握,面试会问你具体如何搭建 ,如何模拟返回的数据,是用的什么格式,如何请求的
7. 不可逆的操作,如何处理,比如删除一个订单这种接口如何测试 -造数据
此题考的是造数据的能力,接口的请求数据,很多都是需要依赖前面一个状态的
比如工作流这种,流向不同的人状态不一样,操作权限不一样,测试的时候,每种状态都要测到,就需要自己会造数据了。
平常手工测试造数据,直接在数据库改字段状态。
那么自动化也是一样,造数据可以用 python 连数据库了,做增删改查的操作,
测试用例前置操作,setUp 做数据准备后置操作,tearDown 做数据清理
8. 接口产生的垃圾数据如何清理 - 数据清理
跟上面一样,造数据和数据清理,需用 python 连数据库了,做增删改查的操作
测试用例前置操作,setUp 做数据准备
后置操作,tearDown 做数据清理
9. 一个订单的几种状态如何全部测到,如:未处理,处理中,处理失败,处理成功 - 造数据,改数据库订单状态
如:未处理,处理中,处理失败,处理成功
跟上面一样,也是考察造数据,修改数据的状态
10. python 如何连接数据库操作?
这个就是详细的考察你是如何用 python 连数据库的,并且最好能现场写代码那种(有的笔试题就是 python 连数据库)
具体问你用到哪个模块,查询的数据是什么类型?如何删除数据?如何新增数据?如何修改数据?
PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2 中则使用 mysqldb。
详情参考教程 传送
#!/usr/bin/python3
# 查询 EMPLOYEE 表中 salary(工资)字段大于 1000 的所有数据:
import pymysql
# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )
# 使用 cursor()方法获取操作游标
cursor = db.cursor()
# SQL 查询语句
sql = "SELECT * FROM EMPLOYEE \
WHERE INCOME > %s" % (1000)
try:
# 执行 SQL 语句
cursor.execute(sql)
# 获取所有记录列表
results = cursor.fetchall()
for row in results:
fname = row[0]
lname = row[1]
age = row[2]
sex = row[3]
income = row[4]
# 打印结果
print ("fname=%s,lname=%s,age=%s,sex=%s,income=%s" % \
(fname, lname, age, sex, income ))
except:
print ("Error: unable to fetch data")
# 关闭数据库连接
db.close()
其它的就是运行出报告、代码管理(git)、运行策略和持续集成 jenkins 相关了,这个所以的自动化但是一样的,后面会单独讲一篇 jenkins 持续集成相关
注:此文参考上海悠悠-测试面试相关