接口测试
1、 接口文档示例:
https://docs.open.alipay.com/api_9/alipay.user.info.auth
http://wiki.open.qq.com/wiki/v3/user/get_info
2. http请求报文格式 与 http响应报文格式
3. GET请求报文 与 POST请求报文
4. 响应报文
5. 接口测试的原则:
- 一个中心:
接口以能服务最终产品为中心,测试前了解开发人员对于产品功能的实现方式,所设计的接口以及其他服务是否覆盖了全部产品功能,有无功能遗漏。各接口和各服务集成后的衔接协作是否断续的可能。总的来说就是从整体架构方面去考虑哪些环节容易出bug
- 两个基本点:
开发逻辑:必须清楚接口的工作原理,根据code review或开发的描述,得出读取什么表的数据,以什么样的逻辑运算后,输出什么数据
业务逻辑:必须清楚接口在整个业务流所处的位置,清晰接口所映射的最终页面,根据业务场景,得出测试场景
这两个基本点就是接口测试里测试需要做的基本功
- 四项基本原则:
充分测试:使用充分的测试数据覆盖各个可能发生的业务分支
接口单元化、解耦:尽量通过mock减少接口对于上游接口或数据的依赖性
用例独立、解耦:单条用例独立维护自己的前置场景,测试数据
可读易维护:用例中的无复杂的代码逻辑,使case代码结构化模板化,尽量使case代码所表达的测试场景直观、易读。
6. 人对于接口的测试行为
第一步:理解业务需求,一般来说可以从需求理解接口的行为和描述,行为:当什么情况,做什么操作,发生什么事情。描述:情况是什么,操作是什么等
第二步:查看(评审)接口文档的入参和返回是不是符合需求描述
第三步:根据业务需求构造前置数据
第四步:根据接口文档的入参请求接口
第五步:查看返回值是不是符合需求行为和描述,对于接口有更新数据库的行为还要检查数据库的变化是否符合需求描述
###################################################################
###################################################################
GET类型的接口自动化case编写步骤:
- 1、通过直接读写数据库或者调用上游接口制造测试数据或重用数据库现有数据
- 2、定义发起请求的数据
- 3、定义预期返回数据(一般返回数据是json)
- 4、使用requests类库发起请求接口
- 5、断言比对接口返回的json和定义预期返回数据是不是一样
- 6、测试过程中产生的测试数据
POST类型的接口自动化case编写步骤:
- 1、定义发起请求的数据
- 2、定义预期返回数据(一般返回数据是json)
- 3、由于post接口会对数据库有操作仅仅查看接口返回值不足以证明接口行为的正确性所以还要定义一个字典表示数据库中的预期数据
- 4、使用requests类库发起请求接口
- 5、断言比对接口返回的json和定义的字典数据是不是一样
- 6、断言比对数据库中的实际数据库和数据库中的预期数据是不是一样
- 7、清理测试过程中产生的测试数据
from flask import Flask, jsonify, request import json app = Flask(__name__) users = { "zhangsan" : {"name":"zhangsan", "age":"25", "sex":1}, "lisi" : {"name":"lisi", "age":"30", "sex":2} } @app.route("/get_user", methods=["GET"]) def get_user(): name = request.args.get("name") return jsonify(users[name]) @app.route("/add_user", methods=["POST"]) def add_user(): user = request.get_data() user_dict = json.loads(user) users[user_dict["name"]]=user_dict return jsonify({"status":"sucess"}) @app.route("/delete_user", methods=["GET"]) def delete_user(): name = request.args.get("name") users.pop(name) return jsonify({"status":"ok"}) if __name__ == '__main__': app.run(host="0.0.0.0", port="5000")
# coding: utf-8 import unittest import requests import json class AutoTest(unittest.TestCase): def setUp(self): self.domain = "http://127.0.0.1:5000" self.add_user_url = "%s/add_user" % self.domain self.get_user_url = "%s/get_user" % self.domain self.add_user_data = {"name":"wangwu", "age":35, "sex":"1"} def test_01(self): """ 1、用户可以被成功的添加到系统中 """ params = {"name": "wangwu"} # 先获取wangwu获取不到 r = requests.get(self.get_user_url, params=params) self.assertEqual(r.status_code, 500) # 将wangwu添加到系统中 r = requests.post(self.add_user_url, data=json.dumps(self.add_user_data), headers={"Content-Type": "application/json"}) self.assertDictEqual(r.json(), {"status":"sucess"}) # 添加到系统中的wangwu可以被获取到 r = requests.get(self.get_user_url, params=params) self.assertDictEqual(r.json(), {"name":"wangwu", "age":35, "sex":"1"}) def tearDown(self): self.delete_user_url = "%s/delete_user" % self.domain params = {"name":"wangwu"} r = requests.get(self.delete_user_url, params=params) self.assertDictEqual(r.json(), {"status":"ok"}) if __name__ == '__main__': unittest.main()