接口自动化框架,参数化处理,db数据承载形式实现参数化

2022-06-30 08:08:42

1,接口自动化框架

        1.1框架结构

                接口测试框架的结构如下图所示:

接口测试框架的结构说明:
    - API 用来封装被测系统的接口
    - TestCase 将一个或者多个接口封装成测试用例,并使用UnitTest管理测试用例TestCase 可以调用数据库进行数据校验
    - 为了方便维护测试数据,可以把测试脚本和测试数据分离开
    - 通过UnitTest断言接口返回的数据,并生成测试报告

       1.2 框架目录结构

apiTestFramework  #项目名称
    -api   #package:定义封装被测系统的接口
    -script    #package:定义测试用例脚本
    -data    #dir:存放测试数据
    -report  #dir:存放生成测试报告
    -lib  #package:存放第三方的文件
    -setting.py #定义项目的配置信息
    -utils.py   #定义工具类
    -run_suite.py   #执行测试套件的入口

        1.3 封装TPShop登录接口案例

                按照功能模块定义封装被测系统的接口,方便测试脚本的调用,并且能够到达代码的复用,对登录功能的相关接口进行封装,示例代码:

# api/login.py
class LoginApi:
    def __init__(self):
        self.verify_code_url = "http://locolhost/index.php?m=Home&a=verify"
        self.login_url = "http://locolhost/index.php?m=Home&c=User&a=do_login"
    
    #获取验证码
    def get_login_verify_code(self,session):
        return session.get(self.verify_code_url)

    #登录
    def login(self,session,username,password,verify_code):
        # 发送请求
        data = {
            "username":username,
            "password":password,
            "verify_code":verify_code,
        }
        return session.post(self.login,data=data)

        1.4 登录测试用例

                将api模块中的一个或多个接口封装成一个测试用例,并使用测试框架UnitTest测试用例,定义登录功能的测试用例,示例代码:

class TestLogin(unittest.TestCase):

    @classmethod
    def setUpClass(cls) -> None:
        cls.login_api = LoginApi()

    def setUp(self) -> None:
        self.session = Session()

    def tearDown(self) -> None:
        self.session.close()

    #登录成功: 到底干了啥
        #发送请求(调api中的封装请求方法) --> 响应
        #断言
    def test_login_success(self):
        #获取验证码
        response = self.login_api.get_login_verify_code(self.seccion)
        #判断是否为图片类型
        self.assertIn("",response.headers.get("Content-Type"))
        #登录
        response = self.login_api.login(self.session,"13012345678","123456","8888")
        res = response.json()
        #断言
        self.assertEqual(200,res.status_code)
        self.assertEqual(1,res.get("status"))
        self.assertEqual("登陆成功",res.get("msg"))

    #账号不存在
    def test_login_username_not_exist(self):
        #获取验证码
        response = self.login_api.get_login_verify_code(self.seccion)
        #判断是否为图片类型
        self.assertIn("",response.headers.get("Content-Type"))
        #登录
        response = self.login_api.login(self.session,"13088888888","123456","8888")
        res = response.json()
        #断言
        self.assertEqual(200,res.status_code)
        self.assertEqual(-1,res.get("status"))
        self.assertEqual("账号不存在",res.get("msg"))
    #账号不存在
    def test_login_username_not_exist(self):
        #获取验证码
        response = self.login_api.get_login_verify_code(self.seccion)
        #判断是否为图片类型
        self.assertIn("",response.headers.get("Content-Type"))
        #登录
        response = self.login_api.login(self.session,"13012345678","error","8888")
        res = response.json()
        #断言
        self.assertEqual(200,res.status_code)
        self.assertEqual(-2,res.get("status"))
        self.assertEqual("密码错误",res.get("msg"))

        1.5 集成测试报告

                使用HTMLTestRunner生成HTML格式的测试报告

                注意:需要将HTMLTestRunner.py工具放置在lib中 (代码如下)

import time
import unittest
from script.test_login import TestLogin
from tools.HTMLTestRunner import HTMLTestRunner

suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestLogin))

#测试报告文件路径
report_file = "./report/report.html".format(time.strftime("%Y%m%d-%H%M%S")) with open(report_file,"wb") as f:
    # 创建HTMLTestRunner运行器
    runner = HTMLTestRunner(f,title="TPshop接口自动化测试报告",description="V1.0")
    # 运行测试条件
    runner.run(suite)

2,参数化处理

        2.1 参数化分析

1,分析需要参数化的参数,都有哪些?
    输入数据:用户名,密码,验证码
    预期结果:content_type,
            状态码,业务码,业务消息
2,选择数据承载格式
    json
    db
3,修改测试用例中的代码
    3.1 构建参数化数据(build_data)
    3.2 在测试用例前引用参数化(@parameter)
    3.3 在具体的测试用例中,按照获得的数据进行参数替换

        2.2 构建json文件存放测试数据(例如:下图)

[
  {
    "username": "13012345678",
    "password": "13579",
    "verify_code": "8888",
    "content_type":"image",
    "status_code":200,
    "status": 0,
    "msg": "账号或密码登陆错误"
  },
  {
    "username": "",
    "password": "13579",
    "verify_code": "8888",
    "content_type":"image",
    "status_code":200,
    "status": 0,
    "msg": "账号或密码登陆错误"
  },
  {
    "username": "13800000005",
    "password": "",
    "verify_code": "8888",
    "content_type":"image",
    "status_code":200,
    "status": 0,
    "msg": "账号或密码登陆错误"
  }
]

        2.3 构建参数化数据

def build_data():
    with open('./data/data.json','r',encoding='utf-8') as f:
        content = f.read()
    data = json.loads(content)
    d = []
    for item in data:
        d.append(
            (
                item["username"],
                item["password"],
                item["verify_code"],
                item["status_code"]
                item["status"],
                item["msg"]
            )
        )
    return d

        2.4 测试用例实现参数化

class TestLogin(unittest.TestCase):
    # 前置处理
    def setUp(self):
        self.login_api = LoginAPI() #实例化接口类
        self.session = requests.Session() #创建session对象
    # 后置处理
    def tearDown(self):
        if self.session:
            self.session.close()
    @parameterized.expand(build_data)
    # 创建测试用例
    def test01_login(self,username,password,verify_code,content_type,status_code,status,msg):
    #调用验证码接口获取验证,并进行断言
    response = self.login_api.get_verify_code(self.session)
    self.assertEqual(status_code,response.status_code)
    self.assertIn(status_type,response.headers.get("Content-Type"))

    #调用登录接口获取登录信息,并进行断言
    response = self.login_api.login(self.session,username,password,verify_code)
    self.assertEqual(status_code,response.status_code)
    self.assertEqual(status,response.json().get("status"))
    self.assertIn(msg,response.json().get("msg"))

3,db数据承载形式实现参数化

        3.1 构建数据库数据

                执行SQL脚本,将数据写入数据库中

        3.2 修改构建数据函数

def build_data():
    #获取数据库数据
    sql = "select * from t_login"
    db_data = DBUtil.exe_sql(sql)
    test_data = []
    for case_data in db_data:
        username = case_data[2]
        password = case_data[3]
        verify_code = case_data[4]
        content_type = case_data[5]
        status_code= case_data[6]
        status = case_data[7]
        msg = case_data[8]
        test_data.append(
            (
                username,password,verify_code,content_type,status_code,status,msg
            )
        )
    return test_data

        拓展(只获取列表中的字典中的指定字段)

def build_data():
    data_json = [{"username":"xxx","password":"123","age":12,"gender":"男"}] #假设有100多个键值对
    dic = {"username":"xxx","age":12} #只需要两个键值对
    list = []
    for i in data_json:
        dic = {"username":"","age":""}
        for key in dic:
            dic[key] = i["key"]
        list.append(dic)
  • 作者:立志做测开
  • 原文链接:https://blog.csdn.net/weixin_50851485/article/details/120716104
    更新时间:2022-06-30 08:08:42