pytest之接口自动化实践

一.搭建接口自动化测试框架

目录分层:
1.common:放置常用公共方法,例如:操作yaml文件的模块、读取配置文件模块等
2.config:存放配置文件:例如:config.ini文件
3.logs:存放日志文件
4.report:存放生成的报告
5.tmep:allure生成的json报告,通过它来生成最终的报告
6.testcase:测试用例所在的目录
7.data:以yaml的方式放测试用例数据
8.extract.yaml:存放用例之间数据关联的数据
9.pytest.ini:pytest的配置文件
10.main.py:主调用入口

二、具体实现和代码

  1. 测试用例

【难点】
数据驱动:
-参数化:@pytest.mark.parametrize()
-数据读取:yaml保存用例数据,通过封装的读取yaml的方法来获取测试数据,通过写入yaml文件是实现用例之间数据关联
公共变量:在congfig下创建config.ini,里面保存公共变量

import pytest
import logging
import json
import requests
import time
# from common.login import login
from common.merge import Merge
from common.yaml_util import yamlUtil
from common.readconfig import readconfig


# login = login()


log = logging.getLogger()

@pytest.fixture(scope="module")
def login():
  log.info("...........登录获取token...........")
  args = yamlUtil().read_extract_yaml("/Users/dongshuai/PycharmProjects/interface/testcase/data/stu_login_data.yaml")
  url = args[0]["url"]
  palyloads = json.dumps(args[0]["payload"])
  headers = args[0]["headers"]
  res = requests.post(url=url,headers=headers,data=palyloads)
  header_token = {}
  header_token["token"] = json.loads(res.text)["data"]["token"]
  header_token["requestid"] = str(int(time.time()))
  yield header_token

  log.info("...........登录完获取token返回...........")


class Test_observatory():

    def setup_class(self):
        # yamlUtil().clear_yaml("/Users/dongshuai/PycharmProjects/interface/extract.yaml")
        yamlUtil().clear_yaml(readconfig("test","file_extract.yaml"))
        log.info("\n.....................模块observatory开始.....................")

    def teardown_class(self):
        log.info("\n.....................模块observatory结束.....................")


    # @pytest.mark.parametrize("args",yamlUtil().read_extract_yaml("/Users/dongshuai/PycharmProjects/interface/testcase/data/MicroClassList.yaml"))
    @pytest.mark.parametrize("args",yamlUtil().read_extract_yaml(readconfig("test","file_MicroClassList.yaml")))
    def test_MicroClassList(self,args,login):
        log.info('..........'+args["interfaceName"]+"..........")
        url = args["url"]
        payload = json.dumps(args["payload"])
        headers = Merge(args["headers"],login) #合并字典
        res = requests.post(url=url,headers=headers,data=payload)
        res_text = json.loads(res.text)
        # yamlUtil().write_extract_yaml(res_text["data"]["list"][0]["resid"])

        #判断用例中ecode是否为true,是的话,就将提取数据存入yaml
        print(args["validata"]["first"])

        if args["validata"]["first"] == True:   #这里的True得写成bool的而不是str的
            map = {}
            print(res_text)
            if res_text["data"]["list"][0]["resid"]:
                map["resid"]=res_text["data"]["list"][0]["resid"]
            yamlUtil().write_extract_yaml(map)
        assert json.loads(res.text)["meta"]["ecode"] == args["validata"]["ecode"],res.text

    # @pytest.mark.parametrize("args",yamlUtil().read_extract_yaml("/Users/dongshuai/PycharmProjects/interface/testcase/data/KnowledgeList.yaml"))
    @pytest.mark.parametrize("args",yamlUtil().read_extract_yaml(readconfig('test',"file_KnowledgeList.yaml")))
    def test_Knowledge_list(self,args):
        # log.info('..........'+args["interfaceName"]+"..........")
        # value = yamlUtil().read_extract_yaml("/Users/dongshuai/PycharmProjects/interface/extract.yaml")
        value = yamlUtil().read_extract_yaml(readconfig("test","file_extract.yaml"))



        print(value)





if __name__ == '__main__':
    pytest.main(["-vs"])

  1. 测试数据

#用例1:
-
 interfaceName: 用例1-推荐微课列表

 url: http://stupad-stress.xk12.cn/api/pad/v1/observatory/microlist
 payload: {
  "isfirst": 1,
  "kid": 1734,
  "ktype": 1,
  "pagesize": 10,
  "vs": "2.12.0.2-debug",
  "vc": 981,
  "ua": "OKAY_EBOOK_S4_OKUI_5.2.0.0_20200518_T",
  "os": "Galileo",
  "sw": "1280",
  "sh": "800",
  "iccid": "89860617030077789660",
  "serial": "f31eda17",
  "channel": "pad",
  "udid": "A63330A4258DF59B72E6863C88DFDE68",
  "screen_pattern": "1",
  "imei": "0",
  "mac": "02:00:00:00:00:00",
  "contype": 3
}

 headers: {
  'Content-Type': 'application/json',
  'requestid': '021619190842',
  'token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiI4OTg2MyIsInN5c3RlbUlkIjoiODE5NTEwNTU3NDEiLCJvcmdJZCI6IjgwIiwidGltZXN0YW1wIjoiMTYxOTE5MDc1NTEwMCJ9.rmQYKPvEgA0OvGwnpEsNJ4dP8qPKMZOhvu_k1g1n8Fg'
}

 validata: {
        "ecode": 0,
        "emsg": "",
        "debug": null,
        "first": true
    }


