接口测试进阶:IHRM登录接口自动化框架的封装与优化

张开发
2026/6/7 12:37:54 15 分钟阅读
接口测试进阶:IHRM登录接口自动化框架的封装与优化
1. 从零开始封装IHRM登录接口第一次接触接口自动化测试时我像大多数新手一样直接写了一大堆重复代码。直到有一天维护测试用例时发现要修改几十个相同接口的URL才意识到封装的重要性。下面我就用IHRM登录接口为例带你体验从原始代码到封装优化的完整过程。1.1 原始代码的痛点分析最开始的测试代码是这样的import unittest import requests class TestIhrmLogin(unittest.TestCase): def test01_login_success(self): url http://ihrm-test.itheima.net/api/sys/login header {Content-Type: application/json} json_data {mobile: 13800000002, password: 123456} resp requests.post(urlurl, headersheader, jsonjson_data) # 断言 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))这段代码有三个明显问题URL和header等固定参数在每个测试方法中重复编写断言逻辑重复且冗长测试数据硬编码在方法内部当测试场景增加到10种时你会发现修改任何一个接口参数都需要改动多处代码维护成本呈指数级增长。1.2 接口对象层封装我的解决方案是将接口调用逻辑抽离到单独的类中# api/ihrm_login_api.py import requests class IhrmLoginApi: classmethod def login(cls, json_data): url http://ihrm-test.itheima.net/api/sys/login header {Content-Type: application/json} return requests.post(urlurl, headersheader, jsonjson_data)封装后测试用例简化为from api.ihrm_login_api import IhrmLoginApi class TestIhrmLogin(unittest.TestCase): def test01_login_success(self): resp IhrmLoginApi.login({mobile: 13800000002, password: 123456}) # 断言保持不变...这种封装方式将变化的部分请求参数保留在测试用例中固定的部分URL、请求头封装在接口类中。当接口地址变更时只需修改ihrm_login_api.py文件即可。2. 测试用例层的优化实践2.1 通用断言方法封装在多个测试类中我发现断言逻辑高度重复。于是创建了assert_util.py# common/assert_util.py def assert_util(resp, status_code, success, code, message): assert resp.status_code status_code assert resp.json().get(success) success assert resp.json().get(code) code assert message in resp.json().get(message)使用方式from common.assert_util import assert_util assert_util(resp, 200, True, 10000, 操作成功)2.2 参数化测试数据当测试不同登录场景时传统做法是为每个场景写一个测试方法。使用parameterized可以实现数据驱动# test_data/login_cases.json [ { desc: 登录成功, req_data: {mobile: 13800000002, password: 123456}, status_code: 200, success: true, code: 10000, message: 操作成功 }, { desc: 密码错误, req_data: {mobile: 13800000002, password: wrong}, status_code: 200, success: false, code: 20001, message: 用户名或密码错误 } ]测试类改造from parameterized import parameterized class TestIhrmLogin(unittest.TestCase): parameterized.expand(load_json_data(login_cases.json)) def test_login(self, desc, req_data, status_code, success, code, message): resp IhrmLoginApi.login(req_data) assert_util(resp, status_code, success, code, message)3. 框架级别的优化技巧3.1 全局配置管理创建config.py集中管理配置项# config.py import os BASE_DIR os.path.dirname(os.path.abspath(__file__)) LOG_DIR os.path.join(BASE_DIR, logs) REPORT_DIR os.path.join(BASE_DIR, reports) # 测试数据路径 TEST_DATA { login: os.path.join(BASE_DIR, data/login_cases.json), employee: os.path.join(BASE_DIR, data/emp_cases.json) }3.2 数据库工具封装对于需要数据库校验的场景封装DBUtil# common/db_util.py import pymysql class DBUtil: classmethod def execute_query(cls, sql): conn pymysql.connect(hostdb.example.com, usertest, passwordtest123) try: with conn.cursor() as cursor: cursor.execute(sql) return cursor.fetchall() finally: conn.close()3.3 日志系统集成配置统一的日志记录# common/logger.py import logging from config import LOG_DIR def init_logger(name): logger logging.getLogger(name) handler logging.FileHandler(f{LOG_DIR}/{name}.log) formatter logging.Formatter(%(asctime)s - %(levelname)s - %(message)s) handler.setFormatter(formatter) logger.addHandler(handler) return logger4. 完整框架目录结构经过上述优化后项目结构如下ihrm_auto_test/ ├── api/ # 接口对象层 │ ├── ihrm_login_api.py │ └── ihrm_emp_api.py ├── common/ # 公共组件 │ ├── assert_util.py │ ├── db_util.py │ └── logger.py ├── data/ # 测试数据 │ ├── login_cases.json │ └── emp_cases.json ├── scripts/ # 测试脚本 │ ├── test_login.py │ └── test_emp.py ├── config.py # 配置中心 └── run.py # 执行入口这种架构下各层职责明确api层负责接口协议封装common层提供通用工具data层管理测试数据scripts层编写测试逻辑当需要新增测试接口时只需在api层添加接口类在data层准备测试数据在scripts层编写测试用例维护成本大幅降低新增接口的测试效率提升明显。我在实际项目中应用这套框架后接口回归测试时间从原来的2小时缩短到15分钟。

更多文章