Skip to content

Commit

Permalink
feature: #1146 add error retry support
Browse files Browse the repository at this point in the history
  • Loading branch information
zhengtong0898 committed Jan 13, 2022
1 parent e75f1b0 commit 46e95a7
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 2 deletions.
13 changes: 13 additions & 0 deletions examples/postman_echo/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import re
import sys
from httprunner.cli import main


if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.argv.append("run")
sys.argv.append("--verbose")
# sys.argv.append("request_methods/request_with_extract.yml")
sys.argv.append("request_methods/request_with_testcase_validate.yml")
print(sys.argv)
sys.exit(main())
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
config:
name: "request testcase: with error retry"
base_url: "https://postman-echo.com"

teststeps:
-
name: get with params
testcase: request_methods/request_with_teststep_errorretry.yml
retry:
tries: 3
delay: 5
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# NOTE: Generated By HttpRunner v3.1.6
# FROM: request_methods/request_with_testcase_errorretry.yml


import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent))


from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase

from request_methods.request_with_teststep_errorretry_test import (
TestCaseRequestWithTeststepErrorretry as RequestWithTeststepErrorretry,
)


class TestCaseRequestWithTestcaseErrorretry(HttpRunner):

config = Config("request testcase: with error retry").base_url(
"https://postman-echo.com"
)

teststeps = [
Step(
RunTestCase("get with params")
.with_retry(tries=3, delay=5)
.call(RequestWithTeststepErrorretry)
),
]


if __name__ == "__main__":
TestCaseRequestWithTestcaseErrorretry().test_start()
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
config:
name: "request teststep: with error retry"
base_url: "https://postman-echo.com"

teststeps:
-
name: get with params
request:
method: GET
url: /get
params:
info: "ip"
headers:
User-Agent: HttpRunner/${get_httprunner_version()}
retry:
tries: 3
delay: 5
validate:
- eq: ["status_code", 200]
- eq: ["body.args.foo1", "bar11"]
- eq: ["body.args.sum_v", "3"]
- eq: ["body.args.foo2", "bar21"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# NOTE: Generated By HttpRunner v3.1.6
# FROM: request_methods/request_with_teststep_errorretry.yml


from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase


class TestCaseRequestWithTeststepErrorretry(HttpRunner):

config = Config("request teststep: with error retry").base_url(
"https://postman-echo.com"
)

teststeps = [
Step(
RunRequest("get with params")
.with_retry(tries=3, delay=5)
.get("/get")
.with_params(**{"info": "ip"})
.with_headers(**{"User-Agent": "HttpRunner/${get_httprunner_version()}"})
.validate()
.assert_equal("status_code", 200)
.assert_equal("body.args.foo1", "bar11")
.assert_equal("body.args.sum_v", "3")
.assert_equal("body.args.foo2", "bar21")
),
]


if __name__ == "__main__":
TestCaseRequestWithTeststepErrorretry().test_start()
3 changes: 3 additions & 0 deletions httprunner/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ def _ensure_step_attachment(step: Dict) -> Dict:
if "variables" in step:
test_dict["variables"] = step["variables"]

if "retry" in step:
test_dict["retry"] = step["retry"]

if "setup_hooks" in step:
test_dict["setup_hooks"] = step["setup_hooks"]

Expand Down
5 changes: 5 additions & 0 deletions httprunner/make.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ def make_teststep_chain_style(teststep: Dict) -> Text:
variables = teststep["variables"]
step_info += f".with_variables(**{variables})"

if "retry" in teststep:
tries = teststep["retry"]["tries"]
delay = teststep["retry"]["delay"]
step_info += f".with_retry(tries={tries}, delay={delay})"

if "setup_hooks" in teststep:
setup_hooks = teststep["setup_hooks"]
for hook in setup_hooks:
Expand Down
6 changes: 6 additions & 0 deletions httprunner/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ class MethodEnum(Text, Enum):
PATCH = "PATCH"


class TRetry(BaseModel):
tries: int
delay: int


class TConfig(BaseModel):
name: Name
verify: Verify = False
Expand Down Expand Up @@ -74,6 +79,7 @@ class TStep(BaseModel):
export: Export = []
validators: Validators = Field([], alias="validate")
validate_script: List[Text] = []
retry: Union[TRetry, None] = TRetry(tries=1, delay=0)


class TestCase(BaseModel):
Expand Down
11 changes: 9 additions & 2 deletions httprunner/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
USE_ALLURE = False

from loguru import logger
from retry.api import retry_call

from httprunner import utils, exceptions
from httprunner.client import HttpSession
Expand Down Expand Up @@ -368,9 +369,15 @@ def run_testcase(self, testcase: TestCase) -> "HttpRunner":
# run step
if USE_ALLURE:
with allure.step(f"step: {step.name}"):
extract_mapping = self.__run_step(step)
extract_mapping = retry_call(
self.__run_step, fargs=(step,), fkwargs={},
tries=step.retry.tries, delay=step.retry.delay
)
else:
extract_mapping = self.__run_step(step)
extract_mapping = retry_call(
self.__run_step, fargs=(step, ), fkwargs={},
tries=step.retry.tries, delay=step.retry.delay
)

# save extracted variables to session variables
extracted_variables.update(extract_mapping)
Expand Down
9 changes: 9 additions & 0 deletions httprunner/testcase.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
TRequest,
MethodEnum,
TestCase,
TRetry
)


Expand Down Expand Up @@ -309,6 +310,10 @@ def with_variables(self, **variables) -> "RunRequest":
self.__step_context.variables.update(variables)
return self

def with_retry(self, tries: int, delay: int):
self.__step_context.retry = TRetry(tries=tries, delay=delay)
return self

def setup_hook(self, hook: Text, assign_var_name: Text = None) -> "RunRequest":
if assign_var_name:
self.__step_context.setup_hooks.append({assign_var_name: hook})
Expand Down Expand Up @@ -377,6 +382,10 @@ def with_variables(self, **variables) -> "RunTestCase":
self.__step_context.variables.update(variables)
return self

def with_retry(self, tries: int, delay: int):
self.__step_context.retry = TRetry(tries=tries, delay=delay)
return self

def setup_hook(self, hook: Text, assign_var_name: Text = None) -> "RunTestCase":
if assign_var_name:
self.__step_context.setup_hooks.append({assign_var_name: hook})
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ requests-toolbelt = {version = "^0.9.1", optional = true}
filetype = {version = "^1.0.7", optional = true}
locust = {version = "^1.0.3", optional = true}
Brotli = "^1.0.9"
retry = "^0.9.2"

[tool.poetry.extras]
allure = ["allure-pytest"] # pip install "httprunner[allure]", poetry install -E allure
Expand Down

0 comments on commit 46e95a7

Please sign in to comment.