接口测试(七)—— 参数化、数据库操作封装、接口自动化框架

news2024/9/29 7:26:55

目录

一、接口自动化测试框架

1、目录结构

二、封装iHRM登录

1、普通方式实现

2、登录接口对象层

3、登录接口测试用例层

4、封装断言方法

三、参数化

1、回顾UnitTest参数化 

1.1 原始案例

1.2 参数化实现

1.3 从json文件读取

2、登录接口参数化

2.1 组织数据文件

2.2 读取数据文件

2.3 使用 parameterized 实现参数化

四、员工管理接口

1、普通方法实现

2、接口对象层

3、接口测试用例层

4、数据库工具类封装

5、解决反复修改手机号

6、完整参数化步骤:添加员工接口参数化

7、获取请求头

8、提取项目目录

9、生成测试报告


一、接口自动化测试框架

1、目录结构

7 部分(5个目录、2个文件):

  • api/: 存储接口对象层(自己封装的 接口)
  • scripts/: 存储测试脚本层 (unittest框架实现的 测试类、测试方法)
  • data/: 存储 .json 数据文件
  • report/: 存储 生成的 html 测试报告
  • common/: 存储 通用的 工具方法
  • config.py: 存储项目的配置信息(全局变量)
  • run_suite.py: 组装测试用例、生成测试报告的 代码

二、封装iHRM登录

==登录接口==

1、普通方式实现

import unittest
import requests

class TestIhrmLogin(unittest.TestCase):

    # 测试方法1,登录成功
    def test01_login_success(self):
        # 组织url
        url = "http://ihrm-test.itheima.net/api/sys/login"
        header = {"Content-Type": "application/json"}
        json_data = {"mobile": "13800000002", "password": "123456"}
        resp = requests.post(url=url, headers=header, json=json_data)
        print("登录成功:", resp.json())

        # 断言
        self.assertEqual(200, resp.status_code)
        self.assertEqual(True, resp.json().get("success"))
        self.assertEqual(10000, resp.json().get("code"))
        self.assertIn("操作成功", resp.json().get("message"))

    # 测试方法2,密码错误
    def test02_pwd_err(self):
        # 组织url
        url = "http://ihrm-test.itheima.net/api/sys/login"
        header = {"Content-Type": "application/json"}
        json_data = {"mobile": "13800000002", "password": "123456789"}
        resp = requests.post(url=url, headers=header, json=json_data)
        print("密码错误:", resp.json())

        # 断言
        self.assertEqual(200, resp.status_code)
        self.assertEqual(False, resp.json().get("success"))
        self.assertEqual(20001, resp.json().get("code"))
        self.assertIn("用户名或密码错误", resp.json().get("message"))

2、登录接口对象层

1. 在 api/ 下,创建 ihrm_login_api.py 文件。
2. 在 文件内,封装 IhrmLoginApi 类,添加 login 类方法。
3. 安照 普通方式实现,分析。实现 login 类方法。

分析:

import requests

class IhrmLoginApi(object):

    # 登录方法
    @classmethod
    def login(cls, json_data):
        url = "http://ihrm-test.itheima.net/api/sys/login"
        header = {"Content-Type": "application/json"}
        resp = requests.post(url=url, headers=header, json=json_data)
        return resp

if __name__ == '__main__':
    data = {"mobile": "13800000002", "password": "123456"}
    resp = IhrmLoginApi.login(data)
    print(resp.json())

3、登录接口测试用例层

1. 在 scripts/ 下,创建 test_ihrm_login.py 文件
2. 在 文件内,创建 测试类 TestIhrmLogin 从 unittest.TestCase 继承
3. 添加 测试方法, 并实现

import unittest
from api.ihrm_login_api import IhrmLoginApi