#用例2:
-
 interfaceName: 用例2-推荐微课列表

 url: http://stupad-stress.xk12.cn/api/pad/v1/observatory/microlist
 payload: {
  "isfirst": "",
  "kid": 1734,
  "ktype": 1,
  "pagesize": 10,
  "vs": "2.12.0.2-debug",
  "vc": 981,
  "ua": "OKAY_EBOOK_S4_OKUI_5.2.0.0_20200518_T",
  "os": "Galileo",
  "sw": "1280",
  "sh": "800",
  "iccid": "89860617030077789660",
  "serial": "f31eda17",
  "channel": "pad",
  "udid": "A63330A4258DF59B72E6863C88DFDE68",
  "screen_pattern": "1",
  "imei": "0",
  "mac": "02:00:00:00:00:00",
  "contype": 3
}

 headers: {
  'Content-Type': 'application/json',
  'requestid': '021619190842',
  'token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiI4OTg2MyIsInN5c3RlbUlkIjoiODE5NTEwNTU3NDEiLCJvcmdJZCI6IjgwIiwidGltZXN0YW1wIjoiMTYxOTE5MDc1NTEwMCJ9.rmQYKPvEgA0OvGwnpEsNJ4dP8qPKMZOhvu_k1g1n8Fg'
}


 validata: {
        "ecode": 0,
        "emsg": "",
        "debug": null,
        "first": true
    }


#用例3:
-
 interfaceName: 用例3-推荐微课列表

 url: http://stupad-stress.xk12.cn/api/pad/v1/observatory/microlist
 payload: {
  "kid": 1734,
  "ktype": 1,
  "pagesize": 10,
  "vs": "2.12.0.2-debug",
  "vc": 981,
  "ua": "OKAY_EBOOK_S4_OKUI_5.2.0.0_20200518_T",
  "os": "Galileo",
  "sw": "1280",
  "sh": "800",
  "iccid": "89860617030077789660",
  "serial": "f31eda17",
  "channel": "pad",
  "udid": "A63330A4258DF59B72E6863C88DFDE68",
  "screen_pattern": "1",
  "imei": "0",
  "mac": "02:00:00:00:00:00",
  "contype": 3
}

 headers: {
  'Content-Type': 'application/json',
  'requestid': '021619190842',
  'token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiI4OTg2MyIsInN5c3RlbUlkIjoiODE5NTEwNTU3NDEiLCJvcmdJZCI6IjgwIiwidGltZXN0YW1wIjoiMTYxOTE5MDc1NTEwMCJ9.rmQYKPvEgA0OvGwnpEsNJ4dP8qPKMZOhvu_k1g1n8Fg'
}


 validata: {
        "ecode": 0,
        "emsg": "",
        "debug": null,
        "first": true
    }

#用例4:
-
 interfaceName: 用例4-推荐微课列表

 url: http://stupad-stress.xk12.cn/api/pad/v1/observatory/microlist
 payload: {
  "isfirst":"#",
  "kid": 1734,
  "ktype": 1,
  "pagesize": 10,
  "vs": "2.12.0.2-debug",
  "vc": 981,
  "ua": "OKAY_EBOOK_S4_OKUI_5.2.0.0_20200518_T",
  "os": "Galileo",
  "sw": "1280",
  "sh": "800",
  "iccid": "89860617030077789660",
  "serial": "f31eda17",
  "channel": "pad",
  "udid": "A63330A4258DF59B72E6863C88DFDE68",
  "screen_pattern": "1",
  "imei": "0",
  "mac": "02:00:00:00:00:00",
  "contype": 3
}

 headers: {
  'Content-Type': 'application/json',
  'requestid': '021619190842',
  'token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiI4OTg2MyIsInN5c3RlbUlkIjoiODE5NTEwNTU3NDEiLCJvcmdJZCI6IjgwIiwidGltZXN0YW1wIjoiMTYxOTE5MDc1NTEwMCJ9.rmQYKPvEgA0OvGwnpEsNJ4dP8qPKMZOhvu_k1g1n8Fg'
}


 validata: {
        "ecode": 0,
        "emsg": "",
        "debug": null,
        "first": true
    }
  1. 公共方法

yaml_util.py:

import yaml,os


'''
封装读取yaml的方法
'''
class yamlUtil():
    def __init__(self):
        pass

    # 读取yaml
    def read_extract_yaml(self,yaml_file):
        with open(yaml_file,encoding="utf-8") as f:
            value = yaml.load(f,Loader=yaml.FullLoader)
            # print(value)
            return value

    #写入yaml,做数据关联时用
    def write_extract_yaml(self,extract_dict):
        with open("/Users/dongshuai/PycharmProjects/interface/extract.yaml","a") as f:
            yaml.dump(extract_dict,f,allow_unicode=True)  #这里需要注意,不然保存的yaml中文是乱码
            f.close()


    #清空yaml数据
    def clear_yaml(self,text_path):
        with open(text_path, 'w') as f1:
            f1.seek(0)
            f1.truncate()
            print("清空yaml数据")



if __name__ == '__main__':
    yamlUtil().write_extract_yaml("斤斤计较军、")

readconfig.py:

import configparser
import os

'''
读取配置文件
'''

def readconfig(section,value):
    root_dir = os.path.abspath("../")

    cf = configparser.ConfigParser()
    cf.read(root_dir+"/config/config.ini")
    value = cf.get(section,value)
    return value

  1. main.py:
import pytest
import os

if __name__ == '__main__':
    pytest.main()
    os.system("cd "+os.getcwd()+" | allure generate ./temp -o ./report --clean")
  • 0
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值