免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

接口自动化之HttpRunner初探 |Python 主题月

接口自动化之HttpRunner初探 |Python 主题月 介绍这是一个测试框架, 它具有简单优雅的特性, 同时功能强大, 专门针对 HTTP(S)。它通过 YAML 或者 JSON 格式来定义测试用例, 以此保障对测试用例描述的统一性以及可维护性。在程序执行之际, 会对用户输入的 yml/json 文件予以处理, 并且基于模板生成测试文件。最终借助.main() 的方式去执行生成的用例文件。用户仅需借助json或者yml文件来对用例展开维护工作, 无需去在意程序要怎样处理json或yml文件, 以及怎样生成测试文件那些情况, 能够以简单且快速的方式经由运行用例, 进而获取到详尽的测试报告。主要特征: 在 HAR 的支持之下, 进行记录, 进而生成测试用例。去抓取请求方, 生成的用例文件搞不好还得手动去处理得以使用执行测试文件这一操作 , 存在数百个插件随时能够被使用。凭借所使, 测试报告能够变得极为强大。经由重复运用 , 您就行性能测试, 不需要去做额外的工作。支持CLI命令相关方面的情况 , 进而与CI/CD完善地结合起来用了才行啦。工作流程。要是期望知晓其工作的流程, 最为好的办法便是运用debug模式, 那么在这儿究竟该怎么样去运用debug进而参透其执行的流程呢, 跟随着我来瞧一瞧:调试技巧使用进行调试且环境使用进行管理# -*- coding: utf-8 -*- import re import sys from httprunner.cli import main_hrun_alias if __name__ __main__: sys.argv [/Users/boyizhang/PycharmProjects/apitest/venv/bin/hrun, /Users/boyizhang/PycharmProjects/apitest/hruntests/testcases/testheader.yml] sys.argv[0] re.sub(r(-script\.pyw|\.exe)?$, , sys.argv[0]) sys.exit(main_hrun_alias())工作流调试日志用例管理关键概念总的来讲, 测试用例分层机制的关键所在, 是把接口定义, 与测试步骤, 同测试用例, 以及测试场景进行分离开来, 各自单独去进行描述, 还要单独进行维护, 借此尽可能地去减少自动化测试用例的维护成本。为了能更妥善地针对接口描述予以管理, 采用单独的文件去存储接口描述, 也就是每一个文件都对应着一份接口描述, 这便是所提及的接口定义api, 此为V2.0。向大伙建议选取最新版的, 然而对于那些心存兴致去知晓架构变更情况的同学们而言, 能够持续去阅读V2.0模块的内容。测试用例分层模型V2.0的版本中存在api 的概念。有这样一个情况, 其具备的优点是API管理较为便利, 它存在的缺点是, 当处于某种情境之中, 无论是就单个步骤所构成的简单场景, 亦或者是由多个步骤组合形成的复杂场景来讲, 均是需要对API予以引用的。如此一来, 针对于单个步骤那样的简单场景而言, 它又跟API有着颇为相似的地方, 如此便必定会导致出现重复描述的状况, 并且还极易造成混淆。我们要怎样在testcase里引用api。怎样去引用它。V2.0案例学习能够在其中借助 api 字段去引用 api , 还能够通过字段进行引用。接下来, 依据脚手架迅速创建一个项目, 也就是 --.0这需要保证安装的是.0 以下的版本来予以说明:$ httprunner --startproject hruntest2.0 tree hruntest2.0 Start to create new project: hruntest2.0 CWD: /Users/boyizhang/PycharmProjects/apitest created folder: hruntest2.0 created folder: hruntest2.0/api created folder: hruntest2.0/testcases created folder: hruntest2.0/testsuites created folder: hruntest2.0/reports created file: hruntest2.0/api/demo_api.yml created file: hruntest2.0/testcases/demo_testcase.yml created file: hruntest2.0/testsuites/demo_testsuite.yml created file: hruntest2.0/debugtalk.py created file: hruntest2.0/.env created file: hruntest2.0/.gitignore hruntest2.0 ├── api │ └── demo_api.yml ├── debugtalk.py ├── reports ├── testcases │ └── demo_testcase.yml └── testsuites └── demo_testsuite.yml# api/demo_api.yml name: demo api variables: var1: value1 var2: value2 request: url: /api/path/$var1 method: POST headers: Content-Type: application/json json: key: $var2 validate: - eq: [status_code, 200]config: name: demo testcase variables: device_sn: ABC username: ${ENV(USERNAME)} password: ${ENV(PASSWORD)} base_url: http://127.0.0.1:5000 teststeps: - name: demo step 1 api: path/to/api1.yml variables: user_agent: iOS/10.3 device_sn: $device_sn extract: - token: content.token validate: - eq: [status_code, 200]在当中运用 api 选项去引用 api , 以此来执行/.yml 用例文件。需要注意的是: api 并不在范畴之内, 所以没办法直接去执行 api/下的 yml/json 文件。在当中所传字段的优先级会比 api 下的要高, 这也就意味着, 要是传了某个字段, 那么就会优先去使用所传的那个, 要是没有传, 那么才会再去使用 api 的字段。V3.0在v2.x里, 为了达成简单的目的, API概念被取消了, 这里要重点留意。可以把API界定为是那种仅有一个请求步骤的测试用例。测试用例分层模型那么问题来了我们应该如何在某个的中引用其他呢v3.0案例学习处于测试步骤里, 能够借由字段去引用别的测试用例, 引用的方式是对应测试用例文件的路径, 无论是绝对路径还是相对路径都行。建议采用相对路径, 路径的基准是项目根目录, 也就是.py所在的那个目录路径。**通过 ** .0 快速创建项目。$ tree hruntest3.0 hruntest3.0 ├── debugtalk.py ├── har ├── reports └── testcases ├── demo_testcase_ref.yml └── demo_testcase_request.yml# demo_testcase_request.yml config: name: request methods testcase with functions variables: foo1: config_bar1 foo2: config_bar2 expect_foo1: config_bar1 expect_foo2: config_bar2 base_url: https://postman-echo.com verify: False export: [foo3] teststeps: - name: post form data variables: foo2: bar23 request: method: POST url: /post headers: User-Agent: HttpRunner/${get_httprunner_version()} Content-Type: application/x-www-form-urlencoded data: foo1$foo1foo2$foo2foo3$foo3 validate: - eq: [status_code, 200] - eq: [body.form.foo1, $expect_foo1] - eq: [body.form.foo2, bar23] - eq: [body.form.foo3, bar21]# demo_testcase_ref.yml config: name: request methods testcase: reference testcase variables: foo1: testsuite_config_bar1 expect_foo1: testsuite_config_bar1 expect_foo2: config_bar2 base_url: https://postman-echo.com verify: False teststeps: - name: request with functions variables: foo1: testcase_ref_bar1 expect_foo1: testcase_ref_bar1 testcase: testcases/demo_testcase_request.yml export: - foo3 - name: post form data variables: foo1: bar1 request: method: POST url: /post headers: User-Agent: HttpRunner/${get_httprunner_version()} Content-Type: application/x-www-form-urlencoded data: foo1$foo1foo2$foo3 validate: - eq: [status_code, 200] - eq: [body.form.foo1, bar1] - eq: [body.form.foo2, bar21]采用字段于其中予以引用, 去执行.yml用例文件, 于执行至name with此步骤之际, 会先行执行其引用的: /t.yml。于根目录里, 执行hrun /.yml, 能够见到, 程序亦生成了该case: /t.yml的测试文件:hook机制涉及hook处理背景自动化测试里, 执行用例之前, 得执行某些预处理操作, 等到执行完用例之后, 则要做些清理方面的工作。要是靠手动去进行操控的话, 那就不太适宜了。所以呢就得用到hook此种机制, 在执行用例的前前后后去执行hook函数。使用hook 机制分为两个层级测试步骤层面编写hook函数# ${print_request($request)} 2021-07-18 09:30:46.740 | DEBUG | httprunner.runner:__call_hooks:121 - call hook function: ${print_reqeust($request)} {method: GET, url: /get, params: {foo1: bar11, foo2: bar21, sum_v: 3}, headers: {User-Agent: HttpRunner/3.1.5, HRUN-Request-ID: HRUN-7768261f-0abf-4ce5-abf2-06327de85fd7-846739}, req_json: None, data: None, cookies: {}, timeout: 120, allow_redirects: True, verify: False} # ${print_req($response)} 2021-07-18 09:36:03.019 | DEBUG | httprunner.runner:__call_hooks:121 - call hook function: ${print_req($response)}环境.env涉及env的处理文档# parser.py def get_mapping_function( function_name: Text, functions_mapping: FunctionsMapping ) - Callable: #省略 if function_name in functions_mapping: return functions_mapping[function_name] elif function_name in [environ, ENV]: return utils.get_os_environ #省略 raise exceptions.FunctionNotFound(f{function_name} is not found.) # utils.py def set_os_environ(variables_mapping): set variables mapping to os.environ for variable in variables_mapping: os.environ[variable] variables_mapping[variable] logger.debug(fSet OS environment variable: {variable}) def get_os_environ(variable_name): try: return os.environ[variable_name] except KeyError: raise exceptions.EnvNotFound(variable_name)在加载用例之前, 会先把.env文件里的变化加载到环境当中, 如果用例有含有ENV或者的情况, 那么就通过os.去读取相应的值。参数化实现达成参数化数据驱动机制/post/… , 再次研讨参数化数据驱动机制/post/…。使用需留意的是, 自v2.0起始, 参数化仅支持于其中达成, 不再支持于测试用例文件里开展参数化配置。参数配置概述/底层予以运用, 开展提取以及验证json响应的操作, 进而让提取变得更为简便。其作用在于抓取响应体里的字段, 导出当前此用例抓取的那些字段, 以供引用这个用例的其他用例去使用。测试报告报告总结妥帖加以运用, 能够涵盖百分之八十的场景, 堪称是一值得肯定的工具, 诚然我们除了钻研该如何运用以外, 更应当研习人家的设计理念, 如此往后自身才会拥有机遇打造出更为优良的工具。另外举荐一款Java版本的接口自动化工具供大家予以参照rest-, 与rest-实现途径大致相同, 然而rest-并非借助json/yaml去管理用例, 而是径直撰写测试文件如同产生的py文件那般, 大家能够对照切磋一番。©著作权归作者所有,转载或内容合作请联系作者社区有内容提示, 社区的部分内容, 疑似是借助AI辅助生成的, 在浏览的时候呀, 请结合常识, 并且结合多方信息, 审慎地去进行甄别。tbIMH.ryvju.com2CPKt.ryvju.comdXig7.ryvju.comO8gVL.ryvju.comHzYDu.ryvju.com9V8pN.ryvju.com1h117.ryvju.comP9zK1.ryvju.comZPnpV.ryvju.comJqUnE.ryvju.comA6L2O.ryvju.com1Tsg6.ryvju.comQjz10.ryvju.com09PNU.ryvju.comMply4.ryvju.comw7nyN.ryvju.com2GOmT.ryvju.comc0SrS.ryvju.comLbNa3.ryvju.com415YE.ryvju.com69O0n.ryvju.comDKCLH.ryvju.comkJOB6.ryvju.com4390x.ryvju.comwOcU0.ryvju.com0rdXo.ryvju.comxwQUg.ryvju.com6cwIx.ryvju.comMUgVT.ryvju.comRp58O.ryvju.com7Ba28.ryvju.comiwTeT.ryvju.comTovRN.ryvju.comhF2Li.ryvju.com20E0z.ryvju.comBVNFb.ryvju.comN5094.ryvju.com5gQ55.ryvju.combPuYf.ryvju.coml7pv5.ryvju.comBgqh7.ryvju.comJayo1.ryvju.comPE9og.ryvju.com25oVv.ryvju.comDaeOU.ryvju.comFTS7j.ryvju.comHTZu9.ryvju.comju77G.ryvju.coms6f4S.ryvju.com3bfA0.ryvju.comuaUQO.ryvju.comXKYjK.ryvju.comwp8G9.ryvju.com6UeIT.ryvju.com3074K.ryvju.comMu8k9.ryvju.comlNw8V.ryvju.comDeTHY.ryvju.com24OSu.ryvju.comRxuNo.ryvju.comis5NY.ryvju.com85w7g.ryvju.com3gDIx.ryvju.comXhBwo.ryvju.com66dgG.ryvju.comhb0H6.ryvju.comXJKmv.ryvju.com8XD6c.ryvju.comSgYaF.ryvju.comu1uNR.ryvju.compmXmn.ryvju.comNu7LB.ryvju.comsxNFU.ryvju.comU9S14.ryvju.comU2Y93.ryvju.comP0JNh.ryvju.com8A4E8.ryvju.comq16hD.ryvju.comQaZte.ryvju.comFVL49.ryvju.comdfp1E.ryvju.compIrk4.ryvju.com724wz.ryvju.com5Ox4c.ryvju.comRtZdp.ryvju.comZfme9.ryvju.comCL51U.ryvju.comZc0rJ.ryvju.comWiMha.ryvju.comLaNqL.ryvju.comJDLGd.ryvju.com9c2ND.ryvju.comDEgq4.ryvju.com8y89Q.ryvju.comOPgdk.ryvju.com3L4dI.ryvju.com8R994.ryvju.comLI86G.ryvju.comrGhO8.ryvju.comybrbe.ryvju.comaUWF7.ryvju.comTZHBg.ryvju.comfkiR2.ryvju.comcBPiK.ryvju.comWTriv.ryvju.comvEvuL.ryvju.com91RKZ.ryvju.comi14pc.ryvju.com37f0L.ryvju.comwiRyy.ryvju.comw63AP.ryvju.com8YnvD.ryvju.comwLA3o.ryvju.com75dzK.ryvju.com6ovg1.ryvju.com1U7z8.ryvju.comAbU5p.ryvju.com5Dg8S.ryvju.com9241D.ryvju.com4Arow.ryvju.comnE2X9.ryvju.comGseSm.ryvju.com716cG.ryvju.comSFgPA.ryvju.comO9R82.ryvju.comD9NtN.ryvju.comszp66.ryvju.comA2oGA.ryvju.comhdtHe.ryvju.comXwa6v.ryvju.comLc5fJ.ryvju.comw0KAX.ryvju.comTcq9n.ryvju.comkODxg.ryvju.com7hnKv.ryvju.comK397K.ryvju.comOdRE5.ryvju.comTUIkM.ryvju.combN36A.ryvju.comBYZwJ.ryvju.com3Am51.ryvju.come263z.ryvju.com4RFqC.ryvju.comp4b5e.ryvju.com5604J.ryvju.comZl7f7.ryvju.comSME6A.ryvju.comZkOO4.ryvju.compFbiE.ryvju.comkM5Qn.ryvju.com6uk4V.ryvju.comJpPN9.ryvju.com9YOBR.ryvju.com1uxPS.ryvju.comZF9QW.ryvju.com7QDPJ.ryvju.com0z06I.ryvju.comjT9F4.ryvju.comgrAq2.ryvju.comsRINB.ryvju.coms2109.ryvju.commlE0Q.ryvju.comzI6qf.ryvju.com2zRrE.ryvju.comVW931.ryvju.comMTJto.ryvju.com3tb97.ryvju.com0k1PN.ryvju.comHrV6z.ryvju.comU230Q.ryvju.comSEtTy.ryvju.coms65It.ryvju.comUj2P8.ryvju.comNnc1c.ryvju.comM1Ju2.ryvju.com75Rb5.ryvju.comC3h06.ryvju.comjiu2Y.ryvju.com8MPKx.ryvju.comCPec4.ryvju.comQkUCO.ryvju.como8os1.ryvju.com9w85O.ryvju.comtsGxT.ryvju.comEOp0P.ryvju.com7CxPw.ryvju.comS9gw2.ryvju.compIVsy.ryvju.comZeGwr.ryvju.comcv5Q0.ryvju.com4a9om.ryvju.comaA7LL.ryvju.com9Xrub.ryvju.combrVjO.ryvju.comynuHY.ryvju.comrl4lI.ryvju.comeRXy7.ryvju.comTK9uN.ryvju.com9lzHD.ryvju.com59SRM.ryvju.comL340T.ryvju.comlAzTc.ryvju.com4kuRc.ryvju.comz5A6T.ryvju.com98xAM.ryvju.comsv83D.ryvju.comk63V1.ryvju.comVXDmb.ryvju.comXj6uV.ryvju.com7G3uy.ryvju.comDKZfn.ryvju.comoD633.ryvju.comT0Qkw.ryvju.comDdRTP.ryvju.comM8sj6.ryvju.comvNX2k.ryvju.com7PdnJ.ryvju.comfDhcx.ryvju.com2Or7K.ryvju.com482Th.ryvju.comGLQmG.ryvju.comCTJ9m.ryvju.comqzcce.ryvju.comz6156.ryvju.comUar1B.ryvju.com1NE7B.ryvju.comV4Gz0.ryvju.com1Rd2i.ryvju.com3PCHN.ryvju.com19hPf.ryvju.com0a3j4.ryvju.com8Hd8X.ryvju.comMFPoy.ryvju.comCG4m3.ryvju.com6EW9p.ryvju.comeBUHu.ryvju.comfT3Uh.ryvju.comJbtdV.ryvju.comXQHoI.ryvju.com5vVIW.ryvju.comHyfQY.ryvju.comQhbwm.ryvju.comdmORm.ryvju.com9EWaU.ryvju.comsmx6E.ryvju.como6wGV.ryvju.combp49u.ryvju.comGmW4C.ryvju.com0lG87.ryvju.comCb9o8.ryvju.comTe1Z5.ryvju.comkK3pE.ryvju.comvf7HZ.ryvju.comC5DCw.ryvju.comoV2Yx.ryvju.comK0fOG.ryvju.comEa432.ryvju.comS7PcA.ryvju.comTp0UU.ryvju.comaXPzj.ryvju.comKkSEv.ryvju.com1acxQ.ryvju.com8zeqO.ryvju.com4S7eD.ryvju.comBw77z.ryvju.combqmyb.ryvju.comAEZts.ryvju.com7Lk3a.ryvju.comU7DL6.ryvju.comXy5KI.ryvju.com298VV.ryvju.comS74jS.ryvju.comZavBG.ryvju.combFBrE.ryvju.comu87V4.ryvju.comU4sRD.ryvju.comlkavO.ryvju.comxPdC4.ryvju.comza2rG.ryvju.com0dU50.ryvju.comRvfZw.ryvju.comdXGOb.ryvju.comp08H8.ryvju.com8e78i.ryvju.com1HoBb.ryvju.com5JRpC.ryvju.comyeCxo.ryvju.comHtzKE.ryvju.comy5egL.ryvju.comJ709Y.ryvju.comt28O4.ryvju.comtwrE7.ryvju.comib9YN.ryvju.comvdvu7.ryvju.comhn5t8.ryvju.coma77Jb.ryvju.comlHTK0.ryvju.comXmf0a.ryvju.comI81in.ryvju.coma8S07.ryvju.comH4NV1.ryvju.com1xAEo.ryvju.com5d7SE.ryvju.com4ks3M.ryvju.comcb5k9.ryvju.comEJM0l.ryvju.comknG52.ryvju.comoO93K.ryvju.comEzA7t.ryvju.comZXeo4.ryvju.com1O9aF.ryvju.comHPeUh.ryvju.comW8g1d.ryvju.comh4VIh.ryvju.comTY6t3.ryvju.com9HT0d.ryvju.comBAdOk.ryvju.comDQBaj.ryvju.comr09Yx.ryvju.comlA2pB.ryvju.comT39TD.ryvju.comr0Yt1.ryvju.coms8ZrU.ryvju.comvb5x1.ryvju.com6XyZ7.ryvju.comPP8F8.ryvju.coml84W1.ryvju.comiC90u.ryvju.com1DWAs.ryvju.comfKeXV.ryvju.comzN0yV.ryvju.com95g0y.ryvju.com8LElw.ryvju.com5pNyg.ryvju.com7jsTK.ryvju.com445el.ryvju.com3aGSa.ryvju.com2wheT.ryvju.comWspyU.ryvju.com8uu34.ryvju.com9CaqN.ryvju.comfV59W.ryvju.com2yui4.ryvju.como9BEV.ryvju.comSC0Ot.ryvju.comTe2Q0.ryvju.com8scss.ryvju.comLQ5lG.ryvju.comBt04c.ryvju.com5Blfe.ryvju.com
返回列表