class TestIhrmLogin(unittest.TestCase):

    # 登录成功
    def test01_login_success(self):
        # 组织请求数据
        json_data = {"mobile": "13800000002", "password": "123456"}
        # 调用自己封装的接口
        resp = IhrmLoginApi.login(json_data)
        print("登录成功:", resp.json())

        # 断言
        self.assertEqual(200, resp.status_code)
        self.assertEqual(True, resp.json().get("success"))
        self.assertEqual(10000, resp.json().get("code"))
        self.assertIn("操作成功", resp.json().get("message"))

    # 手机号为空
    def test02_mobile_none(self):
        # 组织请求数据
        json_data = {"mobile": None, "password": "123456"}
        # 调用自己封装的接口
        resp = IhrmLoginApi.login(json_data)
        print("手机号为空:", resp.json())

        # 断言
        self.assertEqual(200, resp.status_code)
        self.assertEqual(False, resp.json().get("success"))
        self.assertEqual(20001, resp.json().get("code"))
        self.assertIn("用户名或密码错误", resp.json().get("message"))

    # 密码错误
    def test03_pwd_err(self):
        # 组织请求数据
        json_data = {"mobile": "13800000002", "password": "123456890"}
        # 调用自己封装的接口
        resp = IhrmLoginApi.login(json_data)
        print("密码错误:", resp.json())

        # 断言
        self.assertEqual(200, resp.status_code)
        self.assertEqual(False, resp.json().get("success"))
        self.assertEqual(20001, resp.json().get("code"))
        self.assertIn("用户名或密码错误", resp.json().get("message"))

4、封装断言方法

1. 在 common/ 下,新建文件 assert_util.py 文件,
2. 在文件内,添加 函数 assert_util()
3. 在 函数内,实现通用的断言函数。
4. 在 测试方法中,使用 直接封装的 通用断言函数, 实现断言
 

# 定义 通用断言方法
def assert_util(self, resp, status_code, success, code, message):
    self.assertEqual(status_code, resp.status_code)
    self.assertEqual(success, resp.json().get("success"))
    self.assertEqual(code, resp.json().get("code"))
    self.assertIn(message, resp.json().get("message"))

使用断言方法

assert_util(self, resp, 200, True, 10000, "操作成功")
assert_util(self, resp, 200, False, 20001, "用户名或密码错误")
assert_util(self, resp, 200, False, 20001, "用户名或密码错误")

三、参数化

参数化的核心:数据驱动(用数据驱动测试用例执行)

  • 数据驱动:针对一个接口,只写一个测试方法。用一份测试数据文件,管理各个测试用例的测试数据。

参考文章:软件测试 —— Python(七)之UnitTest框架与测试报告 

1、回顾UnitTest参数化 

1.1 原始案例

import unittest

# 待 测试方法
def add(x, y):
    return x + y

class TestAdd(unittest.TestCase):
    def test01_add(self):
        res = add(10, 20)
        self.assertEqual(30, res)

    def test02_add(self):
        res = add(100, 200)
        self.assertEqual(300, res)

    def test03_add(self):
        res = add(1000, 20)
        self.assertEqual(1020, res)

1.2 参数化实现

实现步骤:
1. 导包 from parameterized import parameterized
2. 在通用测试方法上一行,添加 @parameterized.expand()
3. 给 expand() 传入 [(),(),()] 格式数据。( 调用 read_json_data() )
4. 修改 通用测试方法形参,按 数据中的 key 设计 参数。
5. 在 通用测试方法 内,使用形参

import unittest
from parameterized import parameterized

# 待 测试方法
def add(x, y):
    return x + y

data = [
{"x": 10, "y": 20, "except": 30},
{"x": 100, "y": 200, "except": 300},
{"x": 1000, "y": 20, "except": 1020},
{"x": 4, "y": 18, "except": 23}
]

# [{},{},{}] ---> [(),(),()]
def read_json_data():
    list_data = []
    for item in data:
        tmp = tuple(item.values())
        list_data.append(tmp)
    return list_data

class TestAdd(unittest.TestCase):
    # 通用测试方法(实现参数化)
    @parameterized.expand(read_json_data())
    def test_add(self, x, y, except_data):
        res = add(x, y)
        self.assertEqual(except_data, res)

1.3 从json文件读取

创建 json 文件,写入 [{},{},{}] 格式数据    

[
{"x": 10, "y": 20, "except": 30},
{"x": 100, "y": 200, "except": 300},
{"x": 1000, "y": 20, "except": 1020},
{"x": 4, "y": 18, "except": 22}
]

 修改 读取数据的 read_json_data 函数,添加 打开json文件,读数据的代码

# [{},{},{}] ---> [(),(),()]
def read_json_data():
    list_data = []
    # 从 .json 文件中,读取 [{},{},{}] 数据
    with open("./params_data.json", "r", encoding="utf-8") as f:
        data = json.load(f)
        for item in data:
            tmp = tuple(item.values())
            list_data.append(tmp)
    return list_data

2、登录接口参数化

2.1 组织数据文件

