From 357e31fa42e5b16e8cf0d4d15891318ca5502f96 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Mon, 15 Jun 2020 16:02:49 +0800 Subject: [PATCH] Deployed 1847532 with MkDocs version: 1.1.2 --- search/search_index.json | 2 +- sitemap.xml.gz | Bin 198 -> 198 bytes sponsors/index.html | 6 +++--- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/search/search_index.json b/search/search_index.json index ccd15c82..ef06f4fa 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"HttpRunner \u00b6 HttpRunner is a simple & elegant, yet powerful HTTP(S) testing framework. Enjoy! \u2728 \ud83d\ude80 \u2728 This docs site is corresponding to the latest version 3.x , for 2.x you can reference archive link . Design Philosophy \u00b6 Convention over configuration ROI matters Embrace open source, leverage requests , pytest , pydantic , allure and locust . Key Features \u00b6 Inherit all powerful features of requests , just have fun to handle HTTP(S) in human way. Define testcase in YAML or JSON format, run with pytest in concise and elegant manner. Record and generate testcases with HAR support. Supports variables / extract / validate / hooks mechanisms to create extremely complex test scenarios. With debugtalk.py plugin, any function can be used in any part of your testcase. With jmespath , extract and validate json response has never been easier. With pytest , hundreds of plugins are readily available. With allure , test report can be pretty nice and powerful. With reuse of locust , you can run performance test without extra work. CLI command supported, perfect combination with CI/CD . Subscribe \u00b6 \u5173\u6ce8 HttpRunner \u7684\u5fae\u4fe1\u516c\u4f17\u53f7\uff0c\u7b2c\u4e00\u65f6\u95f4\u83b7\u5f97\u6700\u65b0\u8d44\u8baf\u3002","title":"Introduction"},{"location":"#httprunner","text":"HttpRunner is a simple & elegant, yet powerful HTTP(S) testing framework. Enjoy! \u2728 \ud83d\ude80 \u2728 This docs site is corresponding to the latest version 3.x , for 2.x you can reference archive link .","title":"HttpRunner"},{"location":"#design-philosophy","text":"Convention over configuration ROI matters Embrace open source, leverage requests , pytest , pydantic , allure and locust .","title":"Design Philosophy"},{"location":"#key-features","text":"Inherit all powerful features of requests , just have fun to handle HTTP(S) in human way. Define testcase in YAML or JSON format, run with pytest in concise and elegant manner. Record and generate testcases with HAR support. Supports variables / extract / validate / hooks mechanisms to create extremely complex test scenarios. With debugtalk.py plugin, any function can be used in any part of your testcase. With jmespath , extract and validate json response has never been easier. With pytest , hundreds of plugins are readily available. With allure , test report can be pretty nice and powerful. With reuse of locust , you can run performance test without extra work. CLI command supported, perfect combination with CI/CD .","title":"Key Features"},{"location":"#subscribe","text":"\u5173\u6ce8 HttpRunner \u7684\u5fae\u4fe1\u516c\u4f17\u53f7\uff0c\u7b2c\u4e00\u65f6\u95f4\u83b7\u5f97\u6700\u65b0\u8d44\u8baf\u3002","title":"Subscribe"},{"location":"CHANGELOG/","text":"Release History \u00b6 3.0.13 (2020-06-15) \u00b6 Fixed fix: avoid '.csv' been converted to '_csv' fix: convert har to JSON format testcase fix: missing ${var} handling in overriding config variables 3.0.12 (2020-06-14) \u00b6 Fixed fix: compatibility with different path separators of Linux and Windows fix: IndexError in ensure_file_path_valid when file_path=os.getcwd() fix: ensure step referenced api, convert to v3 testcase fix: several other compatibility issues Changed change: skip reporting sentry for errors occurred in debugtalk.py 3.0.11 (2020-06-08) \u00b6 Changed change: override variables (1) testcase: session variables > step variables > config variables (2) testsuite: testcase variables > config variables (3) testsuite testcase variables > testcase config variables Fixed fix: incorrect summary success when testcase failed fix: reload to refresh previously loaded debugtalk module fix: escape $$ in variable value 3.0.10 (2020-06-07) \u00b6 Added feat: implement step setup/teardown hooks feat: support alter response in teardown hooks Fixed fix: ensure upload ready fix: add ExtendJSONEncoder to safely dump json data with python object, such as MultipartEncoder 3.0.9 (2020-06-07) \u00b6 Fixed fix: miss formatting referenced testcase fix: handle cases when parent directory name includes dot/hyphen/space Changed change: add export keyword in TStep to export session variables from referenced testcase change: rename TestCaseInOut field, config_vars and export_vars change: rename StepData field, export_vars change: add --tb=short for hrun command to use shorter traceback format by default change: search debugtalk.py upward recursively until system root dir 3.0.8 (2020-06-04) \u00b6 Added feat: add sentry sdk feat: extract session variable from referenced testcase step Fixed fix: missing request json fix: override testsuite/testcase config verify fix: only strip whitespaces and tabs, \\n\\r are left because they maybe used in changeset fix: log testcase duration before raise ValidationFailure Changed change: add httprunner version in generated pytest file 3.0.7 (2020-06-03) \u00b6 Added feat: make pytest files in chain style feat: hrun supports run pytest files feat: get raw testcase model from pytest file Fixed fix: convert jmespath.search result to int/float unintentionally fix: referenced testcase should not be run duplicately fix: requests.cookies.CookieConflictError, multiple cookies with name fix: missing exit code from pytest fix: skip invalid testcase/testsuite yaml/json file Changed change: har2case generate pytest file by default docs: update sponsor info 3.0.6 (2020-05-29) \u00b6 Added feat: make referenced testcase as pytest class Fixed fix: ensure converted python file in utf-8 encoding fix: duplicate running referenced testcase fix: ensure compatibility issues between testcase format v2 and v3 fix: ensure compatibility with deprecated cli args in v2, include --failfast/--report-file/--save-tests fix: UnicodeDecodeError when request body in protobuf Changed change: make allure-pytest , requests-toolbelt , filetype as optional dependencies change: move all unittests to tests folder change: save testcase log in PWD/logs/ directory 3.0.5 (2020-05-22) \u00b6 Added feat: each testcase has an unique id in uuid4 format feat: add default header HRUN-Request-ID for each testcase #721 feat: builtin allure report feat: dump log for each testcase Fixed fix: ensure referenced testcase share the same session Changed change: remove default added -s option for hrun 3.0.4 (2020-05-19) \u00b6 Added feat: make testsuite and run testsuite feat: testcase/testsuite config support getting variables by function feat: har2case with request cookies feat: log request/response headers and body with indent Fixed fix: extract response cookies fix: handle errors when no valid testcases generated Changed change: har2case do not ignore request headers, except for header startswith : 3.0.3 (2020-05-17) \u00b6 Fixed fix: compatibility with testcase file path includes dots, space and minus sign fix: testcase generator, validate content.xxx => body.xxx fix: scaffold for v3 3.0.2 (2020-05-16) \u00b6 Added feat: add make sub-command to generate python testcases from YAML/JSON feat: format generated python testcases with black test: add postman echo & httpbin as testcase examples Changed refactor all replace jsonschema validation with pydantic remove compatibility with testcase/testsuite format v1 replace unittest with pytest remove builtin html report, allure will be used with pytest later remove locust support temporarily update command line interface 3.0.1 (2020-03-24) \u00b6 Changed remove sentry sdk 3.0.0 (2020-03-10) \u00b6 Added feat: dump log for each testcase feat: add default header HRUN-Request-ID for each testcase #721 Changed remove support for Python 2.7 replace logging with loguru replace string format with f-string remove dependency colorama and colorlog generate reports/logs folder in current working directory remove cli --validate remove cli --pretty","title":"CHANGELOG"},{"location":"CHANGELOG/#release-history","text":"","title":"Release History"},{"location":"CHANGELOG/#3013-2020-06-15","text":"Fixed fix: avoid '.csv' been converted to '_csv' fix: convert har to JSON format testcase fix: missing ${var} handling in overriding config variables","title":"3.0.13 (2020-06-15)"},{"location":"CHANGELOG/#3012-2020-06-14","text":"Fixed fix: compatibility with different path separators of Linux and Windows fix: IndexError in ensure_file_path_valid when file_path=os.getcwd() fix: ensure step referenced api, convert to v3 testcase fix: several other compatibility issues Changed change: skip reporting sentry for errors occurred in debugtalk.py","title":"3.0.12 (2020-06-14)"},{"location":"CHANGELOG/#3011-2020-06-08","text":"Changed change: override variables (1) testcase: session variables > step variables > config variables (2) testsuite: testcase variables > config variables (3) testsuite testcase variables > testcase config variables Fixed fix: incorrect summary success when testcase failed fix: reload to refresh previously loaded debugtalk module fix: escape $$ in variable value","title":"3.0.11 (2020-06-08)"},{"location":"CHANGELOG/#3010-2020-06-07","text":"Added feat: implement step setup/teardown hooks feat: support alter response in teardown hooks Fixed fix: ensure upload ready fix: add ExtendJSONEncoder to safely dump json data with python object, such as MultipartEncoder","title":"3.0.10 (2020-06-07)"},{"location":"CHANGELOG/#309-2020-06-07","text":"Fixed fix: miss formatting referenced testcase fix: handle cases when parent directory name includes dot/hyphen/space Changed change: add export keyword in TStep to export session variables from referenced testcase change: rename TestCaseInOut field, config_vars and export_vars change: rename StepData field, export_vars change: add --tb=short for hrun command to use shorter traceback format by default change: search debugtalk.py upward recursively until system root dir","title":"3.0.9 (2020-06-07)"},{"location":"CHANGELOG/#308-2020-06-04","text":"Added feat: add sentry sdk feat: extract session variable from referenced testcase step Fixed fix: missing request json fix: override testsuite/testcase config verify fix: only strip whitespaces and tabs, \\n\\r are left because they maybe used in changeset fix: log testcase duration before raise ValidationFailure Changed change: add httprunner version in generated pytest file","title":"3.0.8 (2020-06-04)"},{"location":"CHANGELOG/#307-2020-06-03","text":"Added feat: make pytest files in chain style feat: hrun supports run pytest files feat: get raw testcase model from pytest file Fixed fix: convert jmespath.search result to int/float unintentionally fix: referenced testcase should not be run duplicately fix: requests.cookies.CookieConflictError, multiple cookies with name fix: missing exit code from pytest fix: skip invalid testcase/testsuite yaml/json file Changed change: har2case generate pytest file by default docs: update sponsor info","title":"3.0.7 (2020-06-03)"},{"location":"CHANGELOG/#306-2020-05-29","text":"Added feat: make referenced testcase as pytest class Fixed fix: ensure converted python file in utf-8 encoding fix: duplicate running referenced testcase fix: ensure compatibility issues between testcase format v2 and v3 fix: ensure compatibility with deprecated cli args in v2, include --failfast/--report-file/--save-tests fix: UnicodeDecodeError when request body in protobuf Changed change: make allure-pytest , requests-toolbelt , filetype as optional dependencies change: move all unittests to tests folder change: save testcase log in PWD/logs/ directory","title":"3.0.6 (2020-05-29)"},{"location":"CHANGELOG/#305-2020-05-22","text":"Added feat: each testcase has an unique id in uuid4 format feat: add default header HRUN-Request-ID for each testcase #721 feat: builtin allure report feat: dump log for each testcase Fixed fix: ensure referenced testcase share the same session Changed change: remove default added -s option for hrun","title":"3.0.5 (2020-05-22)"},{"location":"CHANGELOG/#304-2020-05-19","text":"Added feat: make testsuite and run testsuite feat: testcase/testsuite config support getting variables by function feat: har2case with request cookies feat: log request/response headers and body with indent Fixed fix: extract response cookies fix: handle errors when no valid testcases generated Changed change: har2case do not ignore request headers, except for header startswith :","title":"3.0.4 (2020-05-19)"},{"location":"CHANGELOG/#303-2020-05-17","text":"Fixed fix: compatibility with testcase file path includes dots, space and minus sign fix: testcase generator, validate content.xxx => body.xxx fix: scaffold for v3","title":"3.0.3 (2020-05-17)"},{"location":"CHANGELOG/#302-2020-05-16","text":"Added feat: add make sub-command to generate python testcases from YAML/JSON feat: format generated python testcases with black test: add postman echo & httpbin as testcase examples Changed refactor all replace jsonschema validation with pydantic remove compatibility with testcase/testsuite format v1 replace unittest with pytest remove builtin html report, allure will be used with pytest later remove locust support temporarily update command line interface","title":"3.0.2 (2020-05-16)"},{"location":"CHANGELOG/#301-2020-03-24","text":"Changed remove sentry sdk","title":"3.0.1 (2020-03-24)"},{"location":"CHANGELOG/#300-2020-03-10","text":"Added feat: dump log for each testcase feat: add default header HRUN-Request-ID for each testcase #721 Changed remove support for Python 2.7 replace logging with loguru replace string format with f-string remove dependency colorama and colorlog generate reports/logs folder in current working directory remove cli --validate remove cli --pretty","title":"3.0.0 (2020-03-10)"},{"location":"installation/","text":"HttpRunner is developed with Python, it supports Python 3.6+ and most operating systems. Combination of Python 3.6/3.7/3.8 and macOS/Linux/Windows are tested continuously on GitHub-Actions . Installation \u00b6 HttpRunner is available on PyPI and can be installed through pip . $ pip3 install httprunner If you want to keep up with the latest version, you can install with github repository url. $ pip3 install git+https://github.com/httprunner/httprunner.git@master If\b you have installed HttpRunner before and want to upgrade to the latest version, you can use the -U option. $ pip3 install -U httprunner $ pip3 install -U git+https://github.com/httprunner/httprunner.git@master Check Installation \u00b6 When HttpRunner is installed, 4 commands will be added in your system. httprunner : main command, used for all functions hrun : alias for httprunner run , used to run YAML/JSON/pytest testcases hmake : alias for httprunner make , used to convert YAML/JSON testcases to pytest files har2case : alias for httprunner har2case , used to convert HAR to YAML/JSON testcases To see HttpRunner version: $ httprunner -V # hrun -V 3.0.10 To see available options, run: $ httprunner -h usage: httprunner [-h] [-V] {run,startproject,har2case,make} ... One-stop solution for HTTP(S) testing. positional arguments: {run,startproject,har2case,make} sub-command help run Make HttpRunner testcases and run with pytest. startproject Create a new project with template structure. har2case Convert HAR(HTTP Archive) to YAML/JSON testcases for HttpRunner. make Convert YAML/JSON testcases to pytest cases. optional arguments: -h, --help show this help message and exit -V, --version show version","title":"Installation"},{"location":"installation/#installation","text":"HttpRunner is available on PyPI and can be installed through pip . $ pip3 install httprunner If you want to keep up with the latest version, you can install with github repository url. $ pip3 install git+https://github.com/httprunner/httprunner.git@master If\b you have installed HttpRunner before and want to upgrade to the latest version, you can use the -U option. $ pip3 install -U httprunner $ pip3 install -U git+https://github.com/httprunner/httprunner.git@master","title":"Installation"},{"location":"installation/#check-installation","text":"When HttpRunner is installed, 4 commands will be added in your system. httprunner : main command, used for all functions hrun : alias for httprunner run , used to run YAML/JSON/pytest testcases hmake : alias for httprunner make , used to convert YAML/JSON testcases to pytest files har2case : alias for httprunner har2case , used to convert HAR to YAML/JSON testcases To see HttpRunner version: $ httprunner -V # hrun -V 3.0.10 To see available options, run: $ httprunner -h usage: httprunner [-h] [-V] {run,startproject,har2case,make} ... One-stop solution for HTTP(S) testing. positional arguments: {run,startproject,har2case,make} sub-command help run Make HttpRunner testcases and run with pytest. startproject Create a new project with template structure. har2case Convert HAR(HTTP Archive) to YAML/JSON testcases for HttpRunner. make Convert YAML/JSON testcases to pytest cases. optional arguments: -h, --help show this help message and exit -V, --version show version","title":"Check Installation"},{"location":"quickstart/","text":"Quick Start \u00b6 First of all, remember HttpRunner is a simple yet powerful HTTP(S) testing framework. This document will help you to learn HttpRunner in 10 minutes. Write the first test case \u00b6 Open your favorite text editor and you can write test cases like this. - test : name : get token request : url : http://127.0.0.1:5000/api/get-token method : POST headers : user_agent : iOS/10.3 device_sn : 9TN6O2Bn1vzfybF os_platform : ios app_version : 2.8.6 json : sign : 19067cf712265eb5426db8d3664026c1ccea02b9 - test : name : create user which does not exist request : url : http://127.0.0.1:5000/api/users/1000 method : POST headers : device_sn : 9TN6O2Bn1vzfybF token : F8prvGryC5beBr4g json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } As you see, each API request is described in a test block. And in the request field, it describes the detail of HTTP request, includes url, method, headers and data, which are in line with the captured traffic. You may wonder why we use the json field other than data . That's because the post data is in JSON format, when we use json to indicate the post data, we do not have to specify Content-Type to be application/json in request headers or dump data before request. Have you recalled some familiar scenes? Yes! That's what we did in requests.request ! Since HttpRunner takes full reuse of Requests , it inherits all powerful features of Requests , and we can handle HTTP request as the way we do before. Run test cases \u00b6 Suppose the test case file is named as quickstart-demo-rev-0.yml and is located in examples folder, then we can run it in this way. ate examples/demo-rev-0.yml Running tests... ---------------------------------------------------------------------- get token ... INFO:root: Start to POST http://127.0.0.1:5000/api/get-token INFO:root: status_code: 200, response_time: 48 ms, response_length: 46 bytes OK (0.049669)s create user which does not exist ... INFO:root: Start to POST http://127.0.0.1:5000/api/users/1000 ERROR:root: Failed to POST http://127.0.0.1:5000/api/users/1000! exception msg: 403 Client Error: FORBIDDEN for url: http://127.0.0.1:5000/api/users/1000 ERROR (0.006471)s ---------------------------------------------------------------------- Ran 2 tests in 0.056s FAILED (Errors=1) Oops! The second test case failed with 403 status code. That is because we request with the same data as we captured in Charles Proxy , while the token is generated dynamically, thus the recorded data can not be be used twice directly. Optimize test case: correlation \u00b6 To fix this problem, we should correlate token field in the second API test case, which is also called correlation . - test : name : get token request : url : http://127.0.0.1:5000/api/get-token method : POST headers : user_agent : iOS/10.3 device_sn : 9TN6O2Bn1vzfybF os_platform : ios app_version : 2.8.6 json : sign : 19067cf712265eb5426db8d3664026c1ccea02b9 extract : - token : content.token validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 200 } - { \"check\" : \"content.token\" , \"comparator\" : \"len_eq\" , \"expect\" : 16 } - test : name : create user which does not exist request : url : http://127.0.0.1:5000/api/users/1000 method : POST headers : device_sn : 9TN6O2Bn1vzfybF token : $token json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } As you see, the token field is no longer hardcoded, instead it is extracted from the first API request with extract mechanism. In the meanwhile, it is assigned to token variable, which can be referenced by the subsequent API requests. Now we save the test cases to quickstart-demo-rev-1.yml and rerun it, and we will find that both API requests to be successful. Optimize test case: parameterization \u00b6 Let's look back to our test set quickstart-demo-rev-1.yml , and we can see the device_sn field is still hardcoded. This may be quite different from the actual scenarios. In actual scenarios, each user's device_sn is different, so we should parameterize the request parameters, which is also called parameterization . In the meanwhile, the sign field is calculated with other header fields, thus it may change significantly if any header field changes slightly. However, the test cases are only YAML documents, it is impossible to generate parameters dynamically in such text. Fortunately, we can combine Python scripts with YAML/JSON test cases in HttpRunner . To achieve this goal, we can utilize debugtalk.py plugin and variables mechanisms. To be specific, we can create a Python file ( examples/debugtalk.py ) and implement the related algorithm in it. The debugtalk.py file can not only be located beside YAML/JSON testcase file, but also can be in any upward recursive folder. Since we want debugtalk.py to be importable, we should put a __init__.py in its folder to make it as a Python module. import hashlib import hmac import random import string SECRET_KEY = \"DebugTalk\" def get_sign ( * args ): content = '' . join ( args ) . encode ( 'ascii' ) sign_key = SECRET_KEY . encode ( 'ascii' ) sign = hmac . new ( sign_key , content , hashlib . sha1 ) . hexdigest () return sign def gen_random_string ( str_len ): random_char_list = [] for _ in range ( str_len ): random_char = random . choice ( string . ascii_letters + string . digits ) random_char_list . append ( random_char ) random_string = '' . join ( random_char_list ) return random_string And then, we can revise our demo test case and reference the functions. Suppose the revised file named quickstart-demo-rev-2.yml . - test : name : get token variables : - user_agent : 'iOS/10.3' - device_sn : ${gen_random_string(15)} - os_platform : 'ios' - app_version : '2.8.6' request : url : http://127.0.0.1:5000/api/get-token method : POST headers : user_agent : $user_agent device_sn : $device_sn os_platform : $os_platform app_version : $app_version json : sign : ${get_sign($user_agent, $device_sn, $os_platform, $app_version)} extract : - token : content.token validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 200 } - { \"check\" : \"content.token\" , \"comparator\" : \"len_eq\" , \"expect\" : 16 } - test : name : create user which does not exist request : url : http://127.0.0.1:5000/api/users/1000 method : POST headers : device_sn : $device_sn token : $token json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } In this revised test case, variable reference and function invoke mechanisms are both used. To make fields like device_sn can be used more than once, we bind values to variables in variables block. When we bind variables, we can not only bind exact value to a variable name, but also can call a function and bind the evaluated value to it. When we want to reference a variable in the test case, we can do this with a escape character $ . For example, $user_agent will not be taken as a normal string, and HttpRunner will consider it as a variable named user_agent , search and return its binding value. When we want to reference a function, we shall use another escape character ${} . Any content in ${} will be considered as function calling, so we should guarantee that we call functions in the right way. At the same time, variables can also be referenced as parameters of function. Optimize test case: overall config block \u00b6 There is still one issue unsolved. The device_sn field is defined in the first API test case, thus it may be impossible to reference it in other test cases. Context separation is a well-designed mechanism, and we should obey this good practice. To handle this case, overall config block is supported in HttpRunner . If we define variables or import functions in config block, these variables and functions will become global and can be referenced in the whole test set. # examples/quickstart-demo-rev-3.yml - config : name : \"smoketest for CRUD users.\" variables : - device_sn : ${gen_random_string(15)} request : base_url : http://127.0.0.1:5000 headers : device_sn : $device_sn - test : name : get token variables : - user_agent : 'iOS/10.3' - os_platform : 'ios' - app_version : '2.8.6' request : url : /api/get-token method : POST headers : user_agent : $user_agent os_platform : $os_platform app_version : $app_version json : sign : ${get_sign($user_agent, $device_sn, $os_platform, $app_version)} extract : - token : content.token validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 200 } - { \"check\" : \"content.token\" , \"comparator\" : \"len_eq\" , \"expect\" : 16 } - test : name : create user which does not exist request : url : /api/users/1000 method : POST headers : token : $token json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } As you see, we define variables in config block. Also, we can set base_url in config block, thereby we can specify relative path in each API request url. Besides, we can also set common fields in config request , such as device_sn in headers. Until now, the test cases are finished and each detail is handled properly. Run test cases and generate report \u00b6 Finally, let's run test set quickstart-demo-rev-3.yml once more. $ ate examples/quickstart-demo-rev-4.yml Running tests... ---------------------------------------------------------------------- get token ... INFO:root: Start to POST http://127.0.0.1:5000/api/get-token INFO:root: status_code: 200, response_time: 33 ms, response_length: 46 bytes OK (0.037027)s create user which does not exist ... INFO:root: Start to POST http://127.0.0.1:5000/api/users/1000 INFO:root: status_code: 201, response_time: 15 ms, response_length: 54 bytes OK (0.016414)s ---------------------------------------------------------------------- Ran 2 tests in 0.054s OK Generating HTML reports... Template is not specified, load default template instead. Reports generated: /Users/Leo/MyProjects/HttpRunner/reports/quickstart-demo-rev-0/2017-08-01-16-51-51.html Great! The test case runs successfully and generates a HTML test report. Further more \u00b6 This is just a starting point, see the advanced guide for the advanced features. templating data extraction and validation comparator","title":"Quick Start"},{"location":"quickstart/#quick-start","text":"First of all, remember HttpRunner is a simple yet powerful HTTP(S) testing framework. This document will help you to learn HttpRunner in 10 minutes.","title":"Quick Start"},{"location":"quickstart/#write-the-first-test-case","text":"Open your favorite text editor and you can write test cases like this. - test : name : get token request : url : http://127.0.0.1:5000/api/get-token method : POST headers : user_agent : iOS/10.3 device_sn : 9TN6O2Bn1vzfybF os_platform : ios app_version : 2.8.6 json : sign : 19067cf712265eb5426db8d3664026c1ccea02b9 - test : name : create user which does not exist request : url : http://127.0.0.1:5000/api/users/1000 method : POST headers : device_sn : 9TN6O2Bn1vzfybF token : F8prvGryC5beBr4g json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } As you see, each API request is described in a test block. And in the request field, it describes the detail of HTTP request, includes url, method, headers and data, which are in line with the captured traffic. You may wonder why we use the json field other than data . That's because the post data is in JSON format, when we use json to indicate the post data, we do not have to specify Content-Type to be application/json in request headers or dump data before request. Have you recalled some familiar scenes? Yes! That's what we did in requests.request ! Since HttpRunner takes full reuse of Requests , it inherits all powerful features of Requests , and we can handle HTTP request as the way we do before.","title":"Write the first test case"},{"location":"quickstart/#run-test-cases","text":"Suppose the test case file is named as quickstart-demo-rev-0.yml and is located in examples folder, then we can run it in this way. ate examples/demo-rev-0.yml Running tests... ---------------------------------------------------------------------- get token ... INFO:root: Start to POST http://127.0.0.1:5000/api/get-token INFO:root: status_code: 200, response_time: 48 ms, response_length: 46 bytes OK (0.049669)s create user which does not exist ... INFO:root: Start to POST http://127.0.0.1:5000/api/users/1000 ERROR:root: Failed to POST http://127.0.0.1:5000/api/users/1000! exception msg: 403 Client Error: FORBIDDEN for url: http://127.0.0.1:5000/api/users/1000 ERROR (0.006471)s ---------------------------------------------------------------------- Ran 2 tests in 0.056s FAILED (Errors=1) Oops! The second test case failed with 403 status code. That is because we request with the same data as we captured in Charles Proxy , while the token is generated dynamically, thus the recorded data can not be be used twice directly.","title":"Run test cases"},{"location":"quickstart/#optimize-test-case-correlation","text":"To fix this problem, we should correlate token field in the second API test case, which is also called correlation . - test : name : get token request : url : http://127.0.0.1:5000/api/get-token method : POST headers : user_agent : iOS/10.3 device_sn : 9TN6O2Bn1vzfybF os_platform : ios app_version : 2.8.6 json : sign : 19067cf712265eb5426db8d3664026c1ccea02b9 extract : - token : content.token validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 200 } - { \"check\" : \"content.token\" , \"comparator\" : \"len_eq\" , \"expect\" : 16 } - test : name : create user which does not exist request : url : http://127.0.0.1:5000/api/users/1000 method : POST headers : device_sn : 9TN6O2Bn1vzfybF token : $token json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } As you see, the token field is no longer hardcoded, instead it is extracted from the first API request with extract mechanism. In the meanwhile, it is assigned to token variable, which can be referenced by the subsequent API requests. Now we save the test cases to quickstart-demo-rev-1.yml and rerun it, and we will find that both API requests to be successful.","title":"Optimize test case: correlation"},{"location":"quickstart/#optimize-test-case-parameterization","text":"Let's look back to our test set quickstart-demo-rev-1.yml , and we can see the device_sn field is still hardcoded. This may be quite different from the actual scenarios. In actual scenarios, each user's device_sn is different, so we should parameterize the request parameters, which is also called parameterization . In the meanwhile, the sign field is calculated with other header fields, thus it may change significantly if any header field changes slightly. However, the test cases are only YAML documents, it is impossible to generate parameters dynamically in such text. Fortunately, we can combine Python scripts with YAML/JSON test cases in HttpRunner . To achieve this goal, we can utilize debugtalk.py plugin and variables mechanisms. To be specific, we can create a Python file ( examples/debugtalk.py ) and implement the related algorithm in it. The debugtalk.py file can not only be located beside YAML/JSON testcase file, but also can be in any upward recursive folder. Since we want debugtalk.py to be importable, we should put a __init__.py in its folder to make it as a Python module. import hashlib import hmac import random import string SECRET_KEY = \"DebugTalk\" def get_sign ( * args ): content = '' . join ( args ) . encode ( 'ascii' ) sign_key = SECRET_KEY . encode ( 'ascii' ) sign = hmac . new ( sign_key , content , hashlib . sha1 ) . hexdigest () return sign def gen_random_string ( str_len ): random_char_list = [] for _ in range ( str_len ): random_char = random . choice ( string . ascii_letters + string . digits ) random_char_list . append ( random_char ) random_string = '' . join ( random_char_list ) return random_string And then, we can revise our demo test case and reference the functions. Suppose the revised file named quickstart-demo-rev-2.yml . - test : name : get token variables : - user_agent : 'iOS/10.3' - device_sn : ${gen_random_string(15)} - os_platform : 'ios' - app_version : '2.8.6' request : url : http://127.0.0.1:5000/api/get-token method : POST headers : user_agent : $user_agent device_sn : $device_sn os_platform : $os_platform app_version : $app_version json : sign : ${get_sign($user_agent, $device_sn, $os_platform, $app_version)} extract : - token : content.token validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 200 } - { \"check\" : \"content.token\" , \"comparator\" : \"len_eq\" , \"expect\" : 16 } - test : name : create user which does not exist request : url : http://127.0.0.1:5000/api/users/1000 method : POST headers : device_sn : $device_sn token : $token json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } In this revised test case, variable reference and function invoke mechanisms are both used. To make fields like device_sn can be used more than once, we bind values to variables in variables block. When we bind variables, we can not only bind exact value to a variable name, but also can call a function and bind the evaluated value to it. When we want to reference a variable in the test case, we can do this with a escape character $ . For example, $user_agent will not be taken as a normal string, and HttpRunner will consider it as a variable named user_agent , search and return its binding value. When we want to reference a function, we shall use another escape character ${} . Any content in ${} will be considered as function calling, so we should guarantee that we call functions in the right way. At the same time, variables can also be referenced as parameters of function.","title":"Optimize test case: parameterization"},{"location":"quickstart/#optimize-test-case-overall-config-block","text":"There is still one issue unsolved. The device_sn field is defined in the first API test case, thus it may be impossible to reference it in other test cases. Context separation is a well-designed mechanism, and we should obey this good practice. To handle this case, overall config block is supported in HttpRunner . If we define variables or import functions in config block, these variables and functions will become global and can be referenced in the whole test set. # examples/quickstart-demo-rev-3.yml - config : name : \"smoketest for CRUD users.\" variables : - device_sn : ${gen_random_string(15)} request : base_url : http://127.0.0.1:5000 headers : device_sn : $device_sn - test : name : get token variables : - user_agent : 'iOS/10.3' - os_platform : 'ios' - app_version : '2.8.6' request : url : /api/get-token method : POST headers : user_agent : $user_agent os_platform : $os_platform app_version : $app_version json : sign : ${get_sign($user_agent, $device_sn, $os_platform, $app_version)} extract : - token : content.token validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 200 } - { \"check\" : \"content.token\" , \"comparator\" : \"len_eq\" , \"expect\" : 16 } - test : name : create user which does not exist request : url : /api/users/1000 method : POST headers : token : $token json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } As you see, we define variables in config block. Also, we can set base_url in config block, thereby we can specify relative path in each API request url. Besides, we can also set common fields in config request , such as device_sn in headers. Until now, the test cases are finished and each detail is handled properly.","title":"Optimize test case: overall config block"},{"location":"quickstart/#run-test-cases-and-generate-report","text":"Finally, let's run test set quickstart-demo-rev-3.yml once more. $ ate examples/quickstart-demo-rev-4.yml Running tests... ---------------------------------------------------------------------- get token ... INFO:root: Start to POST http://127.0.0.1:5000/api/get-token INFO:root: status_code: 200, response_time: 33 ms, response_length: 46 bytes OK (0.037027)s create user which does not exist ... INFO:root: Start to POST http://127.0.0.1:5000/api/users/1000 INFO:root: status_code: 201, response_time: 15 ms, response_length: 54 bytes OK (0.016414)s ---------------------------------------------------------------------- Ran 2 tests in 0.054s OK Generating HTML reports... Template is not specified, load default template instead. Reports generated: /Users/Leo/MyProjects/HttpRunner/reports/quickstart-demo-rev-0/2017-08-01-16-51-51.html Great! The test case runs successfully and generates a HTML test report.","title":"Run test cases and generate report"},{"location":"quickstart/#further-more","text":"This is just a starting point, see the advanced guide for the advanced features. templating data extraction and validation comparator","title":"Further more"},{"location":"sponsors/","text":"\u8d5e\u52a9\u5546 \u00b6 \u611f\u8c22\u5404\u4f4d\u5bf9 HttpRunner \u7684\u8d5e\u52a9\u652f\u6301\uff01 \u91d1\u724c\u8d5e\u52a9\u5546\uff08Gold Sponsor\uff09 \u00b6 \u970d\u683c\u6c83\u5179\u6d4b\u8bd5\u5b66\u9662 \u662f\u7531\u6d4b\u5427\uff08\u5317\u4eac\uff09\u79d1\u6280\u6709\u9650\u516c\u53f8\u4e0e\u77e5\u540d\u8f6f\u4ef6\u6d4b\u8bd5\u793e\u533a TesterHome \u5408\u4f5c\u7684\u9ad8\u7aef\u6559\u80b2\u54c1\u724c\u3002\u7531 BAT \u4e00\u7ebf \u6d4b\u8bd5\u5927\u5496\u6267\u6559 \uff0c\u63d0\u4f9b \u5b9e\u6218\u9a71\u52a8 \u7684\u63a5\u53e3\u81ea\u52a8\u5316\u6d4b\u8bd5\u3001\u79fb\u52a8\u81ea\u52a8\u5316\u6d4b\u8bd5\u3001\u6027\u80fd\u6d4b\u8bd5\u3001\u6301\u7eed\u96c6\u6210\u4e0e DevOps \u7b49\u6280\u672f\u57f9\u8bad\uff0c\u4ee5\u53ca\u6d4b\u8bd5\u5f00\u53d1\u4f18\u79c0\u4eba\u624d\u5185\u63a8\u670d\u52a1\u3002 \u70b9\u51fb\u5b66\u4e60! \u970d\u683c\u6c83\u5179\u6d4b\u8bd5\u5b66\u9662\u662f HttpRunner \u7684\u9996\u5bb6\u91d1\u724c\u8d5e\u52a9\u5546\u3002 \u5f00\u6e90\u670d\u52a1\u8d5e\u52a9\u5546\uff08Open Source Sponsor\uff09 \u00b6 HttpRunner is in Sentry Sponsored plan. \u6210\u4e3a\u8d5e\u52a9\u5546 \u00b6 \u5982\u679c\u4f60\u6240\u5728\u7684\u516c\u53f8\u6216\u4e2a\u4eba\u4e5f\u60f3\u5bf9 HttpRunner \u8fdb\u884c\u8d5e\u52a9\uff0c\u53ef\u53c2\u8003\u5982\u4e0b\u65b9\u6848\uff0c\u5177\u4f53\u53ef\u8054\u7cfb \u9879\u76ee\u4f5c\u8005 \u3002 \u7b49\u7ea7 \u91d1\u724c\u8d5e\u52a9\u5546 \uff08Gold Sponsor\uff09 \u94f6\u724c\u8d5e\u52a9\u5546 \uff08Silver Sponsor\uff09 \u4e2a\u4eba\u8d5e\u8d4f \u91d1\u989d \uffe510000/\u5e74 \uffe55000/\u5e74 \u4efb\u610f \u6743\u76ca \u516c\u53f8 logo\uff08\u5927\uff09\u548c\u94fe\u63a5\u5c55\u793a\u5728 README.md 150 \u5b57\u7684\u5ba3\u4f20\u6587\u6848 \u516c\u53f8 logo\uff08\u4e2d\uff09\u548c\u94fe\u63a5\u5c55\u793a\u5728 README.md 50 \u5b57\u7684\u5ba3\u4f20\u6587\u6848 \u4e2a\u4eba ID \u548c\u94fe\u63a5\u5c55\u793a\u5728 sponsors.md","title":"Sponsors"},{"location":"sponsors/#_1","text":"\u611f\u8c22\u5404\u4f4d\u5bf9 HttpRunner \u7684\u8d5e\u52a9\u652f\u6301\uff01","title":"\u8d5e\u52a9\u5546"},{"location":"sponsors/#gold-sponsor","text":"\u970d\u683c\u6c83\u5179\u6d4b\u8bd5\u5b66\u9662 \u662f\u7531\u6d4b\u5427\uff08\u5317\u4eac\uff09\u79d1\u6280\u6709\u9650\u516c\u53f8\u4e0e\u77e5\u540d\u8f6f\u4ef6\u6d4b\u8bd5\u793e\u533a TesterHome \u5408\u4f5c\u7684\u9ad8\u7aef\u6559\u80b2\u54c1\u724c\u3002\u7531 BAT \u4e00\u7ebf \u6d4b\u8bd5\u5927\u5496\u6267\u6559 \uff0c\u63d0\u4f9b \u5b9e\u6218\u9a71\u52a8 \u7684\u63a5\u53e3\u81ea\u52a8\u5316\u6d4b\u8bd5\u3001\u79fb\u52a8\u81ea\u52a8\u5316\u6d4b\u8bd5\u3001\u6027\u80fd\u6d4b\u8bd5\u3001\u6301\u7eed\u96c6\u6210\u4e0e DevOps \u7b49\u6280\u672f\u57f9\u8bad\uff0c\u4ee5\u53ca\u6d4b\u8bd5\u5f00\u53d1\u4f18\u79c0\u4eba\u624d\u5185\u63a8\u670d\u52a1\u3002 \u70b9\u51fb\u5b66\u4e60! \u970d\u683c\u6c83\u5179\u6d4b\u8bd5\u5b66\u9662\u662f HttpRunner \u7684\u9996\u5bb6\u91d1\u724c\u8d5e\u52a9\u5546\u3002","title":"\u91d1\u724c\u8d5e\u52a9\u5546\uff08Gold Sponsor\uff09"},{"location":"sponsors/#open-source-sponsor","text":"HttpRunner is in Sentry Sponsored plan.","title":"\u5f00\u6e90\u670d\u52a1\u8d5e\u52a9\u5546\uff08Open Source Sponsor\uff09"},{"location":"sponsors/#_2","text":"\u5982\u679c\u4f60\u6240\u5728\u7684\u516c\u53f8\u6216\u4e2a\u4eba\u4e5f\u60f3\u5bf9 HttpRunner \u8fdb\u884c\u8d5e\u52a9\uff0c\u53ef\u53c2\u8003\u5982\u4e0b\u65b9\u6848\uff0c\u5177\u4f53\u53ef\u8054\u7cfb \u9879\u76ee\u4f5c\u8005 \u3002 \u7b49\u7ea7 \u91d1\u724c\u8d5e\u52a9\u5546 \uff08Gold Sponsor\uff09 \u94f6\u724c\u8d5e\u52a9\u5546 \uff08Silver Sponsor\uff09 \u4e2a\u4eba\u8d5e\u8d4f \u91d1\u989d \uffe510000/\u5e74 \uffe55000/\u5e74 \u4efb\u610f \u6743\u76ca \u516c\u53f8 logo\uff08\u5927\uff09\u548c\u94fe\u63a5\u5c55\u793a\u5728 README.md 150 \u5b57\u7684\u5ba3\u4f20\u6587\u6848 \u516c\u53f8 logo\uff08\u4e2d\uff09\u548c\u94fe\u63a5\u5c55\u793a\u5728 README.md 50 \u5b57\u7684\u5ba3\u4f20\u6587\u6848 \u4e2a\u4eba ID \u548c\u94fe\u63a5\u5c55\u793a\u5728 sponsors.md","title":"\u6210\u4e3a\u8d5e\u52a9\u5546"},{"location":"user/gen_tests/","text":"Record & Generate testcase \u00b6 capture HTTP request and response \u00b6 Before we write testcases, we should know the details of the API. It is a good choice to use a web debugging proxy tool like Charles Proxy to capture the HTTP traffic. For example, the image below illustrates post form data to postman-echo.com . export sessions to HAR file \u00b6 Then we can select captured request & response and export sessions to HTTP archive (.har) file. generate testcase with har2case \u00b6 When you get HAR file, you can use builtin command har2case to convert it to HttpRunner testcase. help \u00b6 $ har2case -h usage: har2case har2case [-h] [-2y] [-2j] [--filter FILTER] [--exclude EXCLUDE] [har_source_file] positional arguments: har_source_file Specify HAR source file optional arguments: -h, --help show this help message and exit -2y, --to-yml, --to-yaml Convert to YAML format, if not specified, convert to pytest format by default. -2j, --to-json Convert to JSON format, if not specified, convert to pytest format by default. --filter FILTER Specify filter keyword, only url include filter string will be converted. --exclude EXCLUDE Specify exclude keyword, url that includes exclude string will be ignored, multiple keywords can be joined with '|' generate testcase (pytest) \u00b6 Since HttpRunner 3.0.7 , har2case will convert HAR file to pytest by default, and it is strongly recommended to write and maintain testcases in pytest format instead of former YAML/JSON format. $ har2case har/postman-echo-post-form.har 2020-06-15 15:08:01.187 | INFO | httprunner.ext.har2case.core:gen_testcase:332 - Start to generate testcase from har/postman-echo-post-form.har 2020-06-15 15:08:01.187 | INFO | httprunner.ext.har2case.core:_make_testcase:323 - Extract info from HAR file and prepare for testcase. 2020-06-15 15:08:01.191 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/Desktop/demo/.env 2020-06-15 15:08:01.191 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 15:08:01.191 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 15:08:01.193 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/Desktop/demo/har/postman-echo-post-form.har 2020-06-15 15:08:01.193 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py 2020-06-15 15:08:01.194 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... reformatted /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py All done! \u2728 \ud83c\udf70 \u2728 1 file reformatted. 2020-06-15 15:08:01.469 | INFO | httprunner.ext.har2case.core:gen_testcase:353 - generated testcase: /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py The generated pytest file is a standard Python file shown as below. # NOTE: Generated By HttpRunner v3.0.12 # FROM: har/postman-echo-post-form.har from httprunner import HttpRunner , Config , Step , RunRequest , RunTestCase class TestCasePostmanEchoPostForm ( HttpRunner ): config = Config ( \"testcase description\" ) . verify ( False ) teststeps = [ Step ( RunRequest ( \"/get\" ) . get ( \"https://postman-echo.com/get\" ) . with_params ( ** { \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" }) . with_headers ( ** { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"6606343b-10e5-4165-a89f-6c301b762ce0\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" , } ) . with_cookies ( ** { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" } ) . validate () . assert_equal ( \"status_code\" , 200 ) . assert_equal ( 'headers.\"Content-Type\"' , \"application/json; charset=utf-8\" ) . assert_equal ( \"body.url\" , \"https://postman-echo.com/get?foo1=bar1&foo2=bar2\" ) ), Step ( RunRequest ( \"/post\" ) . post ( \"https://postman-echo.com/post\" ) . with_headers ( ** { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"3e408e9d-25ca-4b31-b04b-7f4898a8cd49\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Content-Type\" : \"application/x-www-form-urlencoded\" , \"Content-Length\" : \"19\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" , } ) . with_cookies ( ** { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" } ) . with_data ({ \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" }) . validate () . assert_equal ( \"status_code\" , 200 ) . assert_equal ( 'headers.\"Content-Type\"' , \"application/json; charset=utf-8\" ) . assert_equal ( \"body.data\" , \"\" ) . assert_equal ( \"body.url\" , \"https://postman-echo.com/post\" ) ), ] if __name__ == \"__main__\" : TestCasePostmanEchoPostForm () . test_start () And it can be run with hrun command or the native pytest command. In fact, hrun is only a wrapper of pytest , thus the effect is basically the same. $ hrun har/postman_echo_post_form_test.py 2020-06-15 15:23:03.502 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/Desktop/demo/.env 2020-06-15 15:23:03.502 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 15:23:03.502 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 15:23:03.503 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... All done! \u2728 \ud83c\udf70 \u2728 1 file left unchanged. 2020-06-15 15:23:03.662 | INFO | httprunner.cli:main_run:56 - start to run tests with pytest. HttpRunner version: 3.0.12 ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/Desktop/demo plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 1 item har/postman_echo_post_form_test.py . [100%] ======================================================================= 1 passed in 2.60s ======================================================================= $ pytest har/postman_echo_post_form_test.py ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/Desktop/demo plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 1 item har/postman_echo_post_form_test.py . [100%] ================================================================= 1 passed, 1 warning in 4.11s ================================================================== generate testcase (YAML/JSON) \u00b6 Of course, you can also generate former YAML/JSON testcase format. Just add -2y/--to-yml or -2j/--to-json argument to har2case . $ har2case har/postman-echo-post-form.har -2j 2020-06-15 15:32:02.955 | INFO | httprunner.ext.har2case.core:gen_testcase:332 - Start to generate testcase from har/postman-echo-post-form.har 2020-06-15 15:32:02.955 | INFO | httprunner.ext.har2case.core:_make_testcase:323 - Extract info from HAR file and prepare for testcase. 2020-06-15 15:32:02.958 | INFO | httprunner.ext.har2case.utils:dump_json:122 - dump testcase to JSON format. 2020-06-15 15:32:02.959 | INFO | httprunner.ext.har2case.utils:dump_json:131 - Generate JSON testcase successfully: har/postman-echo-post-form.json 2020-06-15 15:32:02.959 | INFO | httprunner.ext.har2case.core:gen_testcase:353 - generated testcase: har/postman-echo-post-form.json { \"config\" : { \"name\" : \"testcase description\" , \"variables\" : {}, \"verify\" : false }, \"teststeps\" : [ { \"name\" : \"/get\" , \"request\" : { \"url\" : \"https://postman-echo.com/get\" , \"params\" : { \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" }, \"method\" : \"GET\" , \"cookies\" : { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" }, \"headers\" : { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"6606343b-10e5-4165-a89f-6c301b762ce0\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" } }, \"validate\" : [ { \"eq\" : [ \"status_code\" , 200 ] }, { \"eq\" : [ \"headers.Content-Type\" , \"application/json; charset=utf-8\" ] }, { \"eq\" : [ \"body.url\" , \"https://postman-echo.com/get?foo1=bar1&foo2=bar2\" ] } ] }, { \"name\" : \"/post\" , \"request\" : { \"url\" : \"https://postman-echo.com/post\" , \"method\" : \"POST\" , \"cookies\" : { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" }, \"headers\" : { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"3e408e9d-25ca-4b31-b04b-7f4898a8cd49\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Content-Type\" : \"application/x-www-form-urlencoded\" , \"Content-Length\" : \"19\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" }, \"data\" : { \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" } }, \"validate\" : [ { \"eq\" : [ \"status_code\" , 200 ] }, { \"eq\" : [ \"headers.Content-Type\" , \"application/json; charset=utf-8\" ] }, { \"eq\" : [ \"body.data\" , \"\" ] }, { \"eq\" : [ \"body.url\" , \"https://postman-echo.com/post\" ] } ] } ] } The YAML/JSON testcase has the same info with pytest testcase, and you can run YAML/JSON testcase with hrun command. $ hrun har/postman-echo-post-form.json 2020-06-15 15:37:15.621 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/Desktop/demo/.env 2020-06-15 15:37:15.622 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 15:37:15.622 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 15:37:15.623 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/Desktop/demo/har/postman-echo-post-form.json 2020-06-15 15:37:15.625 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py 2020-06-15 15:37:15.625 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... reformatted /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py All done! \u2728 \ud83c\udf70 \u2728 1 file reformatted, 1 file left unchanged. 2020-06-15 15:37:15.962 | INFO | httprunner.cli:main_run:56 - start to run tests with pytest. HttpRunner version: 3.0.12 ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/Desktop/demo plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 1 item har/postman_echo_post_form_test.py . [100%] ======================================================================= 1 passed in 2.03s =======================================================================","title":"Record & Generate testcase"},{"location":"user/gen_tests/#record-generate-testcase","text":"","title":"Record & Generate testcase"},{"location":"user/gen_tests/#capture-http-request-and-response","text":"Before we write testcases, we should know the details of the API. It is a good choice to use a web debugging proxy tool like Charles Proxy to capture the HTTP traffic. For example, the image below illustrates post form data to postman-echo.com .","title":"capture HTTP request and response"},{"location":"user/gen_tests/#export-sessions-to-har-file","text":"Then we can select captured request & response and export sessions to HTTP archive (.har) file.","title":"export sessions to HAR file"},{"location":"user/gen_tests/#generate-testcase-with-har2case","text":"When you get HAR file, you can use builtin command har2case to convert it to HttpRunner testcase.","title":"generate testcase with har2case"},{"location":"user/gen_tests/#help","text":"$ har2case -h usage: har2case har2case [-h] [-2y] [-2j] [--filter FILTER] [--exclude EXCLUDE] [har_source_file] positional arguments: har_source_file Specify HAR source file optional arguments: -h, --help show this help message and exit -2y, --to-yml, --to-yaml Convert to YAML format, if not specified, convert to pytest format by default. -2j, --to-json Convert to JSON format, if not specified, convert to pytest format by default. --filter FILTER Specify filter keyword, only url include filter string will be converted. --exclude EXCLUDE Specify exclude keyword, url that includes exclude string will be ignored, multiple keywords can be joined with '|'","title":"help"},{"location":"user/gen_tests/#generate-testcase-pytest","text":"Since HttpRunner 3.0.7 , har2case will convert HAR file to pytest by default, and it is strongly recommended to write and maintain testcases in pytest format instead of former YAML/JSON format. $ har2case har/postman-echo-post-form.har 2020-06-15 15:08:01.187 | INFO | httprunner.ext.har2case.core:gen_testcase:332 - Start to generate testcase from har/postman-echo-post-form.har 2020-06-15 15:08:01.187 | INFO | httprunner.ext.har2case.core:_make_testcase:323 - Extract info from HAR file and prepare for testcase. 2020-06-15 15:08:01.191 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/Desktop/demo/.env 2020-06-15 15:08:01.191 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 15:08:01.191 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 15:08:01.193 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/Desktop/demo/har/postman-echo-post-form.har 2020-06-15 15:08:01.193 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py 2020-06-15 15:08:01.194 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... reformatted /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py All done! \u2728 \ud83c\udf70 \u2728 1 file reformatted. 2020-06-15 15:08:01.469 | INFO | httprunner.ext.har2case.core:gen_testcase:353 - generated testcase: /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py The generated pytest file is a standard Python file shown as below. # NOTE: Generated By HttpRunner v3.0.12 # FROM: har/postman-echo-post-form.har from httprunner import HttpRunner , Config , Step , RunRequest , RunTestCase class TestCasePostmanEchoPostForm ( HttpRunner ): config = Config ( \"testcase description\" ) . verify ( False ) teststeps = [ Step ( RunRequest ( \"/get\" ) . get ( \"https://postman-echo.com/get\" ) . with_params ( ** { \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" }) . with_headers ( ** { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"6606343b-10e5-4165-a89f-6c301b762ce0\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" , } ) . with_cookies ( ** { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" } ) . validate () . assert_equal ( \"status_code\" , 200 ) . assert_equal ( 'headers.\"Content-Type\"' , \"application/json; charset=utf-8\" ) . assert_equal ( \"body.url\" , \"https://postman-echo.com/get?foo1=bar1&foo2=bar2\" ) ), Step ( RunRequest ( \"/post\" ) . post ( \"https://postman-echo.com/post\" ) . with_headers ( ** { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"3e408e9d-25ca-4b31-b04b-7f4898a8cd49\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Content-Type\" : \"application/x-www-form-urlencoded\" , \"Content-Length\" : \"19\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" , } ) . with_cookies ( ** { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" } ) . with_data ({ \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" }) . validate () . assert_equal ( \"status_code\" , 200 ) . assert_equal ( 'headers.\"Content-Type\"' , \"application/json; charset=utf-8\" ) . assert_equal ( \"body.data\" , \"\" ) . assert_equal ( \"body.url\" , \"https://postman-echo.com/post\" ) ), ] if __name__ == \"__main__\" : TestCasePostmanEchoPostForm () . test_start () And it can be run with hrun command or the native pytest command. In fact, hrun is only a wrapper of pytest , thus the effect is basically the same. $ hrun har/postman_echo_post_form_test.py 2020-06-15 15:23:03.502 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/Desktop/demo/.env 2020-06-15 15:23:03.502 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 15:23:03.502 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 15:23:03.503 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... All done! \u2728 \ud83c\udf70 \u2728 1 file left unchanged. 2020-06-15 15:23:03.662 | INFO | httprunner.cli:main_run:56 - start to run tests with pytest. HttpRunner version: 3.0.12 ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/Desktop/demo plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 1 item har/postman_echo_post_form_test.py . [100%] ======================================================================= 1 passed in 2.60s ======================================================================= $ pytest har/postman_echo_post_form_test.py ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/Desktop/demo plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 1 item har/postman_echo_post_form_test.py . [100%] ================================================================= 1 passed, 1 warning in 4.11s ==================================================================","title":"generate testcase (pytest)"},{"location":"user/gen_tests/#generate-testcase-yamljson","text":"Of course, you can also generate former YAML/JSON testcase format. Just add -2y/--to-yml or -2j/--to-json argument to har2case . $ har2case har/postman-echo-post-form.har -2j 2020-06-15 15:32:02.955 | INFO | httprunner.ext.har2case.core:gen_testcase:332 - Start to generate testcase from har/postman-echo-post-form.har 2020-06-15 15:32:02.955 | INFO | httprunner.ext.har2case.core:_make_testcase:323 - Extract info from HAR file and prepare for testcase. 2020-06-15 15:32:02.958 | INFO | httprunner.ext.har2case.utils:dump_json:122 - dump testcase to JSON format. 2020-06-15 15:32:02.959 | INFO | httprunner.ext.har2case.utils:dump_json:131 - Generate JSON testcase successfully: har/postman-echo-post-form.json 2020-06-15 15:32:02.959 | INFO | httprunner.ext.har2case.core:gen_testcase:353 - generated testcase: har/postman-echo-post-form.json { \"config\" : { \"name\" : \"testcase description\" , \"variables\" : {}, \"verify\" : false }, \"teststeps\" : [ { \"name\" : \"/get\" , \"request\" : { \"url\" : \"https://postman-echo.com/get\" , \"params\" : { \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" }, \"method\" : \"GET\" , \"cookies\" : { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" }, \"headers\" : { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"6606343b-10e5-4165-a89f-6c301b762ce0\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" } }, \"validate\" : [ { \"eq\" : [ \"status_code\" , 200 ] }, { \"eq\" : [ \"headers.Content-Type\" , \"application/json; charset=utf-8\" ] }, { \"eq\" : [ \"body.url\" , \"https://postman-echo.com/get?foo1=bar1&foo2=bar2\" ] } ] }, { \"name\" : \"/post\" , \"request\" : { \"url\" : \"https://postman-echo.com/post\" , \"method\" : \"POST\" , \"cookies\" : { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" }, \"headers\" : { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"3e408e9d-25ca-4b31-b04b-7f4898a8cd49\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Content-Type\" : \"application/x-www-form-urlencoded\" , \"Content-Length\" : \"19\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" }, \"data\" : { \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" } }, \"validate\" : [ { \"eq\" : [ \"status_code\" , 200 ] }, { \"eq\" : [ \"headers.Content-Type\" , \"application/json; charset=utf-8\" ] }, { \"eq\" : [ \"body.data\" , \"\" ] }, { \"eq\" : [ \"body.url\" , \"https://postman-echo.com/post\" ] } ] } ] } The YAML/JSON testcase has the same info with pytest testcase, and you can run YAML/JSON testcase with hrun command. $ hrun har/postman-echo-post-form.json 2020-06-15 15:37:15.621 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/Desktop/demo/.env 2020-06-15 15:37:15.622 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 15:37:15.622 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 15:37:15.623 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/Desktop/demo/har/postman-echo-post-form.json 2020-06-15 15:37:15.625 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py 2020-06-15 15:37:15.625 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... reformatted /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py All done! \u2728 \ud83c\udf70 \u2728 1 file reformatted, 1 file left unchanged. 2020-06-15 15:37:15.962 | INFO | httprunner.cli:main_run:56 - start to run tests with pytest. HttpRunner version: 3.0.12 ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/Desktop/demo plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 1 item har/postman_echo_post_form_test.py . [100%] ======================================================================= 1 passed in 2.03s =======================================================================","title":"generate testcase (YAML/JSON)"},{"location":"user/scaffold/","text":"Scaffold \u00b6 If you want to create a new project, you can use the scaffold to startup quickly. help \u00b6 $ httprunner startproject -h usage: httprunner startproject [-h] [project_name] positional arguments: project_name Specify new project name. optional arguments: -h, --help show this help message and exit create new project \u00b6 The only argument you need to specify is the project name. $ httprunner startproject demo 2020-06-15 11:53:25.498 | INFO | httprunner.scaffold:create_scaffold:37 - Create new project: demo Project Root Dir: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo created folder: demo created folder: demo/har created folder: demo/testcases created folder: demo/reports created file: demo/testcases/demo_testcase_request.yml created file: demo/testcases/demo_testcase_ref.yml created file: demo/debugtalk.py created file: demo/.env created file: demo/.gitignore $ tree demo -a demo \u251c\u2500\u2500 .env \u251c\u2500\u2500 .gitignore \u251c\u2500\u2500 debugtalk.py \u251c\u2500\u2500 har \u251c\u2500\u2500 reports \u2514\u2500\u2500 testcases \u251c\u2500\u2500 demo_testcase_ref.yml \u2514\u2500\u2500 demo_testcase_request.yml 3 directories, 5 files If you specify a project name that already exists, you will get a warning. $ httprunner startproject demo 2020-06-15 11:55:03.192 | WARNING | httprunner.scaffold:create_scaffold:32 - Project demo exists, please specify a new project name. $ tree demo -a demo \u251c\u2500\u2500 .env \u251c\u2500\u2500 .gitignore \u251c\u2500\u2500 debugtalk.py \u251c\u2500\u2500 har \u251c\u2500\u2500 reports \u2514\u2500\u2500 testcases \u251c\u2500\u2500 demo_testcase_ref.yml \u2514\u2500\u2500 demo_testcase_request.yml 3 directories, 5 files run scaffold project \u00b6 The scaffold project has several valid testcases, so you can run tests without any edit. $ hrun demo 2020-06-15 11:57:15.883 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/.env 2020-06-15 11:57:15.883 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 11:57:15.884 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 11:57:15.885 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_ref.yml 2020-06-15 11:57:15.898 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request.yml 2020-06-15 11:57:15.899 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request_test.py 2020-06-15 11:57:15.900 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_ref_test.py 2020-06-15 11:57:15.911 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request.yml 2020-06-15 11:57:15.912 | INFO | httprunner.make:__ensure_project_meta_files:128 - copy .env to /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/_env 2020-06-15 11:57:15.912 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... reformatted /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_ref_test.py reformatted /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request_test.py All done! \u2728 \ud83c\udf70 \u2728 2 files reformatted, 1 file left unchanged. 2020-06-15 11:57:16.299 | INFO | httprunner.cli:main_run:56 - start to run tests with pytest. HttpRunner version: 3.0.12 ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 2 items demo/testcases/demo_testcase_request_test.py . [ 50%] demo/testcases/demo_testcase_ref_test.py . [100%] ======================================================================= 2 passed in 6.87s =======================================================================","title":"Scaffold"},{"location":"user/scaffold/#scaffold","text":"If you want to create a new project, you can use the scaffold to startup quickly.","title":"Scaffold"},{"location":"user/scaffold/#help","text":"$ httprunner startproject -h usage: httprunner startproject [-h] [project_name] positional arguments: project_name Specify new project name. optional arguments: -h, --help show this help message and exit","title":"help"},{"location":"user/scaffold/#create-new-project","text":"The only argument you need to specify is the project name. $ httprunner startproject demo 2020-06-15 11:53:25.498 | INFO | httprunner.scaffold:create_scaffold:37 - Create new project: demo Project Root Dir: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo created folder: demo created folder: demo/har created folder: demo/testcases created folder: demo/reports created file: demo/testcases/demo_testcase_request.yml created file: demo/testcases/demo_testcase_ref.yml created file: demo/debugtalk.py created file: demo/.env created file: demo/.gitignore $ tree demo -a demo \u251c\u2500\u2500 .env \u251c\u2500\u2500 .gitignore \u251c\u2500\u2500 debugtalk.py \u251c\u2500\u2500 har \u251c\u2500\u2500 reports \u2514\u2500\u2500 testcases \u251c\u2500\u2500 demo_testcase_ref.yml \u2514\u2500\u2500 demo_testcase_request.yml 3 directories, 5 files If you specify a project name that already exists, you will get a warning. $ httprunner startproject demo 2020-06-15 11:55:03.192 | WARNING | httprunner.scaffold:create_scaffold:32 - Project demo exists, please specify a new project name. $ tree demo -a demo \u251c\u2500\u2500 .env \u251c\u2500\u2500 .gitignore \u251c\u2500\u2500 debugtalk.py \u251c\u2500\u2500 har \u251c\u2500\u2500 reports \u2514\u2500\u2500 testcases \u251c\u2500\u2500 demo_testcase_ref.yml \u2514\u2500\u2500 demo_testcase_request.yml 3 directories, 5 files","title":"create new project"},{"location":"user/scaffold/#run-scaffold-project","text":"The scaffold project has several valid testcases, so you can run tests without any edit. $ hrun demo 2020-06-15 11:57:15.883 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/.env 2020-06-15 11:57:15.883 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 11:57:15.884 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 11:57:15.885 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_ref.yml 2020-06-15 11:57:15.898 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request.yml 2020-06-15 11:57:15.899 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request_test.py 2020-06-15 11:57:15.900 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_ref_test.py 2020-06-15 11:57:15.911 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request.yml 2020-06-15 11:57:15.912 | INFO | httprunner.make:__ensure_project_meta_files:128 - copy .env to /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/_env 2020-06-15 11:57:15.912 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... reformatted /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_ref_test.py reformatted /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request_test.py All done! \u2728 \ud83c\udf70 \u2728 2 files reformatted, 1 file left unchanged. 2020-06-15 11:57:16.299 | INFO | httprunner.cli:main_run:56 - start to run tests with pytest. HttpRunner version: 3.0.12 ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 2 items demo/testcases/demo_testcase_request_test.py . [ 50%] demo/testcases/demo_testcase_ref_test.py . [100%] ======================================================================= 2 passed in 6.87s =======================================================================","title":"run scaffold project"}]} \ No newline at end of file +{"config":{"lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"HttpRunner \u00b6 HttpRunner is a simple & elegant, yet powerful HTTP(S) testing framework. Enjoy! \u2728 \ud83d\ude80 \u2728 This docs site is corresponding to the latest version 3.x , for 2.x you can reference archive link . Design Philosophy \u00b6 Convention over configuration ROI matters Embrace open source, leverage requests , pytest , pydantic , allure and locust . Key Features \u00b6 Inherit all powerful features of requests , just have fun to handle HTTP(S) in human way. Define testcase in YAML or JSON format, run with pytest in concise and elegant manner. Record and generate testcases with HAR support. Supports variables / extract / validate / hooks mechanisms to create extremely complex test scenarios. With debugtalk.py plugin, any function can be used in any part of your testcase. With jmespath , extract and validate json response has never been easier. With pytest , hundreds of plugins are readily available. With allure , test report can be pretty nice and powerful. With reuse of locust , you can run performance test without extra work. CLI command supported, perfect combination with CI/CD . Subscribe \u00b6 \u5173\u6ce8 HttpRunner \u7684\u5fae\u4fe1\u516c\u4f17\u53f7\uff0c\u7b2c\u4e00\u65f6\u95f4\u83b7\u5f97\u6700\u65b0\u8d44\u8baf\u3002","title":"Introduction"},{"location":"#httprunner","text":"HttpRunner is a simple & elegant, yet powerful HTTP(S) testing framework. Enjoy! \u2728 \ud83d\ude80 \u2728 This docs site is corresponding to the latest version 3.x , for 2.x you can reference archive link .","title":"HttpRunner"},{"location":"#design-philosophy","text":"Convention over configuration ROI matters Embrace open source, leverage requests , pytest , pydantic , allure and locust .","title":"Design Philosophy"},{"location":"#key-features","text":"Inherit all powerful features of requests , just have fun to handle HTTP(S) in human way. Define testcase in YAML or JSON format, run with pytest in concise and elegant manner. Record and generate testcases with HAR support. Supports variables / extract / validate / hooks mechanisms to create extremely complex test scenarios. With debugtalk.py plugin, any function can be used in any part of your testcase. With jmespath , extract and validate json response has never been easier. With pytest , hundreds of plugins are readily available. With allure , test report can be pretty nice and powerful. With reuse of locust , you can run performance test without extra work. CLI command supported, perfect combination with CI/CD .","title":"Key Features"},{"location":"#subscribe","text":"\u5173\u6ce8 HttpRunner \u7684\u5fae\u4fe1\u516c\u4f17\u53f7\uff0c\u7b2c\u4e00\u65f6\u95f4\u83b7\u5f97\u6700\u65b0\u8d44\u8baf\u3002","title":"Subscribe"},{"location":"CHANGELOG/","text":"Release History \u00b6 3.0.13 (2020-06-15) \u00b6 Fixed fix: avoid '.csv' been converted to '_csv' fix: convert har to JSON format testcase fix: missing ${var} handling in overriding config variables 3.0.12 (2020-06-14) \u00b6 Fixed fix: compatibility with different path separators of Linux and Windows fix: IndexError in ensure_file_path_valid when file_path=os.getcwd() fix: ensure step referenced api, convert to v3 testcase fix: several other compatibility issues Changed change: skip reporting sentry for errors occurred in debugtalk.py 3.0.11 (2020-06-08) \u00b6 Changed change: override variables (1) testcase: session variables > step variables > config variables (2) testsuite: testcase variables > config variables (3) testsuite testcase variables > testcase config variables Fixed fix: incorrect summary success when testcase failed fix: reload to refresh previously loaded debugtalk module fix: escape $$ in variable value 3.0.10 (2020-06-07) \u00b6 Added feat: implement step setup/teardown hooks feat: support alter response in teardown hooks Fixed fix: ensure upload ready fix: add ExtendJSONEncoder to safely dump json data with python object, such as MultipartEncoder 3.0.9 (2020-06-07) \u00b6 Fixed fix: miss formatting referenced testcase fix: handle cases when parent directory name includes dot/hyphen/space Changed change: add export keyword in TStep to export session variables from referenced testcase change: rename TestCaseInOut field, config_vars and export_vars change: rename StepData field, export_vars change: add --tb=short for hrun command to use shorter traceback format by default change: search debugtalk.py upward recursively until system root dir 3.0.8 (2020-06-04) \u00b6 Added feat: add sentry sdk feat: extract session variable from referenced testcase step Fixed fix: missing request json fix: override testsuite/testcase config verify fix: only strip whitespaces and tabs, \\n\\r are left because they maybe used in changeset fix: log testcase duration before raise ValidationFailure Changed change: add httprunner version in generated pytest file 3.0.7 (2020-06-03) \u00b6 Added feat: make pytest files in chain style feat: hrun supports run pytest files feat: get raw testcase model from pytest file Fixed fix: convert jmespath.search result to int/float unintentionally fix: referenced testcase should not be run duplicately fix: requests.cookies.CookieConflictError, multiple cookies with name fix: missing exit code from pytest fix: skip invalid testcase/testsuite yaml/json file Changed change: har2case generate pytest file by default docs: update sponsor info 3.0.6 (2020-05-29) \u00b6 Added feat: make referenced testcase as pytest class Fixed fix: ensure converted python file in utf-8 encoding fix: duplicate running referenced testcase fix: ensure compatibility issues between testcase format v2 and v3 fix: ensure compatibility with deprecated cli args in v2, include --failfast/--report-file/--save-tests fix: UnicodeDecodeError when request body in protobuf Changed change: make allure-pytest , requests-toolbelt , filetype as optional dependencies change: move all unittests to tests folder change: save testcase log in PWD/logs/ directory 3.0.5 (2020-05-22) \u00b6 Added feat: each testcase has an unique id in uuid4 format feat: add default header HRUN-Request-ID for each testcase #721 feat: builtin allure report feat: dump log for each testcase Fixed fix: ensure referenced testcase share the same session Changed change: remove default added -s option for hrun 3.0.4 (2020-05-19) \u00b6 Added feat: make testsuite and run testsuite feat: testcase/testsuite config support getting variables by function feat: har2case with request cookies feat: log request/response headers and body with indent Fixed fix: extract response cookies fix: handle errors when no valid testcases generated Changed change: har2case do not ignore request headers, except for header startswith : 3.0.3 (2020-05-17) \u00b6 Fixed fix: compatibility with testcase file path includes dots, space and minus sign fix: testcase generator, validate content.xxx => body.xxx fix: scaffold for v3 3.0.2 (2020-05-16) \u00b6 Added feat: add make sub-command to generate python testcases from YAML/JSON feat: format generated python testcases with black test: add postman echo & httpbin as testcase examples Changed refactor all replace jsonschema validation with pydantic remove compatibility with testcase/testsuite format v1 replace unittest with pytest remove builtin html report, allure will be used with pytest later remove locust support temporarily update command line interface 3.0.1 (2020-03-24) \u00b6 Changed remove sentry sdk 3.0.0 (2020-03-10) \u00b6 Added feat: dump log for each testcase feat: add default header HRUN-Request-ID for each testcase #721 Changed remove support for Python 2.7 replace logging with loguru replace string format with f-string remove dependency colorama and colorlog generate reports/logs folder in current working directory remove cli --validate remove cli --pretty","title":"CHANGELOG"},{"location":"CHANGELOG/#release-history","text":"","title":"Release History"},{"location":"CHANGELOG/#3013-2020-06-15","text":"Fixed fix: avoid '.csv' been converted to '_csv' fix: convert har to JSON format testcase fix: missing ${var} handling in overriding config variables","title":"3.0.13 (2020-06-15)"},{"location":"CHANGELOG/#3012-2020-06-14","text":"Fixed fix: compatibility with different path separators of Linux and Windows fix: IndexError in ensure_file_path_valid when file_path=os.getcwd() fix: ensure step referenced api, convert to v3 testcase fix: several other compatibility issues Changed change: skip reporting sentry for errors occurred in debugtalk.py","title":"3.0.12 (2020-06-14)"},{"location":"CHANGELOG/#3011-2020-06-08","text":"Changed change: override variables (1) testcase: session variables > step variables > config variables (2) testsuite: testcase variables > config variables (3) testsuite testcase variables > testcase config variables Fixed fix: incorrect summary success when testcase failed fix: reload to refresh previously loaded debugtalk module fix: escape $$ in variable value","title":"3.0.11 (2020-06-08)"},{"location":"CHANGELOG/#3010-2020-06-07","text":"Added feat: implement step setup/teardown hooks feat: support alter response in teardown hooks Fixed fix: ensure upload ready fix: add ExtendJSONEncoder to safely dump json data with python object, such as MultipartEncoder","title":"3.0.10 (2020-06-07)"},{"location":"CHANGELOG/#309-2020-06-07","text":"Fixed fix: miss formatting referenced testcase fix: handle cases when parent directory name includes dot/hyphen/space Changed change: add export keyword in TStep to export session variables from referenced testcase change: rename TestCaseInOut field, config_vars and export_vars change: rename StepData field, export_vars change: add --tb=short for hrun command to use shorter traceback format by default change: search debugtalk.py upward recursively until system root dir","title":"3.0.9 (2020-06-07)"},{"location":"CHANGELOG/#308-2020-06-04","text":"Added feat: add sentry sdk feat: extract session variable from referenced testcase step Fixed fix: missing request json fix: override testsuite/testcase config verify fix: only strip whitespaces and tabs, \\n\\r are left because they maybe used in changeset fix: log testcase duration before raise ValidationFailure Changed change: add httprunner version in generated pytest file","title":"3.0.8 (2020-06-04)"},{"location":"CHANGELOG/#307-2020-06-03","text":"Added feat: make pytest files in chain style feat: hrun supports run pytest files feat: get raw testcase model from pytest file Fixed fix: convert jmespath.search result to int/float unintentionally fix: referenced testcase should not be run duplicately fix: requests.cookies.CookieConflictError, multiple cookies with name fix: missing exit code from pytest fix: skip invalid testcase/testsuite yaml/json file Changed change: har2case generate pytest file by default docs: update sponsor info","title":"3.0.7 (2020-06-03)"},{"location":"CHANGELOG/#306-2020-05-29","text":"Added feat: make referenced testcase as pytest class Fixed fix: ensure converted python file in utf-8 encoding fix: duplicate running referenced testcase fix: ensure compatibility issues between testcase format v2 and v3 fix: ensure compatibility with deprecated cli args in v2, include --failfast/--report-file/--save-tests fix: UnicodeDecodeError when request body in protobuf Changed change: make allure-pytest , requests-toolbelt , filetype as optional dependencies change: move all unittests to tests folder change: save testcase log in PWD/logs/ directory","title":"3.0.6 (2020-05-29)"},{"location":"CHANGELOG/#305-2020-05-22","text":"Added feat: each testcase has an unique id in uuid4 format feat: add default header HRUN-Request-ID for each testcase #721 feat: builtin allure report feat: dump log for each testcase Fixed fix: ensure referenced testcase share the same session Changed change: remove default added -s option for hrun","title":"3.0.5 (2020-05-22)"},{"location":"CHANGELOG/#304-2020-05-19","text":"Added feat: make testsuite and run testsuite feat: testcase/testsuite config support getting variables by function feat: har2case with request cookies feat: log request/response headers and body with indent Fixed fix: extract response cookies fix: handle errors when no valid testcases generated Changed change: har2case do not ignore request headers, except for header startswith :","title":"3.0.4 (2020-05-19)"},{"location":"CHANGELOG/#303-2020-05-17","text":"Fixed fix: compatibility with testcase file path includes dots, space and minus sign fix: testcase generator, validate content.xxx => body.xxx fix: scaffold for v3","title":"3.0.3 (2020-05-17)"},{"location":"CHANGELOG/#302-2020-05-16","text":"Added feat: add make sub-command to generate python testcases from YAML/JSON feat: format generated python testcases with black test: add postman echo & httpbin as testcase examples Changed refactor all replace jsonschema validation with pydantic remove compatibility with testcase/testsuite format v1 replace unittest with pytest remove builtin html report, allure will be used with pytest later remove locust support temporarily update command line interface","title":"3.0.2 (2020-05-16)"},{"location":"CHANGELOG/#301-2020-03-24","text":"Changed remove sentry sdk","title":"3.0.1 (2020-03-24)"},{"location":"CHANGELOG/#300-2020-03-10","text":"Added feat: dump log for each testcase feat: add default header HRUN-Request-ID for each testcase #721 Changed remove support for Python 2.7 replace logging with loguru replace string format with f-string remove dependency colorama and colorlog generate reports/logs folder in current working directory remove cli --validate remove cli --pretty","title":"3.0.0 (2020-03-10)"},{"location":"installation/","text":"HttpRunner is developed with Python, it supports Python 3.6+ and most operating systems. Combination of Python 3.6/3.7/3.8 and macOS/Linux/Windows are tested continuously on GitHub-Actions . Installation \u00b6 HttpRunner is available on PyPI and can be installed through pip . $ pip3 install httprunner If you want to keep up with the latest version, you can install with github repository url. $ pip3 install git+https://github.com/httprunner/httprunner.git@master If\b you have installed HttpRunner before and want to upgrade to the latest version, you can use the -U option. $ pip3 install -U httprunner $ pip3 install -U git+https://github.com/httprunner/httprunner.git@master Check Installation \u00b6 When HttpRunner is installed, 4 commands will be added in your system. httprunner : main command, used for all functions hrun : alias for httprunner run , used to run YAML/JSON/pytest testcases hmake : alias for httprunner make , used to convert YAML/JSON testcases to pytest files har2case : alias for httprunner har2case , used to convert HAR to YAML/JSON testcases To see HttpRunner version: $ httprunner -V # hrun -V 3.0.10 To see available options, run: $ httprunner -h usage: httprunner [-h] [-V] {run,startproject,har2case,make} ... One-stop solution for HTTP(S) testing. positional arguments: {run,startproject,har2case,make} sub-command help run Make HttpRunner testcases and run with pytest. startproject Create a new project with template structure. har2case Convert HAR(HTTP Archive) to YAML/JSON testcases for HttpRunner. make Convert YAML/JSON testcases to pytest cases. optional arguments: -h, --help show this help message and exit -V, --version show version","title":"Installation"},{"location":"installation/#installation","text":"HttpRunner is available on PyPI and can be installed through pip . $ pip3 install httprunner If you want to keep up with the latest version, you can install with github repository url. $ pip3 install git+https://github.com/httprunner/httprunner.git@master If\b you have installed HttpRunner before and want to upgrade to the latest version, you can use the -U option. $ pip3 install -U httprunner $ pip3 install -U git+https://github.com/httprunner/httprunner.git@master","title":"Installation"},{"location":"installation/#check-installation","text":"When HttpRunner is installed, 4 commands will be added in your system. httprunner : main command, used for all functions hrun : alias for httprunner run , used to run YAML/JSON/pytest testcases hmake : alias for httprunner make , used to convert YAML/JSON testcases to pytest files har2case : alias for httprunner har2case , used to convert HAR to YAML/JSON testcases To see HttpRunner version: $ httprunner -V # hrun -V 3.0.10 To see available options, run: $ httprunner -h usage: httprunner [-h] [-V] {run,startproject,har2case,make} ... One-stop solution for HTTP(S) testing. positional arguments: {run,startproject,har2case,make} sub-command help run Make HttpRunner testcases and run with pytest. startproject Create a new project with template structure. har2case Convert HAR(HTTP Archive) to YAML/JSON testcases for HttpRunner. make Convert YAML/JSON testcases to pytest cases. optional arguments: -h, --help show this help message and exit -V, --version show version","title":"Check Installation"},{"location":"quickstart/","text":"Quick Start \u00b6 First of all, remember HttpRunner is a simple yet powerful HTTP(S) testing framework. This document will help you to learn HttpRunner in 10 minutes. Write the first test case \u00b6 Open your favorite text editor and you can write test cases like this. - test : name : get token request : url : http://127.0.0.1:5000/api/get-token method : POST headers : user_agent : iOS/10.3 device_sn : 9TN6O2Bn1vzfybF os_platform : ios app_version : 2.8.6 json : sign : 19067cf712265eb5426db8d3664026c1ccea02b9 - test : name : create user which does not exist request : url : http://127.0.0.1:5000/api/users/1000 method : POST headers : device_sn : 9TN6O2Bn1vzfybF token : F8prvGryC5beBr4g json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } As you see, each API request is described in a test block. And in the request field, it describes the detail of HTTP request, includes url, method, headers and data, which are in line with the captured traffic. You may wonder why we use the json field other than data . That's because the post data is in JSON format, when we use json to indicate the post data, we do not have to specify Content-Type to be application/json in request headers or dump data before request. Have you recalled some familiar scenes? Yes! That's what we did in requests.request ! Since HttpRunner takes full reuse of Requests , it inherits all powerful features of Requests , and we can handle HTTP request as the way we do before. Run test cases \u00b6 Suppose the test case file is named as quickstart-demo-rev-0.yml and is located in examples folder, then we can run it in this way. ate examples/demo-rev-0.yml Running tests... ---------------------------------------------------------------------- get token ... INFO:root: Start to POST http://127.0.0.1:5000/api/get-token INFO:root: status_code: 200, response_time: 48 ms, response_length: 46 bytes OK (0.049669)s create user which does not exist ... INFO:root: Start to POST http://127.0.0.1:5000/api/users/1000 ERROR:root: Failed to POST http://127.0.0.1:5000/api/users/1000! exception msg: 403 Client Error: FORBIDDEN for url: http://127.0.0.1:5000/api/users/1000 ERROR (0.006471)s ---------------------------------------------------------------------- Ran 2 tests in 0.056s FAILED (Errors=1) Oops! The second test case failed with 403 status code. That is because we request with the same data as we captured in Charles Proxy , while the token is generated dynamically, thus the recorded data can not be be used twice directly. Optimize test case: correlation \u00b6 To fix this problem, we should correlate token field in the second API test case, which is also called correlation . - test : name : get token request : url : http://127.0.0.1:5000/api/get-token method : POST headers : user_agent : iOS/10.3 device_sn : 9TN6O2Bn1vzfybF os_platform : ios app_version : 2.8.6 json : sign : 19067cf712265eb5426db8d3664026c1ccea02b9 extract : - token : content.token validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 200 } - { \"check\" : \"content.token\" , \"comparator\" : \"len_eq\" , \"expect\" : 16 } - test : name : create user which does not exist request : url : http://127.0.0.1:5000/api/users/1000 method : POST headers : device_sn : 9TN6O2Bn1vzfybF token : $token json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } As you see, the token field is no longer hardcoded, instead it is extracted from the first API request with extract mechanism. In the meanwhile, it is assigned to token variable, which can be referenced by the subsequent API requests. Now we save the test cases to quickstart-demo-rev-1.yml and rerun it, and we will find that both API requests to be successful. Optimize test case: parameterization \u00b6 Let's look back to our test set quickstart-demo-rev-1.yml , and we can see the device_sn field is still hardcoded. This may be quite different from the actual scenarios. In actual scenarios, each user's device_sn is different, so we should parameterize the request parameters, which is also called parameterization . In the meanwhile, the sign field is calculated with other header fields, thus it may change significantly if any header field changes slightly. However, the test cases are only YAML documents, it is impossible to generate parameters dynamically in such text. Fortunately, we can combine Python scripts with YAML/JSON test cases in HttpRunner . To achieve this goal, we can utilize debugtalk.py plugin and variables mechanisms. To be specific, we can create a Python file ( examples/debugtalk.py ) and implement the related algorithm in it. The debugtalk.py file can not only be located beside YAML/JSON testcase file, but also can be in any upward recursive folder. Since we want debugtalk.py to be importable, we should put a __init__.py in its folder to make it as a Python module. import hashlib import hmac import random import string SECRET_KEY = \"DebugTalk\" def get_sign ( * args ): content = '' . join ( args ) . encode ( 'ascii' ) sign_key = SECRET_KEY . encode ( 'ascii' ) sign = hmac . new ( sign_key , content , hashlib . sha1 ) . hexdigest () return sign def gen_random_string ( str_len ): random_char_list = [] for _ in range ( str_len ): random_char = random . choice ( string . ascii_letters + string . digits ) random_char_list . append ( random_char ) random_string = '' . join ( random_char_list ) return random_string And then, we can revise our demo test case and reference the functions. Suppose the revised file named quickstart-demo-rev-2.yml . - test : name : get token variables : - user_agent : 'iOS/10.3' - device_sn : ${gen_random_string(15)} - os_platform : 'ios' - app_version : '2.8.6' request : url : http://127.0.0.1:5000/api/get-token method : POST headers : user_agent : $user_agent device_sn : $device_sn os_platform : $os_platform app_version : $app_version json : sign : ${get_sign($user_agent, $device_sn, $os_platform, $app_version)} extract : - token : content.token validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 200 } - { \"check\" : \"content.token\" , \"comparator\" : \"len_eq\" , \"expect\" : 16 } - test : name : create user which does not exist request : url : http://127.0.0.1:5000/api/users/1000 method : POST headers : device_sn : $device_sn token : $token json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } In this revised test case, variable reference and function invoke mechanisms are both used. To make fields like device_sn can be used more than once, we bind values to variables in variables block. When we bind variables, we can not only bind exact value to a variable name, but also can call a function and bind the evaluated value to it. When we want to reference a variable in the test case, we can do this with a escape character $ . For example, $user_agent will not be taken as a normal string, and HttpRunner will consider it as a variable named user_agent , search and return its binding value. When we want to reference a function, we shall use another escape character ${} . Any content in ${} will be considered as function calling, so we should guarantee that we call functions in the right way. At the same time, variables can also be referenced as parameters of function. Optimize test case: overall config block \u00b6 There is still one issue unsolved. The device_sn field is defined in the first API test case, thus it may be impossible to reference it in other test cases. Context separation is a well-designed mechanism, and we should obey this good practice. To handle this case, overall config block is supported in HttpRunner . If we define variables or import functions in config block, these variables and functions will become global and can be referenced in the whole test set. # examples/quickstart-demo-rev-3.yml - config : name : \"smoketest for CRUD users.\" variables : - device_sn : ${gen_random_string(15)} request : base_url : http://127.0.0.1:5000 headers : device_sn : $device_sn - test : name : get token variables : - user_agent : 'iOS/10.3' - os_platform : 'ios' - app_version : '2.8.6' request : url : /api/get-token method : POST headers : user_agent : $user_agent os_platform : $os_platform app_version : $app_version json : sign : ${get_sign($user_agent, $device_sn, $os_platform, $app_version)} extract : - token : content.token validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 200 } - { \"check\" : \"content.token\" , \"comparator\" : \"len_eq\" , \"expect\" : 16 } - test : name : create user which does not exist request : url : /api/users/1000 method : POST headers : token : $token json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } As you see, we define variables in config block. Also, we can set base_url in config block, thereby we can specify relative path in each API request url. Besides, we can also set common fields in config request , such as device_sn in headers. Until now, the test cases are finished and each detail is handled properly. Run test cases and generate report \u00b6 Finally, let's run test set quickstart-demo-rev-3.yml once more. $ ate examples/quickstart-demo-rev-4.yml Running tests... ---------------------------------------------------------------------- get token ... INFO:root: Start to POST http://127.0.0.1:5000/api/get-token INFO:root: status_code: 200, response_time: 33 ms, response_length: 46 bytes OK (0.037027)s create user which does not exist ... INFO:root: Start to POST http://127.0.0.1:5000/api/users/1000 INFO:root: status_code: 201, response_time: 15 ms, response_length: 54 bytes OK (0.016414)s ---------------------------------------------------------------------- Ran 2 tests in 0.054s OK Generating HTML reports... Template is not specified, load default template instead. Reports generated: /Users/Leo/MyProjects/HttpRunner/reports/quickstart-demo-rev-0/2017-08-01-16-51-51.html Great! The test case runs successfully and generates a HTML test report. Further more \u00b6 This is just a starting point, see the advanced guide for the advanced features. templating data extraction and validation comparator","title":"Quick Start"},{"location":"quickstart/#quick-start","text":"First of all, remember HttpRunner is a simple yet powerful HTTP(S) testing framework. This document will help you to learn HttpRunner in 10 minutes.","title":"Quick Start"},{"location":"quickstart/#write-the-first-test-case","text":"Open your favorite text editor and you can write test cases like this. - test : name : get token request : url : http://127.0.0.1:5000/api/get-token method : POST headers : user_agent : iOS/10.3 device_sn : 9TN6O2Bn1vzfybF os_platform : ios app_version : 2.8.6 json : sign : 19067cf712265eb5426db8d3664026c1ccea02b9 - test : name : create user which does not exist request : url : http://127.0.0.1:5000/api/users/1000 method : POST headers : device_sn : 9TN6O2Bn1vzfybF token : F8prvGryC5beBr4g json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } As you see, each API request is described in a test block. And in the request field, it describes the detail of HTTP request, includes url, method, headers and data, which are in line with the captured traffic. You may wonder why we use the json field other than data . That's because the post data is in JSON format, when we use json to indicate the post data, we do not have to specify Content-Type to be application/json in request headers or dump data before request. Have you recalled some familiar scenes? Yes! That's what we did in requests.request ! Since HttpRunner takes full reuse of Requests , it inherits all powerful features of Requests , and we can handle HTTP request as the way we do before.","title":"Write the first test case"},{"location":"quickstart/#run-test-cases","text":"Suppose the test case file is named as quickstart-demo-rev-0.yml and is located in examples folder, then we can run it in this way. ate examples/demo-rev-0.yml Running tests... ---------------------------------------------------------------------- get token ... INFO:root: Start to POST http://127.0.0.1:5000/api/get-token INFO:root: status_code: 200, response_time: 48 ms, response_length: 46 bytes OK (0.049669)s create user which does not exist ... INFO:root: Start to POST http://127.0.0.1:5000/api/users/1000 ERROR:root: Failed to POST http://127.0.0.1:5000/api/users/1000! exception msg: 403 Client Error: FORBIDDEN for url: http://127.0.0.1:5000/api/users/1000 ERROR (0.006471)s ---------------------------------------------------------------------- Ran 2 tests in 0.056s FAILED (Errors=1) Oops! The second test case failed with 403 status code. That is because we request with the same data as we captured in Charles Proxy , while the token is generated dynamically, thus the recorded data can not be be used twice directly.","title":"Run test cases"},{"location":"quickstart/#optimize-test-case-correlation","text":"To fix this problem, we should correlate token field in the second API test case, which is also called correlation . - test : name : get token request : url : http://127.0.0.1:5000/api/get-token method : POST headers : user_agent : iOS/10.3 device_sn : 9TN6O2Bn1vzfybF os_platform : ios app_version : 2.8.6 json : sign : 19067cf712265eb5426db8d3664026c1ccea02b9 extract : - token : content.token validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 200 } - { \"check\" : \"content.token\" , \"comparator\" : \"len_eq\" , \"expect\" : 16 } - test : name : create user which does not exist request : url : http://127.0.0.1:5000/api/users/1000 method : POST headers : device_sn : 9TN6O2Bn1vzfybF token : $token json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } As you see, the token field is no longer hardcoded, instead it is extracted from the first API request with extract mechanism. In the meanwhile, it is assigned to token variable, which can be referenced by the subsequent API requests. Now we save the test cases to quickstart-demo-rev-1.yml and rerun it, and we will find that both API requests to be successful.","title":"Optimize test case: correlation"},{"location":"quickstart/#optimize-test-case-parameterization","text":"Let's look back to our test set quickstart-demo-rev-1.yml , and we can see the device_sn field is still hardcoded. This may be quite different from the actual scenarios. In actual scenarios, each user's device_sn is different, so we should parameterize the request parameters, which is also called parameterization . In the meanwhile, the sign field is calculated with other header fields, thus it may change significantly if any header field changes slightly. However, the test cases are only YAML documents, it is impossible to generate parameters dynamically in such text. Fortunately, we can combine Python scripts with YAML/JSON test cases in HttpRunner . To achieve this goal, we can utilize debugtalk.py plugin and variables mechanisms. To be specific, we can create a Python file ( examples/debugtalk.py ) and implement the related algorithm in it. The debugtalk.py file can not only be located beside YAML/JSON testcase file, but also can be in any upward recursive folder. Since we want debugtalk.py to be importable, we should put a __init__.py in its folder to make it as a Python module. import hashlib import hmac import random import string SECRET_KEY = \"DebugTalk\" def get_sign ( * args ): content = '' . join ( args ) . encode ( 'ascii' ) sign_key = SECRET_KEY . encode ( 'ascii' ) sign = hmac . new ( sign_key , content , hashlib . sha1 ) . hexdigest () return sign def gen_random_string ( str_len ): random_char_list = [] for _ in range ( str_len ): random_char = random . choice ( string . ascii_letters + string . digits ) random_char_list . append ( random_char ) random_string = '' . join ( random_char_list ) return random_string And then, we can revise our demo test case and reference the functions. Suppose the revised file named quickstart-demo-rev-2.yml . - test : name : get token variables : - user_agent : 'iOS/10.3' - device_sn : ${gen_random_string(15)} - os_platform : 'ios' - app_version : '2.8.6' request : url : http://127.0.0.1:5000/api/get-token method : POST headers : user_agent : $user_agent device_sn : $device_sn os_platform : $os_platform app_version : $app_version json : sign : ${get_sign($user_agent, $device_sn, $os_platform, $app_version)} extract : - token : content.token validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 200 } - { \"check\" : \"content.token\" , \"comparator\" : \"len_eq\" , \"expect\" : 16 } - test : name : create user which does not exist request : url : http://127.0.0.1:5000/api/users/1000 method : POST headers : device_sn : $device_sn token : $token json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } In this revised test case, variable reference and function invoke mechanisms are both used. To make fields like device_sn can be used more than once, we bind values to variables in variables block. When we bind variables, we can not only bind exact value to a variable name, but also can call a function and bind the evaluated value to it. When we want to reference a variable in the test case, we can do this with a escape character $ . For example, $user_agent will not be taken as a normal string, and HttpRunner will consider it as a variable named user_agent , search and return its binding value. When we want to reference a function, we shall use another escape character ${} . Any content in ${} will be considered as function calling, so we should guarantee that we call functions in the right way. At the same time, variables can also be referenced as parameters of function.","title":"Optimize test case: parameterization"},{"location":"quickstart/#optimize-test-case-overall-config-block","text":"There is still one issue unsolved. The device_sn field is defined in the first API test case, thus it may be impossible to reference it in other test cases. Context separation is a well-designed mechanism, and we should obey this good practice. To handle this case, overall config block is supported in HttpRunner . If we define variables or import functions in config block, these variables and functions will become global and can be referenced in the whole test set. # examples/quickstart-demo-rev-3.yml - config : name : \"smoketest for CRUD users.\" variables : - device_sn : ${gen_random_string(15)} request : base_url : http://127.0.0.1:5000 headers : device_sn : $device_sn - test : name : get token variables : - user_agent : 'iOS/10.3' - os_platform : 'ios' - app_version : '2.8.6' request : url : /api/get-token method : POST headers : user_agent : $user_agent os_platform : $os_platform app_version : $app_version json : sign : ${get_sign($user_agent, $device_sn, $os_platform, $app_version)} extract : - token : content.token validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 200 } - { \"check\" : \"content.token\" , \"comparator\" : \"len_eq\" , \"expect\" : 16 } - test : name : create user which does not exist request : url : /api/users/1000 method : POST headers : token : $token json : name : \"user1\" password : \"123456\" validate : - { \"check\" : \"status_code\" , \"comparator\" : \"eq\" , \"expect\" : 201 } - { \"check\" : \"content.success\" , \"comparator\" : \"eq\" , \"expect\" : true } As you see, we define variables in config block. Also, we can set base_url in config block, thereby we can specify relative path in each API request url. Besides, we can also set common fields in config request , such as device_sn in headers. Until now, the test cases are finished and each detail is handled properly.","title":"Optimize test case: overall config block"},{"location":"quickstart/#run-test-cases-and-generate-report","text":"Finally, let's run test set quickstart-demo-rev-3.yml once more. $ ate examples/quickstart-demo-rev-4.yml Running tests... ---------------------------------------------------------------------- get token ... INFO:root: Start to POST http://127.0.0.1:5000/api/get-token INFO:root: status_code: 200, response_time: 33 ms, response_length: 46 bytes OK (0.037027)s create user which does not exist ... INFO:root: Start to POST http://127.0.0.1:5000/api/users/1000 INFO:root: status_code: 201, response_time: 15 ms, response_length: 54 bytes OK (0.016414)s ---------------------------------------------------------------------- Ran 2 tests in 0.054s OK Generating HTML reports... Template is not specified, load default template instead. Reports generated: /Users/Leo/MyProjects/HttpRunner/reports/quickstart-demo-rev-0/2017-08-01-16-51-51.html Great! The test case runs successfully and generates a HTML test report.","title":"Run test cases and generate report"},{"location":"quickstart/#further-more","text":"This is just a starting point, see the advanced guide for the advanced features. templating data extraction and validation comparator","title":"Further more"},{"location":"sponsors/","text":"\u8d5e\u52a9\u5546 \u00b6 \u611f\u8c22\u5404\u4f4d\u5bf9 HttpRunner \u7684\u8d5e\u52a9\u652f\u6301\uff01 \u91d1\u724c\u8d5e\u52a9\u5546\uff08Gold Sponsor\uff09 \u00b6 \u970d\u683c\u6c83\u5179\u6d4b\u8bd5\u5b66\u9662 \u662f\u4e1a\u754c\u9886\u5148\u7684\u6d4b\u8bd5\u5f00\u53d1\u6280\u672f\u9ad8\u7aef\u6559\u80b2\u54c1\u724c\uff0c\u96b6\u5c5e\u4e8e\u6d4b\u5427\uff08\u5317\u4eac\uff09\u79d1\u6280\u6709\u9650\u516c\u53f8\u3002\u5b66\u9662\u8bfe\u7a0b\u5747\u7531 BAT \u4e00\u7ebf\u6d4b\u8bd5\u5927\u5496\u6267\u6559\uff0c\u63d0\u4f9b\u5b9e\u6218\u9a71\u52a8\u7684\u63a5\u53e3\u81ea\u52a8\u5316\u6d4b\u8bd5\u3001\u79fb\u52a8\u81ea\u52a8\u5316\u6d4b\u8bd5\u3001\u6027\u80fd\u6d4b\u8bd5\u3001\u6301\u7eed\u96c6\u6210\u4e0e DevOps \u7b49\u6280\u672f\u57f9\u8bad\uff0c\u4ee5\u53ca\u6d4b\u8bd5\u5f00\u53d1\u4f18\u79c0\u4eba\u624d\u5185\u63a8\u670d\u52a1\u3002 \u70b9\u51fb\u5b66\u4e60! \u970d\u683c\u6c83\u5179\u6d4b\u8bd5\u5b66\u9662 \u662f HttpRunner \u7684\u9996\u5bb6\u91d1\u724c\u8d5e\u52a9\u5546\u3002 \u5f00\u6e90\u670d\u52a1\u8d5e\u52a9\u5546\uff08Open Source Sponsor\uff09 \u00b6 HttpRunner is in Sentry Sponsored plan. \u6210\u4e3a\u8d5e\u52a9\u5546 \u00b6 \u5982\u679c\u4f60\u6240\u5728\u7684\u516c\u53f8\u6216\u4e2a\u4eba\u4e5f\u60f3\u5bf9 HttpRunner \u8fdb\u884c\u8d5e\u52a9\uff0c\u53ef\u53c2\u8003\u5982\u4e0b\u65b9\u6848\uff0c\u5177\u4f53\u53ef\u8054\u7cfb \u9879\u76ee\u4f5c\u8005 \u3002 \u7b49\u7ea7 \u91d1\u724c\u8d5e\u52a9\u5546 \uff08Gold Sponsor\uff09 \u94f6\u724c\u8d5e\u52a9\u5546 \uff08Silver Sponsor\uff09 \u4e2a\u4eba\u8d5e\u8d4f \u91d1\u989d \uffe510000/\u5e74 \uffe55000/\u5e74 \u4efb\u610f \u6743\u76ca \u516c\u53f8 logo\uff08\u5927\uff09\u548c\u94fe\u63a5\u5c55\u793a\u5728 README.md 150 \u5b57\u7684\u5ba3\u4f20\u6587\u6848 \u516c\u53f8 logo\uff08\u4e2d\uff09\u548c\u94fe\u63a5\u5c55\u793a\u5728 README.md 50 \u5b57\u7684\u5ba3\u4f20\u6587\u6848 \u4e2a\u4eba ID \u548c\u94fe\u63a5\u5c55\u793a\u5728 sponsors.md","title":"Sponsors"},{"location":"sponsors/#_1","text":"\u611f\u8c22\u5404\u4f4d\u5bf9 HttpRunner \u7684\u8d5e\u52a9\u652f\u6301\uff01","title":"\u8d5e\u52a9\u5546"},{"location":"sponsors/#gold-sponsor","text":"\u970d\u683c\u6c83\u5179\u6d4b\u8bd5\u5b66\u9662 \u662f\u4e1a\u754c\u9886\u5148\u7684\u6d4b\u8bd5\u5f00\u53d1\u6280\u672f\u9ad8\u7aef\u6559\u80b2\u54c1\u724c\uff0c\u96b6\u5c5e\u4e8e\u6d4b\u5427\uff08\u5317\u4eac\uff09\u79d1\u6280\u6709\u9650\u516c\u53f8\u3002\u5b66\u9662\u8bfe\u7a0b\u5747\u7531 BAT \u4e00\u7ebf\u6d4b\u8bd5\u5927\u5496\u6267\u6559\uff0c\u63d0\u4f9b\u5b9e\u6218\u9a71\u52a8\u7684\u63a5\u53e3\u81ea\u52a8\u5316\u6d4b\u8bd5\u3001\u79fb\u52a8\u81ea\u52a8\u5316\u6d4b\u8bd5\u3001\u6027\u80fd\u6d4b\u8bd5\u3001\u6301\u7eed\u96c6\u6210\u4e0e DevOps \u7b49\u6280\u672f\u57f9\u8bad\uff0c\u4ee5\u53ca\u6d4b\u8bd5\u5f00\u53d1\u4f18\u79c0\u4eba\u624d\u5185\u63a8\u670d\u52a1\u3002 \u70b9\u51fb\u5b66\u4e60! \u970d\u683c\u6c83\u5179\u6d4b\u8bd5\u5b66\u9662 \u662f HttpRunner \u7684\u9996\u5bb6\u91d1\u724c\u8d5e\u52a9\u5546\u3002","title":"\u91d1\u724c\u8d5e\u52a9\u5546\uff08Gold Sponsor\uff09"},{"location":"sponsors/#open-source-sponsor","text":"HttpRunner is in Sentry Sponsored plan.","title":"\u5f00\u6e90\u670d\u52a1\u8d5e\u52a9\u5546\uff08Open Source Sponsor\uff09"},{"location":"sponsors/#_2","text":"\u5982\u679c\u4f60\u6240\u5728\u7684\u516c\u53f8\u6216\u4e2a\u4eba\u4e5f\u60f3\u5bf9 HttpRunner \u8fdb\u884c\u8d5e\u52a9\uff0c\u53ef\u53c2\u8003\u5982\u4e0b\u65b9\u6848\uff0c\u5177\u4f53\u53ef\u8054\u7cfb \u9879\u76ee\u4f5c\u8005 \u3002 \u7b49\u7ea7 \u91d1\u724c\u8d5e\u52a9\u5546 \uff08Gold Sponsor\uff09 \u94f6\u724c\u8d5e\u52a9\u5546 \uff08Silver Sponsor\uff09 \u4e2a\u4eba\u8d5e\u8d4f \u91d1\u989d \uffe510000/\u5e74 \uffe55000/\u5e74 \u4efb\u610f \u6743\u76ca \u516c\u53f8 logo\uff08\u5927\uff09\u548c\u94fe\u63a5\u5c55\u793a\u5728 README.md 150 \u5b57\u7684\u5ba3\u4f20\u6587\u6848 \u516c\u53f8 logo\uff08\u4e2d\uff09\u548c\u94fe\u63a5\u5c55\u793a\u5728 README.md 50 \u5b57\u7684\u5ba3\u4f20\u6587\u6848 \u4e2a\u4eba ID \u548c\u94fe\u63a5\u5c55\u793a\u5728 sponsors.md","title":"\u6210\u4e3a\u8d5e\u52a9\u5546"},{"location":"user/gen_tests/","text":"Record & Generate testcase \u00b6 capture HTTP request and response \u00b6 Before we write testcases, we should know the details of the API. It is a good choice to use a web debugging proxy tool like Charles Proxy to capture the HTTP traffic. For example, the image below illustrates post form data to postman-echo.com . export sessions to HAR file \u00b6 Then we can select captured request & response and export sessions to HTTP archive (.har) file. generate testcase with har2case \u00b6 When you get HAR file, you can use builtin command har2case to convert it to HttpRunner testcase. help \u00b6 $ har2case -h usage: har2case har2case [-h] [-2y] [-2j] [--filter FILTER] [--exclude EXCLUDE] [har_source_file] positional arguments: har_source_file Specify HAR source file optional arguments: -h, --help show this help message and exit -2y, --to-yml, --to-yaml Convert to YAML format, if not specified, convert to pytest format by default. -2j, --to-json Convert to JSON format, if not specified, convert to pytest format by default. --filter FILTER Specify filter keyword, only url include filter string will be converted. --exclude EXCLUDE Specify exclude keyword, url that includes exclude string will be ignored, multiple keywords can be joined with '|' generate testcase (pytest) \u00b6 Since HttpRunner 3.0.7 , har2case will convert HAR file to pytest by default, and it is strongly recommended to write and maintain testcases in pytest format instead of former YAML/JSON format. $ har2case har/postman-echo-post-form.har 2020-06-15 15:08:01.187 | INFO | httprunner.ext.har2case.core:gen_testcase:332 - Start to generate testcase from har/postman-echo-post-form.har 2020-06-15 15:08:01.187 | INFO | httprunner.ext.har2case.core:_make_testcase:323 - Extract info from HAR file and prepare for testcase. 2020-06-15 15:08:01.191 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/Desktop/demo/.env 2020-06-15 15:08:01.191 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 15:08:01.191 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 15:08:01.193 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/Desktop/demo/har/postman-echo-post-form.har 2020-06-15 15:08:01.193 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py 2020-06-15 15:08:01.194 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... reformatted /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py All done! \u2728 \ud83c\udf70 \u2728 1 file reformatted. 2020-06-15 15:08:01.469 | INFO | httprunner.ext.har2case.core:gen_testcase:353 - generated testcase: /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py The generated pytest file is a standard Python file shown as below. # NOTE: Generated By HttpRunner v3.0.12 # FROM: har/postman-echo-post-form.har from httprunner import HttpRunner , Config , Step , RunRequest , RunTestCase class TestCasePostmanEchoPostForm ( HttpRunner ): config = Config ( \"testcase description\" ) . verify ( False ) teststeps = [ Step ( RunRequest ( \"/get\" ) . get ( \"https://postman-echo.com/get\" ) . with_params ( ** { \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" }) . with_headers ( ** { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"6606343b-10e5-4165-a89f-6c301b762ce0\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" , } ) . with_cookies ( ** { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" } ) . validate () . assert_equal ( \"status_code\" , 200 ) . assert_equal ( 'headers.\"Content-Type\"' , \"application/json; charset=utf-8\" ) . assert_equal ( \"body.url\" , \"https://postman-echo.com/get?foo1=bar1&foo2=bar2\" ) ), Step ( RunRequest ( \"/post\" ) . post ( \"https://postman-echo.com/post\" ) . with_headers ( ** { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"3e408e9d-25ca-4b31-b04b-7f4898a8cd49\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Content-Type\" : \"application/x-www-form-urlencoded\" , \"Content-Length\" : \"19\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" , } ) . with_cookies ( ** { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" } ) . with_data ({ \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" }) . validate () . assert_equal ( \"status_code\" , 200 ) . assert_equal ( 'headers.\"Content-Type\"' , \"application/json; charset=utf-8\" ) . assert_equal ( \"body.data\" , \"\" ) . assert_equal ( \"body.url\" , \"https://postman-echo.com/post\" ) ), ] if __name__ == \"__main__\" : TestCasePostmanEchoPostForm () . test_start () And it can be run with hrun command or the native pytest command. In fact, hrun is only a wrapper of pytest , thus the effect is basically the same. $ hrun har/postman_echo_post_form_test.py 2020-06-15 15:23:03.502 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/Desktop/demo/.env 2020-06-15 15:23:03.502 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 15:23:03.502 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 15:23:03.503 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... All done! \u2728 \ud83c\udf70 \u2728 1 file left unchanged. 2020-06-15 15:23:03.662 | INFO | httprunner.cli:main_run:56 - start to run tests with pytest. HttpRunner version: 3.0.12 ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/Desktop/demo plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 1 item har/postman_echo_post_form_test.py . [100%] ======================================================================= 1 passed in 2.60s ======================================================================= $ pytest har/postman_echo_post_form_test.py ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/Desktop/demo plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 1 item har/postman_echo_post_form_test.py . [100%] ================================================================= 1 passed, 1 warning in 4.11s ================================================================== generate testcase (YAML/JSON) \u00b6 Of course, you can also generate former YAML/JSON testcase format. Just add -2y/--to-yml or -2j/--to-json argument to har2case . $ har2case har/postman-echo-post-form.har -2j 2020-06-15 15:32:02.955 | INFO | httprunner.ext.har2case.core:gen_testcase:332 - Start to generate testcase from har/postman-echo-post-form.har 2020-06-15 15:32:02.955 | INFO | httprunner.ext.har2case.core:_make_testcase:323 - Extract info from HAR file and prepare for testcase. 2020-06-15 15:32:02.958 | INFO | httprunner.ext.har2case.utils:dump_json:122 - dump testcase to JSON format. 2020-06-15 15:32:02.959 | INFO | httprunner.ext.har2case.utils:dump_json:131 - Generate JSON testcase successfully: har/postman-echo-post-form.json 2020-06-15 15:32:02.959 | INFO | httprunner.ext.har2case.core:gen_testcase:353 - generated testcase: har/postman-echo-post-form.json { \"config\" : { \"name\" : \"testcase description\" , \"variables\" : {}, \"verify\" : false }, \"teststeps\" : [ { \"name\" : \"/get\" , \"request\" : { \"url\" : \"https://postman-echo.com/get\" , \"params\" : { \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" }, \"method\" : \"GET\" , \"cookies\" : { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" }, \"headers\" : { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"6606343b-10e5-4165-a89f-6c301b762ce0\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" } }, \"validate\" : [ { \"eq\" : [ \"status_code\" , 200 ] }, { \"eq\" : [ \"headers.Content-Type\" , \"application/json; charset=utf-8\" ] }, { \"eq\" : [ \"body.url\" , \"https://postman-echo.com/get?foo1=bar1&foo2=bar2\" ] } ] }, { \"name\" : \"/post\" , \"request\" : { \"url\" : \"https://postman-echo.com/post\" , \"method\" : \"POST\" , \"cookies\" : { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" }, \"headers\" : { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"3e408e9d-25ca-4b31-b04b-7f4898a8cd49\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Content-Type\" : \"application/x-www-form-urlencoded\" , \"Content-Length\" : \"19\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" }, \"data\" : { \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" } }, \"validate\" : [ { \"eq\" : [ \"status_code\" , 200 ] }, { \"eq\" : [ \"headers.Content-Type\" , \"application/json; charset=utf-8\" ] }, { \"eq\" : [ \"body.data\" , \"\" ] }, { \"eq\" : [ \"body.url\" , \"https://postman-echo.com/post\" ] } ] } ] } The YAML/JSON testcase has the same info with pytest testcase, and you can run YAML/JSON testcase with hrun command. $ hrun har/postman-echo-post-form.json 2020-06-15 15:37:15.621 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/Desktop/demo/.env 2020-06-15 15:37:15.622 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 15:37:15.622 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 15:37:15.623 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/Desktop/demo/har/postman-echo-post-form.json 2020-06-15 15:37:15.625 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py 2020-06-15 15:37:15.625 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... reformatted /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py All done! \u2728 \ud83c\udf70 \u2728 1 file reformatted, 1 file left unchanged. 2020-06-15 15:37:15.962 | INFO | httprunner.cli:main_run:56 - start to run tests with pytest. HttpRunner version: 3.0.12 ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/Desktop/demo plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 1 item har/postman_echo_post_form_test.py . [100%] ======================================================================= 1 passed in 2.03s =======================================================================","title":"Record & Generate testcase"},{"location":"user/gen_tests/#record-generate-testcase","text":"","title":"Record & Generate testcase"},{"location":"user/gen_tests/#capture-http-request-and-response","text":"Before we write testcases, we should know the details of the API. It is a good choice to use a web debugging proxy tool like Charles Proxy to capture the HTTP traffic. For example, the image below illustrates post form data to postman-echo.com .","title":"capture HTTP request and response"},{"location":"user/gen_tests/#export-sessions-to-har-file","text":"Then we can select captured request & response and export sessions to HTTP archive (.har) file.","title":"export sessions to HAR file"},{"location":"user/gen_tests/#generate-testcase-with-har2case","text":"When you get HAR file, you can use builtin command har2case to convert it to HttpRunner testcase.","title":"generate testcase with har2case"},{"location":"user/gen_tests/#help","text":"$ har2case -h usage: har2case har2case [-h] [-2y] [-2j] [--filter FILTER] [--exclude EXCLUDE] [har_source_file] positional arguments: har_source_file Specify HAR source file optional arguments: -h, --help show this help message and exit -2y, --to-yml, --to-yaml Convert to YAML format, if not specified, convert to pytest format by default. -2j, --to-json Convert to JSON format, if not specified, convert to pytest format by default. --filter FILTER Specify filter keyword, only url include filter string will be converted. --exclude EXCLUDE Specify exclude keyword, url that includes exclude string will be ignored, multiple keywords can be joined with '|'","title":"help"},{"location":"user/gen_tests/#generate-testcase-pytest","text":"Since HttpRunner 3.0.7 , har2case will convert HAR file to pytest by default, and it is strongly recommended to write and maintain testcases in pytest format instead of former YAML/JSON format. $ har2case har/postman-echo-post-form.har 2020-06-15 15:08:01.187 | INFO | httprunner.ext.har2case.core:gen_testcase:332 - Start to generate testcase from har/postman-echo-post-form.har 2020-06-15 15:08:01.187 | INFO | httprunner.ext.har2case.core:_make_testcase:323 - Extract info from HAR file and prepare for testcase. 2020-06-15 15:08:01.191 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/Desktop/demo/.env 2020-06-15 15:08:01.191 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 15:08:01.191 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 15:08:01.193 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/Desktop/demo/har/postman-echo-post-form.har 2020-06-15 15:08:01.193 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py 2020-06-15 15:08:01.194 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... reformatted /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py All done! \u2728 \ud83c\udf70 \u2728 1 file reformatted. 2020-06-15 15:08:01.469 | INFO | httprunner.ext.har2case.core:gen_testcase:353 - generated testcase: /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py The generated pytest file is a standard Python file shown as below. # NOTE: Generated By HttpRunner v3.0.12 # FROM: har/postman-echo-post-form.har from httprunner import HttpRunner , Config , Step , RunRequest , RunTestCase class TestCasePostmanEchoPostForm ( HttpRunner ): config = Config ( \"testcase description\" ) . verify ( False ) teststeps = [ Step ( RunRequest ( \"/get\" ) . get ( \"https://postman-echo.com/get\" ) . with_params ( ** { \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" }) . with_headers ( ** { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"6606343b-10e5-4165-a89f-6c301b762ce0\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" , } ) . with_cookies ( ** { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" } ) . validate () . assert_equal ( \"status_code\" , 200 ) . assert_equal ( 'headers.\"Content-Type\"' , \"application/json; charset=utf-8\" ) . assert_equal ( \"body.url\" , \"https://postman-echo.com/get?foo1=bar1&foo2=bar2\" ) ), Step ( RunRequest ( \"/post\" ) . post ( \"https://postman-echo.com/post\" ) . with_headers ( ** { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"3e408e9d-25ca-4b31-b04b-7f4898a8cd49\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Content-Type\" : \"application/x-www-form-urlencoded\" , \"Content-Length\" : \"19\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" , } ) . with_cookies ( ** { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2 %2F rD9cxUhQemIsm78nifYZYHpPCU\" } ) . with_data ({ \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" }) . validate () . assert_equal ( \"status_code\" , 200 ) . assert_equal ( 'headers.\"Content-Type\"' , \"application/json; charset=utf-8\" ) . assert_equal ( \"body.data\" , \"\" ) . assert_equal ( \"body.url\" , \"https://postman-echo.com/post\" ) ), ] if __name__ == \"__main__\" : TestCasePostmanEchoPostForm () . test_start () And it can be run with hrun command or the native pytest command. In fact, hrun is only a wrapper of pytest , thus the effect is basically the same. $ hrun har/postman_echo_post_form_test.py 2020-06-15 15:23:03.502 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/Desktop/demo/.env 2020-06-15 15:23:03.502 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 15:23:03.502 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 15:23:03.503 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... All done! \u2728 \ud83c\udf70 \u2728 1 file left unchanged. 2020-06-15 15:23:03.662 | INFO | httprunner.cli:main_run:56 - start to run tests with pytest. HttpRunner version: 3.0.12 ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/Desktop/demo plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 1 item har/postman_echo_post_form_test.py . [100%] ======================================================================= 1 passed in 2.60s ======================================================================= $ pytest har/postman_echo_post_form_test.py ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/Desktop/demo plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 1 item har/postman_echo_post_form_test.py . [100%] ================================================================= 1 passed, 1 warning in 4.11s ==================================================================","title":"generate testcase (pytest)"},{"location":"user/gen_tests/#generate-testcase-yamljson","text":"Of course, you can also generate former YAML/JSON testcase format. Just add -2y/--to-yml or -2j/--to-json argument to har2case . $ har2case har/postman-echo-post-form.har -2j 2020-06-15 15:32:02.955 | INFO | httprunner.ext.har2case.core:gen_testcase:332 - Start to generate testcase from har/postman-echo-post-form.har 2020-06-15 15:32:02.955 | INFO | httprunner.ext.har2case.core:_make_testcase:323 - Extract info from HAR file and prepare for testcase. 2020-06-15 15:32:02.958 | INFO | httprunner.ext.har2case.utils:dump_json:122 - dump testcase to JSON format. 2020-06-15 15:32:02.959 | INFO | httprunner.ext.har2case.utils:dump_json:131 - Generate JSON testcase successfully: har/postman-echo-post-form.json 2020-06-15 15:32:02.959 | INFO | httprunner.ext.har2case.core:gen_testcase:353 - generated testcase: har/postman-echo-post-form.json { \"config\" : { \"name\" : \"testcase description\" , \"variables\" : {}, \"verify\" : false }, \"teststeps\" : [ { \"name\" : \"/get\" , \"request\" : { \"url\" : \"https://postman-echo.com/get\" , \"params\" : { \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" }, \"method\" : \"GET\" , \"cookies\" : { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" }, \"headers\" : { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"6606343b-10e5-4165-a89f-6c301b762ce0\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" } }, \"validate\" : [ { \"eq\" : [ \"status_code\" , 200 ] }, { \"eq\" : [ \"headers.Content-Type\" , \"application/json; charset=utf-8\" ] }, { \"eq\" : [ \"body.url\" , \"https://postman-echo.com/get?foo1=bar1&foo2=bar2\" ] } ] }, { \"name\" : \"/post\" , \"request\" : { \"url\" : \"https://postman-echo.com/post\" , \"method\" : \"POST\" , \"cookies\" : { \"sails.sid\" : \"s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" }, \"headers\" : { \"User-Agent\" : \"PostmanRuntime/7.24.1\" , \"Accept\" : \"*/*\" , \"Cache-Control\" : \"no-cache\" , \"Postman-Token\" : \"3e408e9d-25ca-4b31-b04b-7f4898a8cd49\" , \"Host\" : \"postman-echo.com\" , \"Accept-Encoding\" : \"gzip, deflate, br\" , \"Connection\" : \"keep-alive\" , \"Content-Type\" : \"application/x-www-form-urlencoded\" , \"Content-Length\" : \"19\" , \"Cookie\" : \"sails.sid=s%3AQG_EVeNRw8k1xxZ6v_SG401VTpmJDSRu.fTAGx3JnZUT7S0c2%2FrD9cxUhQemIsm78nifYZYHpPCU\" }, \"data\" : { \"foo1\" : \"bar1\" , \"foo2\" : \"bar2\" } }, \"validate\" : [ { \"eq\" : [ \"status_code\" , 200 ] }, { \"eq\" : [ \"headers.Content-Type\" , \"application/json; charset=utf-8\" ] }, { \"eq\" : [ \"body.data\" , \"\" ] }, { \"eq\" : [ \"body.url\" , \"https://postman-echo.com/post\" ] } ] } ] } The YAML/JSON testcase has the same info with pytest testcase, and you can run YAML/JSON testcase with hrun command. $ hrun har/postman-echo-post-form.json 2020-06-15 15:37:15.621 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/Desktop/demo/.env 2020-06-15 15:37:15.622 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 15:37:15.622 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 15:37:15.623 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/Desktop/demo/har/postman-echo-post-form.json 2020-06-15 15:37:15.625 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py 2020-06-15 15:37:15.625 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... reformatted /Users/debugtalk/Desktop/demo/har/postman_echo_post_form_test.py All done! \u2728 \ud83c\udf70 \u2728 1 file reformatted, 1 file left unchanged. 2020-06-15 15:37:15.962 | INFO | httprunner.cli:main_run:56 - start to run tests with pytest. HttpRunner version: 3.0.12 ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/Desktop/demo plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 1 item har/postman_echo_post_form_test.py . [100%] ======================================================================= 1 passed in 2.03s =======================================================================","title":"generate testcase (YAML/JSON)"},{"location":"user/scaffold/","text":"Scaffold \u00b6 If you want to create a new project, you can use the scaffold to startup quickly. help \u00b6 $ httprunner startproject -h usage: httprunner startproject [-h] [project_name] positional arguments: project_name Specify new project name. optional arguments: -h, --help show this help message and exit create new project \u00b6 The only argument you need to specify is the project name. $ httprunner startproject demo 2020-06-15 11:53:25.498 | INFO | httprunner.scaffold:create_scaffold:37 - Create new project: demo Project Root Dir: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo created folder: demo created folder: demo/har created folder: demo/testcases created folder: demo/reports created file: demo/testcases/demo_testcase_request.yml created file: demo/testcases/demo_testcase_ref.yml created file: demo/debugtalk.py created file: demo/.env created file: demo/.gitignore $ tree demo -a demo \u251c\u2500\u2500 .env \u251c\u2500\u2500 .gitignore \u251c\u2500\u2500 debugtalk.py \u251c\u2500\u2500 har \u251c\u2500\u2500 reports \u2514\u2500\u2500 testcases \u251c\u2500\u2500 demo_testcase_ref.yml \u2514\u2500\u2500 demo_testcase_request.yml 3 directories, 5 files If you specify a project name that already exists, you will get a warning. $ httprunner startproject demo 2020-06-15 11:55:03.192 | WARNING | httprunner.scaffold:create_scaffold:32 - Project demo exists, please specify a new project name. $ tree demo -a demo \u251c\u2500\u2500 .env \u251c\u2500\u2500 .gitignore \u251c\u2500\u2500 debugtalk.py \u251c\u2500\u2500 har \u251c\u2500\u2500 reports \u2514\u2500\u2500 testcases \u251c\u2500\u2500 demo_testcase_ref.yml \u2514\u2500\u2500 demo_testcase_request.yml 3 directories, 5 files run scaffold project \u00b6 The scaffold project has several valid testcases, so you can run tests without any edit. $ hrun demo 2020-06-15 11:57:15.883 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/.env 2020-06-15 11:57:15.883 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 11:57:15.884 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 11:57:15.885 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_ref.yml 2020-06-15 11:57:15.898 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request.yml 2020-06-15 11:57:15.899 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request_test.py 2020-06-15 11:57:15.900 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_ref_test.py 2020-06-15 11:57:15.911 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request.yml 2020-06-15 11:57:15.912 | INFO | httprunner.make:__ensure_project_meta_files:128 - copy .env to /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/_env 2020-06-15 11:57:15.912 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... reformatted /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_ref_test.py reformatted /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request_test.py All done! \u2728 \ud83c\udf70 \u2728 2 files reformatted, 1 file left unchanged. 2020-06-15 11:57:16.299 | INFO | httprunner.cli:main_run:56 - start to run tests with pytest. HttpRunner version: 3.0.12 ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 2 items demo/testcases/demo_testcase_request_test.py . [ 50%] demo/testcases/demo_testcase_ref_test.py . [100%] ======================================================================= 2 passed in 6.87s =======================================================================","title":"Scaffold"},{"location":"user/scaffold/#scaffold","text":"If you want to create a new project, you can use the scaffold to startup quickly.","title":"Scaffold"},{"location":"user/scaffold/#help","text":"$ httprunner startproject -h usage: httprunner startproject [-h] [project_name] positional arguments: project_name Specify new project name. optional arguments: -h, --help show this help message and exit","title":"help"},{"location":"user/scaffold/#create-new-project","text":"The only argument you need to specify is the project name. $ httprunner startproject demo 2020-06-15 11:53:25.498 | INFO | httprunner.scaffold:create_scaffold:37 - Create new project: demo Project Root Dir: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo created folder: demo created folder: demo/har created folder: demo/testcases created folder: demo/reports created file: demo/testcases/demo_testcase_request.yml created file: demo/testcases/demo_testcase_ref.yml created file: demo/debugtalk.py created file: demo/.env created file: demo/.gitignore $ tree demo -a demo \u251c\u2500\u2500 .env \u251c\u2500\u2500 .gitignore \u251c\u2500\u2500 debugtalk.py \u251c\u2500\u2500 har \u251c\u2500\u2500 reports \u2514\u2500\u2500 testcases \u251c\u2500\u2500 demo_testcase_ref.yml \u2514\u2500\u2500 demo_testcase_request.yml 3 directories, 5 files If you specify a project name that already exists, you will get a warning. $ httprunner startproject demo 2020-06-15 11:55:03.192 | WARNING | httprunner.scaffold:create_scaffold:32 - Project demo exists, please specify a new project name. $ tree demo -a demo \u251c\u2500\u2500 .env \u251c\u2500\u2500 .gitignore \u251c\u2500\u2500 debugtalk.py \u251c\u2500\u2500 har \u251c\u2500\u2500 reports \u2514\u2500\u2500 testcases \u251c\u2500\u2500 demo_testcase_ref.yml \u2514\u2500\u2500 demo_testcase_request.yml 3 directories, 5 files","title":"create new project"},{"location":"user/scaffold/#run-scaffold-project","text":"The scaffold project has several valid testcases, so you can run tests without any edit. $ hrun demo 2020-06-15 11:57:15.883 | INFO | httprunner.loader:load_dot_env_file:130 - Loading environment variables from /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/.env 2020-06-15 11:57:15.883 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: USERNAME 2020-06-15 11:57:15.884 | DEBUG | httprunner.utils:set_os_environ:32 - Set OS environment variable: PASSWORD 2020-06-15 11:57:15.885 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_ref.yml 2020-06-15 11:57:15.898 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request.yml 2020-06-15 11:57:15.899 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request_test.py 2020-06-15 11:57:15.900 | INFO | httprunner.make:make_testcase:383 - generated testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_ref_test.py 2020-06-15 11:57:15.911 | INFO | httprunner.make:make_testcase:310 - start to make testcase: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request.yml 2020-06-15 11:57:15.912 | INFO | httprunner.make:__ensure_project_meta_files:128 - copy .env to /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/_env 2020-06-15 11:57:15.912 | INFO | httprunner.make:format_pytest_with_black:147 - format pytest cases with black ... reformatted /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_ref_test.py reformatted /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/demo/testcases/demo_testcase_request_test.py All done! \u2728 \ud83c\udf70 \u2728 2 files reformatted, 1 file left unchanged. 2020-06-15 11:57:16.299 | INFO | httprunner.cli:main_run:56 - start to run tests with pytest. HttpRunner version: 3.0.12 ====================================================================== test session starts ====================================================================== platform darwin -- Python 3.7.5, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 rootdir: /Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner plugins: metadata-1.9.0, allure-pytest-2.8.16, html-2.1.1 collected 2 items demo/testcases/demo_testcase_request_test.py . [ 50%] demo/testcases/demo_testcase_ref_test.py . [100%] ======================================================================= 2 passed in 6.87s =======================================================================","title":"run scaffold project"}]} \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index 4a02e452d243cfd357fe290c088da7c23b385bb7..2cfe93df00092d2198a32ac3aa3913f273f6ba4a 100644 GIT binary patch delta 14 VcmX@cc#M%vzMF$XQ+p!Y0RSFN1Nr~} delta 14 VcmX@cc#M%vzMF&Nz2-!=0{|i;1ik赞助商

感谢各位对 HttpRunner 的赞助支持!

金牌赞助商(Gold Sponsor)

-

霍格沃兹测试学院

+

霍格沃兹测试学院

-

霍格沃兹测试学院 是由测吧(北京)科技有限公司与知名软件测试社区 TesterHome 合作的高端教育品牌。由 BAT 一线测试大咖执教,提供实战驱动的接口自动化测试、移动自动化测试、性能测试、持续集成与 DevOps 等技术培训,以及测试开发优秀人才内推服务。点击学习!

+

霍格沃兹测试学院 是业界领先的测试开发技术高端教育品牌,隶属于测吧(北京)科技有限公司。学院课程均由 BAT 一线测试大咖执教,提供实战驱动的接口自动化测试、移动自动化测试、性能测试、持续集成与 DevOps 等技术培训,以及测试开发优秀人才内推服务。点击学习!

-

霍格沃兹测试学院是 HttpRunner 的首家金牌赞助商。

+

霍格沃兹测试学院 是 HttpRunner 的首家金牌赞助商。

开源服务赞助商(Open Source Sponsor)

Sentry

HttpRunner is in Sentry Sponsored plan.