1. 实例讲解-新增
接口自动化没有setup,teardown,直接调用接口即可。
测试场景:新增栏目接口
思路:新增栏目(post)->查询栏目(get)->断言
断言有2种思路:
(1) 获取新增后的栏目列表,取最新值[-1],与新增的栏目进行比较
(2) 思路1存在不严谨的地方(万一新增栏目后,通过其他途径也同时新增了栏目,就会出现断言结果不准确的现象),所以可以在新增栏目后面加时间戳,然后在栏目列表中查找是否存在新增的带时间戳的栏目
说明:
-
接口自动化核心在于断言,如果请求接口后直接有明显的返回值,比如会返回“成功”、用户名等信息时,可以直接断言返回结果
-
如果返回值中没有明确信息,则需要重新查询(get)一下,看页面中是否存在我们想要的元素。一般有3种情况:
①新增后查询,看是否存在新增的信息
②修改后查询,看是否已正确修改
③删除后查询,看是否真的被删除 -
为了避免出现栏目中最新的值不是新添加的或本来就已经存在这样的值,可以有2种方法:
①程序写完之后实现闭环操作,即新增-修改-删除
②在新增的栏目后面加精确到秒的时间,时间永远不会重复
程序如下:
import unittest
import time
import requests
from public.get_cookie import get_cookie
class vblog_test(unittest.TestCase):
'''测试新增栏目接口'''
def test_new_catenames(self):
#新增
url_xinzeng = 'http://182.92.178.83:8081/admin/category/'
nowtime = time.time() #取当前的时间戳,秒级别
payload = {'cateName': 'lxh%d' % nowtime} #将时间戳拼到新增栏目后面
cookies = get_cookie()
global vblog_headers #将vblog_headers声明为全局变量,后续会用到
vblog_headers = {'Cookie': cookies}
requests.post(url_xinzeng, data=payload, headers=vblog_headers)
#查询
url_chaxun = 'http://182.92.178.83:8081/admin/category/all'
chaxun = requests.get(url_chaxun,headers=vblog_headers)
#断言方法1
exp = payload['cateName'] #预期输入值
act = chaxun.json()[-1]['cateName'] #查询到的所有栏目中最新的值
self.assertEqual(exp, act)
#断言方法2
exp = payload['cateName'] # 预期输入值
act = '123' #先随便赋给act一个值,如果在下面的列表中没有找到期望值,则act等于这个值
for catenameinfo in chaxun.json():
if catenameinfo['cateName']==exp:
global cateName_id #将cateName_id定义为全局变量,后续会用到
cateName_id = catenameinfo['id']
act='yes'
self.assertEqual('yes',act)
2. 实例讲解-编辑
变量在用例1中被定义,在其他用例中是不能使用的,如果想要使用,则需要将变量定义成全局变量,比如新增用例中的cateName_id被定义为了全局变量,就可在编辑的用例中直接使用cateName_id
import unittest
import time
import requests
from public.get_cookie import get_cookie
class vblog_test(unittest.TestCase):
def test_update_catename(self):
'''编辑栏目'''
#编辑
url_bianji = 'http://182.92.178.83:8081/admin/category/'
payload = {'id':cateName_id,'cateName':'啊啊啊啊11112'} #使用全局变量cateName_id
requests.put(url_bianji,data=payload,headers=vblog_headers) #使用全局变量vblog_headers
#查询
url_chaxun = 'http://182.92.178.83:8081/admin/category/all'
chaxun = requests.get(url_chaxun, headers=vblog_headers)
#断言
exp = payload['cateName'] #预期栏目
act = 'abc'
for catenameinfo in chaxun.json():
if catenameinfo['id']==cateName_id: #如果找到了编辑栏目的id,则将该栏目的cateName赋值给实际结果
act = catenameinfo['cateName']
self.assertEqual(exp,act)
3. main主函数执行顺序
main函数:
if __name__ == ‘__main__’:
unittest.main() #main函数主入口
- main函数执行先后顺序:执行以test开头,比较字符串大小,字符串从小到大执行,比如test_a比test_b先执行。
- 所以建议在case名称前加上序号(需要使用零填充),比如test_0001_b会比test_0002_a先执行。
4. __name__含义
- 一个py文件,当被别的py文件导入时,导入意味着被执行,if name == ‘main’能够使被导入的模块case不执行。
- 当运行if name == ‘main’时,本文件的case才会执行,当被其他模块导入的时候,if语句不满足,case不执行,但自定义函数和类都能正常被导入。
- name__是模块的基本属性,在本文件中就等于字符串__main,在被导入后就等于包名.模块名
5. unittest框架
接口自动化框架和UI自动化一样,如下:
最后执行testrunner.py文件后生成测试报告如下:
6.工具使用总结
Postman/jmeter/request都是针对接口的,postman更多被用来做接口的功能测试,jmeter重点做性能测试,request重点用来做接口自动化,三种工具各有特色,共同的特点是都能做接口功能测试,只是偏重点不一样。