从零开始写博客系统——测试我们的代码(接口测试)
背景
上文我们介绍了如何对我们的代码进行单元测试,本文我们来介绍接口测试。
相对于单元测试,接口测试属于一个更上层的测试,接口测试主要关注的是接口的输入和输出,并不关心代码内部运行的逻辑。
在实际的项目中,接口测试也是非常重要的,由于接口测试在实际的工作中非常常见。
接口测试前的准备
基于我们现在的框架,我们所有的接口全部都写在app.py
这个文件中,相比于单元测试,接口测试需要把服务运行起来。
我们进行接口测试的时候,同样使用unittest
进行测试用例的归档。
发起接口测试有非常多的办法,我们的服务是一个http
的服务,因此例如curl
命令,postman
等工具都可以进行接口请求,这里我们使用的是一个Python
的一个优秀的第三方库,叫 requests
。
我们先进入项目,安装这个库。pip install requests
. 同样的,如果网络状况不好,可以使用豆瓣源 pip install requests -i https://pypi.douban.com/simple/
接口测试
- 文本指测试
先在我们的test
目录下再新建一个文件叫test_api.py
。这个文件用于存放接口测试用例。我们先来尝试我们的hello world
接口。测试代码如下:
import unittest
import requests
class TestApi(unittest.TestCase):
def test_hello(self):
r = requests.get("http://127.0.0.1:5000/")
self.assertEqual(r.text, "Hello World!")
2
3
4
5
6
7
helloworld
这个接口返回的是一个字符串,因此我们验证返回的字符串是否相等。运行我们的测试用例。
python -m unittest test.test_api.TestApi.test_hello
.
----------------------------------------------------------------------
Ran 1 test in 0.011s
OK
2
3
4
5
6
第一个测试用例搞定了,后面的流程,就有点类似单元测试了,只不过区别是我们在服务运行起来的时候才能跑这个测试用例,而单元测试无需启动服务,才能执行测试用例。
- json数据
我们继续写下一条测试用例。这次是返回一个json
数据。
def test_article_list(self):
r = requests.get(url + "/article_list")
print(r.json())
2
3
在这里,我们先不进行断言,先把返回结果打出来。
python -m unittest test.test_api.TestApi.test_article_list
{'code': 0, 'data': {'articles': [{'author': '点点寒彬', 'category': '从零开始学博客', 'content': '我从2015年底开始慢慢的学习编码相关的知识。在这个博客我把自己学习的记录全部都记了下来,这么多年过去了,版本不停的在更替,当年的那个系列确实已经没啥参考意义了,并且受限于当时的水平,写出来的东西也没啥价值,甚至在某些时候会误导初学者,因此决定重新写一下这个系列的内容,如果可以的话,也配套录制一些视频,方便后来人学习。', 'created_time': '2022-04-01 11:12:21', 'id': 1, 'modified_time': '2022-04-23 11:12:21', 'tag': ['Python', 'Flask', '博客'], 'title': '开篇'}, {'author': '点点寒彬', 'category': '从零开始学博客', 'content': '关于Python的安装,环境变量等配置这里就不单独出文章了,网上有大量的文章可以参考。我使用的Mac电脑,使用Windows也是同样可以的。只不过某些配置可能略有差异。', 'created_time': '2022-04-05 11:12:21', 'id': 2, 'modified_time': '2022-04-23 11:12:21', 'tag': ['Python', 'Flask', '博客'], 'title': '环境搭建'}], 'total': 2}, 'msg': 'success'}
.
----------------------------------------------------------------------
Ran 1 test in 0.012s
OK
2
3
4
5
6
7
我们返回的数据是一个json
,所以我们直接用r.json()
方法把结果转成dict
格式,有了这个结果,我们就知道怎么断言了。于是我们把测试用例加上断言。
def test_article_list(self):
r = requests.get(url + "/article_list")
self.assertEqual(r.json()["code"], 0)
self.assertEqual(r.json()["data"]["total"], len(r.json()["data"]["articles"]))
2
3
4
这里我们需要验证返回码是否是0
,同时,需要确认返回的total
字段与实际articles
的长度是否一致。
python -m unittest test.test_api.TestApi.test_article_list
.
----------------------------------------------------------------------
Ran 1 test in 0.012s
OK
2
3
4
5
6
- 多接口联动
接下来,我们要写一条测试用例来验证我们新增的数据是否成功。那么这种功能就需要进行多接口的联动才能验证到结果。
- 请求查询接口查询现在的数据
- 请求新增接口
- 请求查询接口检查新增后的数据
因此我们这里会有3次的接口调用请求,我们需要在代码中把这三步的逻辑体现出来。代码如下 :
def test_add_article(self):
r = requests.get(url + "/article_list")
self.assertEqual(r.json()["code"], 0)
self.assertEqual(r.json()["data"]["total"], len(r.json()["data"]["articles"]))
ori_lengh = r.json()["data"]["total"]
# add
data = {"title": "test", "content": "test", "author": "test", "category": "test", "tag": ["test"]}
r = requests.post(url + "/add_article", json=data)
self.assertEqual(r.json()["code"], 0)
# qry
r = requests.get(url + "/article_list")
self.assertEqual(r.json()["code"], 0)
self.assertEqual(r.json()["data"]["total"], len(r.json()["data"]["articles"]))
now_length = r.json()["data"]["total"]
self.assertEqual(now_length - ori_lengh, 1)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
python -m unittest test.test_api.TestApi.test_add_article
.
----------------------------------------------------------------------
Ran 1 test in 0.020s
OK
2
3
4
5
6
总结
本文我们对自己博客的接口进行了接口测试,覆盖了不同类型的返回结果,但是它们的测试方式基本上大同小异,都是通过请求接口来判定结果是否符合预期。当然,根据不同的接口我们查询的次数可能是不一样的。
同样的,我把这部分代码也放在了:代码浏览 - blog - 从零开始写一个博客系统 - svenweng (coding.net)
思考
除了文章列的几个接口,我还写了一些代码里面,读者可以自行把剩下的接口测试用例补齐。