[
{
"desc": "登录成功",
"req_data": {
"mobile": "13800000002",
"password": "123456"
},
"stauts_code": 200,
"success": true,
"code": 10000,
"message": "操作成功"
},
{
"desc": "手机号为空",
"req_data": {
"mobile": null,
"password": "123456"
},
"stauts_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "密码错误",
"req_data": {
"mobile": "13800000002",
"password": "123456789"
},
"stauts_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "多参",
"req_data": {
"mobile": "13800000002",
"password": "123456",
"abc": "123"
},
"stauts_code": 200,
"success": true,
"code": 10000,
"message": "操作成功"
},
{
"desc": "少参",
"req_data": {
"password": "123456"
},
"stauts_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "无参",
"req_data": null,
"stauts_code": 200,
"success": false,
"code": 99999,
"message": "抱歉,系统繁忙,请稍后重试!"
},
{
"desc": "错误参数",
"req_data": {
"abc": "13800000002",
"password": "123456"
},
"stauts_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
}
]

2.2 读取数据文件

1. 在 common/ 下 创建 read_json_util.py 文件
2. 在 文件内,定义函数,从 json文件中读取数据,转换成 元组列表,返回

import json

# 定义函数,读取 data/xxx.json 文件
def read_json_data():
    with open("../data/ihrm_login.json", "r", encoding="utf-8") as f:
        json_data = json.load(f)
        list_data = []
        for item in json_data:
            tmp = tuple(item.values())
            list_data.append(tmp)
    # 这个 返回,坚决不能在 for 内
    return list_data

if __name__ == '__main__':
    ret = read_json_data()
    print(ret)
