从0到1框架搭建,Python+Pytest+Allure+Git+Jenkins接口自动化框架(超细整理)

📅 发布时间:2026/7/5 16:58:41 👁️ 浏览次数:
从0到1框架搭建,Python+Pytest+Allure+Git+Jenkins接口自动化框架(超细整理)
前言接口测试是对系统和组件之间的接口进行测试主要是效验数据的交换传递和控制管理过程以及相互逻辑依赖关系。其中接口协议分为HTTPRPCWebserviceDubboRESTful等类型。接口测试流程1、需求评审熟悉业务和需求2、开发提供接口文档3、编写接口测试用例4、用例评审5、提测后开始测试6、提交测试报告两种常见的 HTTP 请求方法GET 和 POST框架是一套基于PythonPytestRequestsAllureJenkins而设计的数据驱动接口自动化测试的框架。技术栈Python、Pytest、Requests、Pactverity、Excel、Json、Mysql、Allure、Logbook、Git、Jenkins框架结构图项目功能PythonPytestAllureJenkins接口自动化框架实现Excel或Json维护测试用例支持数据库操作利用封装的请求基类调取相应的测试用例接口获取配置文件中的环境地址与环境变量结合Pytest进行单元测试使用LogBook进行记录日志并生成allure测试报告最后进行Jenkins集成项目实现集成部署并发送测试报告邮件。工具类封装1、日志模块项目中的log日志是logbook进行日志记录的方便测试开发调试时进行排错纠正或修复优化。日志可选择是否打印在屏幕上即运行时是否在终端输出打印。日志格式输出可调整。handle_log.py部分源码def log_type(record, handler): log [{date}] [{level}] [{filename}] [{func_name}] [{lineno}] {msg}.format( daterecord.time, # 日志时间 levelrecord.level_name, # 日志等级 filenameos.path.split(record.filename)[-1], # 文件名 func_namerecord.func_name, # 函数名 linenorecord.lineno, # 行号 msgrecord.message # 日志内容 ) return log # 日志存放路径 LOG_DIR BasePath /log print(LOG_DIR) if not os.path.exists(LOG_DIR): os.makedirs(LOG_DIR) # 日志打印到屏幕 log_std ColorizedStderrHandler(bubbleTrue) log_std.formatter log_type # 日志打印到文件 log_file TimedRotatingFileHandler( os.path.join(LOG_DIR, %s.log % log), date_format%Y-%m-%d, bubbleTrue, encodingutf-8) log_file.formatter log_type # 脚本日志 run_log Logger(global_log) def init_logger(): logbook.set_datetime_format(local) run_log.handlers [] run_log.handlers.append(log_file) run_log.handlers.append(log_std) return 打印在终端的日志如下图所示。同时运行项目后会在项目文件log中自动生成一个以当天日期命名的log文件。点击log日志文件可查看日志详情即项目运行时所记录的日志或报错日志。如下图所示。2、配置文件模块项目中涉及到一些配置文件如username、password或环境变量时我们可通过配置文件来获取配置值。通过配置文件中key与value的定义来确定获取配置文件的值。handle_init.py部分源码class HandleInit: # 读取配置文件 def load_ini(self): file_path BasePath /config/config.ini cf configparser.ConfigParser() cf.read(file_path, encodingUTF-8) return cf # 获取ini里面对应key的value def get_value(self, key, nodeNone): if node None: node Test cf self.load_ini() try: data cf.get(node, key) logger.info(获取配置文件的值node{},key{}, data{}.format(node, key, data)) except Exception: logger.exception(没有获取到对应的值node{},key{}.format(node, key)) data None return data获取配置文件中的值日志如下图所示。3、接口请求封装获取相关测试用例及接口用例配置记录请求相关参数的日志定义Allure测试报告的步骤。handle_apirequest.py部分代码class ApiRequest: def api_request(self, base_url, test_case_data, case_data): get_name None get_url None get_method None get_headers None get_cookies None get_case_name None get_case_params None response_data None try: get_name test_case_data[config][name] get_url base_url test_case_data[config][url] get_method test_case_data[config][method] get_headers test_case_data[config][headers] get_cookies test_case_data[config][cookies] except Exception as e: logger.exception(获取用例基本信息失败{}.format(e)) try: get_case_name case_data[name] get_case_params case_data[params] except Exception as e: logger.exception(获取测试用例信息失败{}.format(e)) with allure.step(请求接口%s,请求地址%s,请求方法%s,请求头%s,请求Cookies%s % ( get_name, get_url, get_method, get_headers, get_cookies)): allure.attach(接口用例描述, {0}.format(get_case_name)) allure.attach(接口用例请求参数, {0}.format(get_case_params)) logger.info( 请求接口名%r请求地址%r请求方法%r请求头%r请求Cookies%r %\ (get_name, get_url, get_method, get_headers, get_cookies)) logger.info(请求接口名%r请求接口用例名%r接口用例请求参数%r %\ (get_name, get_case_name, get_case_params)) try: response_data baseRequest.run_main(get_method, get_url, get_case_params, get_headers) except Exception as e: logger.exception(用例请求返回失败{}.format(e)) logger.info(请求接口名%r请求接口用例名%r返回参数%r % (get_name, get_case_name, response_data.json())) return response_data4、Excel数据处理-测试用例测试用例中维护在Excel文件中类中定义如何获取Excel中的相关数据如获取某个单元格的内容获取单元格的行数以及将数据写入Excel中等操作。handle_exceldata.py部分源码class OperationExcel: def __init__(self, file_nameNone, sheet_idNone): if file_name: self.file_name file_name self.sheet_id sheet_id else: self.file_name self.sheet_id 0 self.data self.get_data() # 获取sheets的内容 def get_data(self): data xlrd.open_workbook(self.file_name) tables data.sheets()[self.sheet_id] return tables # 获取单元格的行数 def get_lines(self): tables self.data return tables.nrows # 获取某一个单元格的内容 def get_cell_value(self, row, col): return self.data.cell_value(row, col)5、JSON数据处理-测试用例{ config:{ name:post接口名, url:/langdetect, method:POST, headers:{ Content-Type:application/json }, cookies:{ } }, testcase:[ { name:测试用例1, params:{ query:测试 }, validate:[ { check:status_code, comparator:eq, expect:200 } ] }, { name:测试用例2, params:{ query:python }, validate:[ { check:msg, comparator:eq, expect:success } ] } ] }获取Json文件中里具体字段的值。handle.json.py部分源码class HandleJson: # 读取json文件 def load_json(self, file_name): if file_name None: file_path else: file_path file_name try: with open(file_path, encodingUTF-8) as f: data json.load(f) return data except Exception: print(未找到json文件) return {} # 读取json文件里具体的字段值 def getJson_value(self, key, file_name): if file_name None: return jsonData self.load_json(file_name) if key None: getJsonValue else: getJsonValue jsonData.get(key) return getJsonValue基类封装接口支持Get、Post请求调用requests请求来实现接口的调用与返回。接口参数包括接口地址、接口请求参数、cookie参数、header参数。class BaseRequest: def send_get(self, url, data, headerNone, cookieNone): Requests发送Get请求 :param url请求地址 :param dataGet请求参数 :param cookiecookie参数 :param headerheader参数 response requests.get(urlurl, paramsdata, cookiescookie, headersheader) return response def send_post(self, url, data, headerNone, cookieNone): Requests发送Post请求 :param url请求地址 :param dataPost请求参数 :param dataPost请求参数 :param cookiecookie参数 :param headerheader参数 response requests.post(urlurl, jsondata, cookiescookie, headersheader) return response # 主函数调用 def run_main(self, method, url, data, header, cookieNone): try: result if method.upper() GET: result self.send_get(url, data, header, cookie) elif method.upper() POST: result self.send_post(url, data, header, cookie) return result except Exception as e: logger.exception(请求主函数调用失败{}.format(e))测试用例编写引用Pytest来进行接口的单元测试通过JSON中多个测试用例来做为参数化数据驱动。结合Allure制定相应接口的测试报告。在接口返回断言之前我们先进行该接口的契约测试我们采用的是Pactverity的全量契约校验测试。当契约测试通过时我们再进行返回参数的相关校验测试。test_getRequestJson.py部分源码allure.feature(测试GET请求模块) class TestRequestOne(): allure.title(测试标题) allure.testcase(测试地址https://www.imooc.com) pytest.mark.parametrize(case_data, testCaseData[testcase]) def test_requestOne(self, case_data): try: api_response apiRequest.api_request(baseurl, testCaseData, case_data) api_response_data api_response.json() # pactverity——全量契约校验 config_contract_format Like({ msg: 成功, result: 0, data: EachLike({ word: Like(testng) }) }) mPactVerify PactVerify(config_contract_format) try: mPactVerify.verify(api_response_data) logger.info( verify_result{}verify_info:{}.format(mPactVerify.verify_result, mPactVerify.verify_info)) assert mPactVerify.verify_result True except Exception: err_msg 契约校验错误 logger.exception(测试用例契约校验失败verify_result{}verify_info:{}.format(mPactVerify.verify_result, mPactVerify.verify_info)) try: for case_validate in case_data[validate]: logger.info(断言期望相关参数check{},comparator{},expect{}.format(case_validate[check], case_validate[comparator], case_validate[expect])) comparatorsTest.comparators_Assert(api_response, case_validate[check], case_validate[comparator], case_validate[expect]) logger.info(测试用例断言成功) except Exception as e: logger.exception(测试用例断言失败) except Exception as e: logger.exception(测试用例请求失败原因{}.format(e))主运行运用Pytest和Allure的特性命令行运行测试用例文件夹并生成对应的allure测试报告。if __name__ __main__: pytest.main([-s, -v, test_case/testRequest/, -q, --alluredir, reports])Alluer2 测试报告当我们运行主函数时并生成对应的测试用例报告时我们可以看到在该文件夹中会生成对应的json文件的测试报告。reports是json格式测试报告存放的目录位置allure_reports是html测试报告文件生成的目录位置。allure命令如下。allure generate reports -o allure_result/项目根目录下的allure_reports文件存放的是allure生成的测试报告。可看出文件下有一个HTML文件可通过Python的编辑器Pycharm来打开该HTML文件测试报告或可通过allure命令来打开该HTML。最后作为一位过来人也是希望大家少走一些弯路在这里我给大家分享一些软件测试的学习资料和我花了3个月整理的软件测试自学站这些资料希望能给你前进的路上带来帮助。​视频文档获取方式这份文档和视频资料对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库这个仓库也陪伴我走过了最艰难的路程希望也能帮助到你以上均可以分享点下方小卡片即可自行领取。