# 测试结果
[('登录成功', {'mobile': '13800000002', 'password': '123456'}, 200, True, 10000, '操作成功'), ('手
机号为空', {'mobile': None, 'password': '123456'}, 200, False, 20001, '用户名或密码错误'), ('密码错
误', {'mobile': '13800000002', 'password': '123456789'}, 200, False, 20001, '用户名或密码错误'),
('多参', {'mobile': '13800000002', 'password': '123456', 'abc': '123'}, 200, True, 10000, '操作成
功'), ('少参', {'password': '123456'}, 200, False, 20001, '用户名或密码错误'), ('无参', None, 200,
False, 99999, '抱歉,系统繁忙,请稍后重试!'), ('错误参数', {'abc': '13800000002', 'password':
'123456'}, 200, False, 20001, '用户名或密码错误')]

2.3 使用 parameterized 实现参数化

步骤:
1. 导包 from parameterized import parameterized
2. 在 通用测试方法上一行,添加 @parameterized.expand()
3. 给 expand() 传入 元组列表数据( 调用 自己封装的 读取 json 文件的 函数 read_json_data() )
4. 修改 通用测试方法形参,与 json 数据文件中的 key 一致。
5. 在 通用测试方法内,使用形参

import unittest
from api.ihrm_login_api import IhrmLoginApi
from common.assert_util import assert_util
from common.read_json_util import read_json_data
from parameterized import parameterized

"""
1. 导包 from parameterized import parameterized
2. 在 通用测试方法上一行,添加 @parameterized.expand()
3. 给 expand() 传入 元组列表数据( 调用 自己封装的 读取 json 文件的 函数 read_json_data() )
4. 修改 通用测试方法形参,与 json 数据文件中的 key 一致。
5. 在 通用测试方法内,使用形参
"""
class TestIhrmLogin(unittest.TestCase):
    # 通用测试方法(实现参数化)
    @parameterized.expand(read_json_data())
    def test_login(self, desc, req_data, stauts_code, success, code, message):
        # 调用自己封装的接口
        resp = IhrmLoginApi.login(req_data)
        print(desc, ":", resp.json())
        # 断言
        assert_util(self, resp, stauts_code, success, code, message)

四、员工管理接口

1、普通方法实现

import requests

# 添加员工
url = "http://ihrm-test.itheima.net/api/sys/user"
header = {"Content-Type": "application/json", "Authorization": "Bearer b040daed-39c1-4302-8777-f950770c8a26"}
json_data = {
    "username": "业务猪001",
    "mobile": "13978734783",
    "workNumber": "9527"
} 
resp = requests.post(url=url, headers=header, json=json_data)
print("添加员工:", resp.json())

# 查询员工
url_query = "http://ihrm-test.itheima.net/api/sys/user/1469566449784717312"
header_query = {"Content-Type": "application/json","Authorization": "Bearer b040daed-39c1-4302-8777-f950770c8a26"}
resp_query = requests.get(url=url_query, headers=header_query)
print("查询员工:", resp_query.json())

# 修改员工
url_modify = "http://ihrm-test.itheima.net/api/sys/user/1469566449784717312"
header_modify = {"Content-Type": "application/json","Authorization": "Bearer b040daed-39c1-4302-8777-f950770c8a26"}
modify_data = {"username": "齐天大圣"}
resp_modify = requests.put(url=url_modify, headers=header_modify, json=modify_data)
print("修改员工:", resp_modify.json())

# 删除员工
url_del = "http://ihrm-test.itheima.net/api/sys/user/1469566449784717312"
header_del = {"Content-Type": "application/json","Authorization": "Bearer b040daed-39c1-4302-8777-f950770c8a26"}
resp_del = requests.delete(url=url_del, headers=header_del)
print("删除员工:", resp_del.json())

2、接口对象层

"""
员工管理模块的 接口对象层
"""
import requests

class IhrmEmpCURD(object):
    # 添加员工
    @classmethod
    def add_emp(cls, header, json_data):
        url = "http://ihrm-test.itheima.net/api/sys/user"
        resp = requests.post(url=url, headers=header, json=json_data)
        return resp

    # 查询员工
    @classmethod
    def query_emp(cls, emp_id, header):
        url = "http://ihrm-test.itheima.net/api/sys/user/" + emp_id
        resp = requests.get(url=url, headers=header)
        return resp

    # 修改员工
    @classmethod
    def modify_emp(cls, emp_id, header, modify_data):
        url = "http://ihrm-test.itheima.net/api/sys/user/" + emp_id
        resp = requests.put(url=url, headers=header, json=modify_data)
        return resp

    # 删除员工
    @classmethod
    def delete_emp(cls, emp_id, header):
        url = "http://ihrm-test.itheima.net/api/sys/user/" + emp_id
        resp = requests.delete(url=url, headers=header)
        return resp

if __name__ == '__main__':
    header = {"Content-Type": "application/json",
    "Authorization": "Bearer b040daed-39c1-4302-8777-f950770c8a26"}
    data_add = {
        "username": "业务猪001",
        "mobile": "13978734786",
        "workNumber": "9527"
    } 
    resp = IhrmEmpCURD.add_emp(header, data_add)
    print("添加:", resp.json())
    emp_id = "1469572901224054784"
    resp = IhrmEmpCURD.query_emp(emp_id, header)
    print("查询:", resp.json())
    data = {"username": "齐天大圣"}
    resp = IhrmEmpCURD.modify_emp(emp_id, header, data)
    print("修改:", resp.json())
    resp = IhrmEmpCURD.delete_emp(emp_id, header)
    print("删除:", resp.json())

3、接口测试用例层

import unittest
from api.ihrm_emp_curd import IhrmEmpCURD
from common.assert_util import assert_util

class TestEmpAdd(unittest.TestCase):
    # 必选参数
    def test01_add_emp(self):
        # 准备数据
        header = {"Content-Type": "application/json",
                "Authorization": "Bearer b040daed-39c1-4302-8777-f950770c8a26"}
        json_data = {
            "username": "业务猪001",
            "mobile": "13978734787",
            "workNumber": "9527"
        } 

        #调用自己封装的 接口
        resp = IhrmEmpCURD.add_emp(header, json_data)
        print("添加-必选:", resp.json())

        # 断言
        assert_util(self, resp, 200, True, 10000, "操作成功")

    # 组合参数
    def test02_add_emp(self):
        # 准备数据
        header = {"Content-Type": "application/json",
                "Authorization": "Bearer b040daed-39c1-4302-8777-f950770c8a26"}
        json_data = {
            "username": "业务猪001",
            "mobile": "13978743801",
            "workNumber": "9527",
            "formOfEmployment": "2"
        } 

        #调用自己封装的 接口
        resp = IhrmEmpCURD.add_emp(header, json_data)
        print("添加-组合:", resp.json())

        # 断言
        assert_util(self, resp, 200, True, 10000, "操作成功")

    # 全部参数
    def test03_add_emp(self):
        # 准备数据
        header = {"Content-Type": "application/json",
                "Authorization": "Bearer b040daed-39c1-4302-8777-f950770c8a26"}
        json_data = {"username": "大猪乔治",
            "mobile": "13899078431",
            "timeOfEntry": "2021-12-01", "formOfEmployment": 1,
            "workNumber": "777888", "departmentName": "测试",
            "departmentId": "1452603344685203456",
            "correctionTime": "2021-12-30T16:00:00.000Z"}

        # 调用自己封装的 接口
        resp = IhrmEmpCURD.add_emp(header, json_data)
        print("添加-全部:", resp.json())

        # 断言
        assert_util(self, resp, 200, True, 10000, "操作成功")

4、数据库工具类封装

1. 在 common/ 下,创建 db_util.py 文件
2. 在 文件内, 实现 数据库 工具类及常用的数据库操作方法(查、增删改)

import pymysql

# 封装数据库工具类
class DBUtil(object):
    # 添加类属性
    conn = None

    @classmethod
    def __get_conn(cls):
        # 判断 conn 是否为空,如果是,再创建
        if cls.conn is None:
            cls.conn = pymysql.connect(host="211.103.136.244", port=7061, user="student",
                                        password="iHRM_student_2021", database="test_db",
charset="utf8")
        # 返回 非空连接
        return cls.conn

    @classmethod
    def __close_conn(cls):
        # 判断,conn 不为空,需要关闭。
        if cls.conn is not None:
            cls.conn.close()
            cls.conn = None

    # 常用方法:查询一条
    @classmethod
    def select_one(cls, sql):
        cursor = None
        res = None
        try:
            # 获取连接
            cls.conn = cls.__get_conn()
            # 获取游标
            cursor = cls.conn.cursor()
            # 执行 查询语句
            cursor.execute(sql)
            # 提取一条结果
            res = cursor.fetchone()
        except Exception as err:
            print("查询sql错误:", str(err))
        finally:
            # 关闭游标
            cursor.close()
            # 关闭连接
            cls.__close_conn()
            # 将查询sql执行的 结果,返回
            return res

    # 常用方法:增删改
    @classmethod
    def uid_db(cls, sql):
        cursor = None
        try:
            # 获取连接
            cls.conn = cls.__get_conn()
            # 获取游标
            cursor = cls.conn.cursor()
            # 执行 uid 语句
            cursor.execute(sql)
            print("影响的行数:", cls.conn.affected_rows())
            # 提交事务
            cls.conn.commit()
        except Exception as err:
            # 回滚事务
            cls.conn.rollback()
            print("增删改 SQL 执行失败:", str(err))
        finally:
            # 关闭游标
            cursor.close()
            # 关闭连接
            cls.__close_conn()

if __name__ == '__main__':
    res = DBUtil.select_one("select * from t_book;")
    print("查询结果为:", res)
    DBUtil.uid_db("update t_book set is_delete = 1 where id = 1111;")

5、解决反复修改手机号

解决思路:
1. 在 添加员工 接口测试 前(setUp),指定一个要使用的手机号,做 删除 delete sql 实现!
2. 测试 添加员工 接口, 使用 这个手机号。
3. 在 添加员工 接口测试 后(tearDown),再次 删除 这个手机号。delete sql 实现!
4. 将 手机号 定义成 全局手机号, 存放在 config.py 文件中。 TEL = “13900231473”

class TestEmpAdd(unittest.TestCase):

    def setUp(self) -> None:
        # 删除手机号
        delete_sql = f"delete from bs_user where mobile = '{TEL}'"
        DBUtil.uid_db(delete_sql)

    def tearDown(self) -> None:
        # 删除手机号
        delete_sql = f"delete from bs_user where mobile = '{TEL}'"
        DBUtil.uid_db(delete_sql)

    # 必选参数
    def test01_add_emp(self):
        # 准备数据
        header = {"Content-Type": "application/json","Authorization": "Bearer b040daed-39c1-4302-8777-f950770c8a26"}
        json_data = {
            "username": "业务猪001",
            "mobile": TEL,
            "workNumber": "9527"
        } 
        #调用自己封装的 接口
        resp = IhrmEmpCURD.add_emp(header, json_data)
        print("添加-必选:", resp.json())
        # 断言
        assert_util(self, resp, 200, True, 10000, "操作成功")

    # 组合参数
    def test02_add_emp(self):
        # 准备数据
        header = {"Content-Type": "application/json","Authorization": "Bearer b040daed-39c1-4302-8777-f950770c8a26"}
        json_data = {
            "username": "业务猪001",
            "mobile": TEL,
            "workNumber": "9527",
            "formOfEmployment": "2"
        } 
        #调用自己封装的 接口
        resp = IhrmEmpCURD.add_emp(header, json_data)
        print("添加-组合:", resp.json())
        # 断言
        assert_util(self, resp, 200, True, 10000, "操作成功")

    # 全部参数
    def test03_add_emp(self):
        # 准备数据
        header = {"Content-Type": "application/json","Authorization": "Bearer b040daed-39c1-4302-8777-f950770c8a26"}
        json_data = {
            "username": "大猪乔治",
            "mobile": TEL,
            "timeOfEntry": "2021-12-01", "formOfEmployment": 1,
            "workNumber": "777888", "departmentName": "测试",
            "departmentId": "1452603344685203456",
            "correctionTime": "2021-12-30T16:00:00.000Z"}
        # 调用自己封装的 接口
        resp = IhrmEmpCURD.add_emp(header, json_data)
        print("添加-全部:", resp.json())
        # 断言
        assert_util(self, resp, 200, True, 10000, "操作成功")

6、完整参数化步骤:添加员工接口参数化

完整参数化步骤:
1. 组织测试数据到 json 文件中。 格式 [{},{},{}]
2. 读取 json 数据文件中的 [{},{},{}] 数据,转换成 [(),(),()] 数据
3. 在 测试脚本中,借助 parameterized 实现参数化
        1. 导包 from parameterized import parameterized
        2. 在 通用测试方法上一行,添加 @parameterized.expand()
        3. 给 expand() 传入 元组列表数据( 调用 自己封装的 读取 json 文件的 函数 read_json_data() )
        4. 修改 通用测试方法形参,与 json 数据文件中的 key 一致。
        5. 在 通用测试方法内,使用形参


json 数据文件:

[
{
"desc": "必选参数",
"json_data": {
"username": "业务猪001",
"mobile": "13900043762",
"workNumber": "9527"
},
"stauts_code": 200,
"success": true,
"code": 10000,
"message": "操作成功"
},
{
"desc": "组合参数",
"json_data": {
"username": "业务猪001",
"mobile": "13900043762",
"workNumber": "9527",
"formOfEmployment": "2"
},
"stauts_code": 200,
"success": true,
"code": 10000,
"message": "操作成功"
},
{
"desc": "全部参数",
"json_data": {
"username": "大猪乔治",
"mobile": "13900043762",
"timeOfEntry": "2021-12-01",
"formOfEmployment": 1,
"workNumber": "777888",
"departmentName": "测试",
"departmentId": "1452603344685203456",
"correctionTime": "2021-12-30T16:00:00.000Z"
},
"stauts_code": 200,
"success": true,
"code": 10000,
"message": "操作成功"
}
]

7、获取请求头

1. 在 common/ 下 创建 get_header.py 文件
2. 在 文件内 创建 get_header() 函数,实现 登录成功,获取令牌,拼接成 请求头,返回。
3. 在 scripts/ 的测试脚本文件中,添加 setUpClass 方法,调用 get_header() 函数。 将返回值 保存到 类属性上
4. 在 使用 请求头的位置,直接从类属性获取

# 在 common/ 下 创建 get_header.py 文件 实现 get_header 函数
import requests

def get_header():
    url = "http://ihrm-test.itheima.net/api/sys/login"
    data = {"mobile": "13800000002", "password": "123456"}
    resp = requests.post(url=url, json=data)
    print(resp.json())
    # 从 响应体中,获取 data的值
    token = resp.json().get("data")
    header = {"Content-Type": "application/json","Authorization": "Bearer " + token}
    return header



# 在 scripts/ 的测试脚本文件中,添加 setUpClass 方法,调用 get_header 函数。 
# 将返回值 保存到 类属性上
from common.get_header import get_header
class TestEmpAdd(unittest.TestCase):
    # 类属性
    header = None
    @classmethod
    def setUpClass(cls) -> None:
        cls.header = get_header()



# 在 使用 请求头的位置,直接从类属性获取
resp = IhrmEmpCURD.add_emp(self.header, json_data)

8、提取项目目录

相关知识:

  • __file__ : 获取 当前文件的 绝对路径。
  • BASE_DIR = os.path.dirname(__file__) : 获取 到 当前文件的 上一级目录。
    • 此行代码,写在 config.py 中, 可以直接获取 项目目录

 项目中使用:

​​​​​​​1. 在 config.py 文件中,添加 获取项目路径 全局变量 BASE_DIR = os.path.dirname(__file__)
2. 修改 common/ 下 read_json_util.py 文件中,读取 json 文件 函数read_json_data(),添加 参数 path_filename
3. 在 使用 read_json_data()函数 时, 拼接 json 文件路径, 传入到 函数中。

9、生成测试报告

参考文章:软件测试 —— Python(七)之UnitTest框架与测试报告

步骤:
1. 创建测试套件实例。 suite
2. 添加 测试类
3. 创建 HTMLTestReport 类实例。 runner
4. runner 调用 run(), 传入 suite


实现:

import unittest
from config import BASE_DIR
from scripts.test_emp_add_params import TestEmpAddParams
from scripts.test_ihrm_login_params import TestIhrmLoginParams
from htmltestreport import HTMLTestReport

# 1. 创建测试套件实例。 suite
suite = unittest.TestSuite()

# 2. 添加 测试类, 组装测试用例
suite.addTest(unittest.makeSuite(TestIhrmLoginParams))
suite.addTest(unittest.makeSuite(TestEmpAddParams))

# 3. 创建 HTMLTestReport 类实例。 runner
# runner = HTMLTestReport(BASE_DIR + "/report/ihrm.html") # 绝对路径
runner = HTMLTestReport("./report/ihrm.html", description="描述", title="标题") # 相对路径

# 4. runner 调用 run(), 传入 suite
runner.run(suite)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/96721.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ArcGIS:如何进行离散点数据插值分析(IDW)、栅格数据的重分类、栅格计算器的简单使用、缓冲区分析、掩膜?

目录 01 说明 02 实验目的及要求 03 实验设备及软件平台 04 实验内容与步骤 4.1 反距离权重插值分析 4.2 多栅格局域运算 4.3 按表格显示分区统计 4.4 重分类 4.5 邻域运算 4.6 矢量数据的裁剪 4.7 缓冲区分析及栅格数据提取分析 05 思考及讨论 01 说明 由于这次的作业是从word…

jsp+ssm计算机毕业设计宠物寻回系统【附源码】

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: JSPSSM mybatis Maven等等组成,B/S模式 Mave…

2.两数相加

正在建设中 传送门: https://leetcode.cn/problems/add-two-numbers/ 题目描述 给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。 请你将两个数相加,并以相同形…

git 进阶系列教程-------git使用流程

GIT使用流程 前言 初衷 git是一门很容易入门的项目管理工具,但是它是一门很难精通的技术。 git pull/git add ./git commit -m "message"/git push/......知道以上几个命令,或许再多一点,也许就能说:‘我会git’了。…

IDEA画UML类图

第一步(IDEA下载画图插件) PlantUML Integration 插件可以支持画图 第二步(创建类图文件) 点击之后会让选择 选择class即可 类图的语法 在画类图的时候分为五种 1. 依赖 依赖分为好多种, 作为成员变量,作为方法的入参和出参,在类中使用…

【JSP菜鸟教程】

简介 JSP是一种Java servlet&#xff0c;主要用于实现Java web应用程序的用户界面部分。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。 Scriptlet脚本小程序 如果你想在HTML中写Java代码&#xff0c;就需要将Java代码写入Scriptlet中&#xff0…

数据库实验一:数据定义与操作语言实验

实验一 数据定义与操作语言实验 实验 1.1 数据库定义实验 1.实验目的 理解和掌握数据库DDL语言&#xff0c;能够熟练地使用SQL DDL语句创建、修改和删除数据库、模式和基本表。 2.实验内容和要求 理解和掌握SQL DDL语句的语法&#xff0c;特别是各种参数的具体含义和使用方…

第十七届D2大会(I)

一、Web Compass-端内Web App解决方案揭秘 增强传统web端内方案&#xff0c;提供更好、更收敛的工程体验 二、自渲染跨端框架在字节跳动的实践与展望 基于Flutter Engine的二次开发 三、Qking&#xff1a;跨端JS引擎的深度探索与突破 常见js引擎&#xff0c;如&#xff1a;v8…

CSC7268

CSC7268概述: CSC7268是一款内置高压MOS的高性能、多工作模式的PWM控制芯片&#xff0c;内置多种保护机制。当系统为空载和轻载时&#xff0c;CSC7268采用Burst和Green控制模式可有效地减少了空载和轻载时的损耗。当系统为中载和重载时&#xff0c;芯片采用QR模式和CCM模式可有…

python基础: filter, lambda 函数表达式

filter(function or None, sequence)&#xff0c;其中sequence 可以是list ,tuple,string。这个函数的功能是过滤出sequence 中所有以元素自身作为参数调用function时返回True或bool(返回值)为True的元素并以列表返回. filter只能接受两个参(function,sequence) &#xff0c;其…

Biotin-PEG-SH,Biotin-PEG-Thiol,生物素PEG巯基PEG衍生物供应

英文名称&#xff1a;Biotin-PEG-Thiol&#xff0c;Biotin-PEG-SH 中文名称&#xff1a;生物素-聚乙二醇-巯基 生物素-PEG-SH通过与链霉亲和素或抗生物素结合进行聚乙二醇化&#xff0c;具有高亲和力和特异性。生物素通过稳定的酰胺连接物与线性PEG结合。它具有与马来酰亚胺选…

java 瑞吉外卖day3 公共字段自动填充 新增分类

公共字段自动填充 代码实现 1. TableField(fill FieldFill.INSERT)//插入时填充字段 private LocalDateTime createTime;TableField(fill FieldFill.INSERT_UPDATE)//插入和更新时填充字段 private LocalDateTime updateTime;TableField(fill FieldFill.INSERT) private Lo…

数据库实验六:存储过程实验

实验六 存储过程实验 实验6.1 存储过程实验 1.实验目的 ​ 掌握数据库PL/SQL编程语言&#xff0c;以及数据库存储过程的设计和使用方法。 2.实验内容和要求 ​ 存储过程定义&#xff0c;存储过程运行&#xff0c;存储过程更名&#xff0c;存储过程删除&#xff0c;存储过程…

[附源码]Python计算机毕业设计Django少儿节目智能推荐系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Oracle数据的备份和恢复

Oracle数据的备份和恢复 ​ 当我们使用一个数据库时,总希望数据是可靠的、正确的,但由于计算机系统的故障(硬件故障、软件故障、网络故障、进程故障和系统故障)影响数据库系统的操作,影响数据库中数据的正确性,甚至破坏数据库,使数据库中全部或部分数据丢失。因此当发生上述故…

logistic回归的标准化回归系数 计算方式

创建于&#xff1a;2022.12.17 修改于&#xff1a;2022.12.17 文章目录1、未标准化回归系数2、标准化回归系数3、两者的区别4、手动计算5、计算样例6、参考资料1、未标准化回归系数 通常我们在构建多因素回归模型时&#xff0c;方程中呈现的是未标准化回归系数&#xff0c;它是…

【财务】财务分析---管理报告体系搭建

财务分析体系搭建的是一个系统化的功能&#xff0c;涉及的业务面非常广&#xff0c;财务分析也能表现出清晰的数据&#xff0c;以此进行改善&#xff1b;本文作者详细分析了财务分析中的管理报告体系的搭建&#xff0c;我们一起来看一下。 一、理清核算、财报、管报、预算关系 …

java设计模式(下)

文章目录第六章 行为型模式(11种)6.1 观察者模式6.1.1 观察者模式介绍6.1.2 观察者模式原理6.1.3 观察者模式实现6.1.4 观察者模式应用实例6.1.5 观察者模式总结6.2 模板方法模式6.2.1 模板方法模式介绍6.2.2 模板方法模式原理6.2.3 模板方法模式实现6.2.4 模板方法模式应用实例…

计算机网络——PPP协议与HDLC协议

广域网 广域网通常跨接很大的1物理范围&#xff0c;所覆盖的范围从几十公里到几千公里&#xff0c;他能链接多个城市或者国家&#xff0c;并且横跨几个州并能提供远距离通信。 广域网的通信子网使用的分组交换技术&#xff0c;广域网的通信子网可以利用公用分局交换网&#xf…

我也“阳”了

大家好&#xff0c;我是哪吒&#xff0c;我也“阳”了&#xff0c;现在是北京时间2022年12月17日 18:36&#xff0c;这篇文章简单说一下我“阳”了的经历和感受。 昨天下午&#xff0c;发现嗓子疼&#xff0c;不舒服&#xff0c;喝了很多茶水&#xff0c;喝了一瓶蓝芩口服液&a…