From 7fc3280584cb64e8541f2ff38fc9d68823949dfe Mon Sep 17 00:00:00 2001 From: debugtalk Date: Tue, 25 Jun 2019 15:51:24 +0800 Subject: [PATCH 1/6] fix: extend with testcase reference in format version 2 --- CHANGELOG.md | 6 ++++++ httprunner/__about__.py | 2 +- httprunner/loader.py | 13 ++++++++++++- tests/testcases/create_user.v2.yml | 22 ++++++++++++++++++++++ tests/testsuites/create_users.v2.json | 4 ++-- tests/testsuites/create_users.v2.yml | 4 ++-- 6 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 tests/testcases/create_user.v2.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b0f541c..9198cec6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Release History +## 2.2.1 (2019-06-25) + +**Bugfixes** + +- fix extend with testcase reference in format version 2 + ## 2.2.0 (2019-06-24) **Features** diff --git a/httprunner/__about__.py b/httprunner/__about__.py index e3bd235e..df64ac93 100644 --- a/httprunner/__about__.py +++ b/httprunner/__about__.py @@ -1,7 +1,7 @@ __title__ = 'HttpRunner' __description__ = 'One-stop solution for HTTP(S) testing.' __url__ = 'https://github.com/HttpRunner/HttpRunner' -__version__ = '2.2.0' +__version__ = '2.2.1' __author__ = 'debugtalk' __author_email__ = 'mail@debugtalk.com' __license__ = 'Apache-2.0' diff --git a/httprunner/loader.py b/httprunner/loader.py index 4093bb37..8f1aadb7 100644 --- a/httprunner/loader.py +++ b/httprunner/loader.py @@ -332,7 +332,18 @@ def __extend_with_testcase_ref(raw_testinfo): project_mapping["PWD"], *testcase_path.split("/") ) - testcase_dict = load_testcase(load_file(testcase_path)) + loaded_testcase = load_file(testcase_path) + + if isinstance(loaded_testcase, list): + # make compatible with version < 2.2.0 + testcase_dict = load_testcase(loaded_testcase) + elif isinstance(loaded_testcase, dict) and "teststeps" in loaded_testcase: + # format version 2, implemented in 2.2.0 + testcase_dict = load_testcase_v2(loaded_testcase) + else: + raise exceptions.FileFormatError( + "Invalid format testcase: {}".format(testcase_path)) + tests_def_mapping[testcase_path] = testcase_dict else: testcase_dict = tests_def_mapping[testcase_path] diff --git a/tests/testcases/create_user.v2.yml b/tests/testcases/create_user.v2.yml new file mode 100644 index 00000000..7f34c532 --- /dev/null +++ b/tests/testcases/create_user.v2.yml @@ -0,0 +1,22 @@ +config: + name: "create user and check result." + id: create_user + base_url: "http://127.0.0.1:5000" + variables: + uid: 9001 + device_sn: "TESTCASE_CREATE_XXX" + output: + - session_token + +teststeps: +- + name: setup and reset all (override) for $device_sn. + testcase: testcases/setup.yml + output: + - session_token + +- + name: create user and check result. + variables: + token: $session_token + testcase: testcases/deps/check_and_create.yml diff --git a/tests/testsuites/create_users.v2.json b/tests/testsuites/create_users.v2.json index de4d5d27..450a27aa 100644 --- a/tests/testsuites/create_users.v2.json +++ b/tests/testsuites/create_users.v2.json @@ -11,7 +11,7 @@ "testcases": [ { "name": "create user 1000 and check result.", - "testcase": "testcases/create_user.yml", + "testcase": "testcases/create_user.v2.yml", "variables": { "var_d": "$var_c", "var_c": "${gen_random_string(5)}", @@ -20,7 +20,7 @@ }, { "name": "create user 1001 and check result.", - "testcase": "testcases/create_user.yml", + "testcase": "testcases/create_user.v2.yml", "variables": { "var_d": "$var_c", "var_c": "${gen_random_string(5)}", diff --git a/tests/testsuites/create_users.v2.yml b/tests/testsuites/create_users.v2.yml index 0714d82f..8fcdd930 100644 --- a/tests/testsuites/create_users.v2.yml +++ b/tests/testsuites/create_users.v2.yml @@ -9,7 +9,7 @@ config: testcases: - name: create user 1000 and check result. - testcase: testcases/create_user.yml + testcase: testcases/create_user.v2.yml variables: uid: 1000 var_c: ${gen_random_string(5)} @@ -17,7 +17,7 @@ testcases: - name: create user 1001 and check result. - testcase: testcases/create_user.yml + testcase: testcases/create_user.v2.yml variables: uid: 1001 var_c: ${gen_random_string(5)} From d7121132a702bfda944cf1f672dff4be692fd402 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Tue, 25 Jun 2019 16:18:57 +0800 Subject: [PATCH 2/6] update default .gitignore of new created scaffold project --- CHANGELOG.md | 4 ++++ httprunner/utils.py | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9198cec6..7799e613 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## 2.2.1 (2019-06-25) +**Features** + +- update default `.gitignore` of new created scaffold project + **Bugfixes** - fix extend with testcase reference in format version 2 diff --git a/httprunner/utils.py b/httprunner/utils.py index e8e90747..2a422846 100644 --- a/httprunner/utils.py +++ b/httprunner/utils.py @@ -432,7 +432,14 @@ def create_scaffold(project_name): # create .gitignore file ignore_file = os.path.join(project_name, ".gitignore") - ignore_content = ".env\nreports/*" + ignore_content = "\n".join([ + ".env", + "reports/*", + "__pycache__/*", + "*.pyc", + ".python-version", + "logs/*" + ]) with open(ignore_file, "w") as f: f.write(ignore_content) From 6f0cc48346c4216836c746bda4aaba68487b808a Mon Sep 17 00:00:00 2001 From: debugtalk Date: Tue, 25 Jun 2019 17:36:33 +0800 Subject: [PATCH 3/6] feat: add demo api/testcase/testsuite to new created scaffold project --- CHANGELOG.md | 1 + httprunner/utils.py | 100 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 83 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7799e613..6156b532 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ **Features** +- add demo api/testcase/testsuite to new created scaffold project - update default `.gitignore` of new created scaffold project **Bugfixes** diff --git a/httprunner/utils.py b/httprunner/utils.py index 2a422846..54fad0b6 100644 --- a/httprunner/utils.py +++ b/httprunner/utils.py @@ -410,28 +410,82 @@ def create_scaffold(project_name): logger.color_print("Start to create new project: {}".format(project_name), "GREEN") logger.color_print("CWD: {}\n".format(os.getcwd()), "BLUE") - def create_path(path, ptype): + def create_folder(path): + os.makedirs(path) + msg = "created folder: {}".format(path) + logger.color_print(msg, "BLUE") + + def create_file(path, file_content=""): + with open(path, 'w') as f: + f.write(file_content) + msg = "created file: {}".format(path) + logger.color_print(msg, "BLUE") + + def create_path(path, ptype, file_content=""): if ptype == "folder": os.makedirs(path) elif ptype == "file": - open(path, 'w').close() + with open(path, 'w') as f: + f.write(file_content) - msg = "created {}: {}".format(ptype, path) - logger.color_print(msg, "BLUE") + demo_api_content = """ +name: demo api +variables: + var1: value1 + var2: value2 +request: + url: /api/path/$var1 + method: POST + headers: + Content-Type: "application/json" + json: + key: $var2 +validate: + - eq: ["status_code", 200] +""" + demo_testcase_content = """ +config: + name: "demo testcase" + variables: + device_sn: "ABC" + base_url: "http://127.0.0.1:5000" - path_list = [ - (project_name, "folder"), - (os.path.join(project_name, "api"), "folder"), - (os.path.join(project_name, "testcases"), "folder"), - (os.path.join(project_name, "testsuites"), "folder"), - (os.path.join(project_name, "reports"), "folder"), - (os.path.join(project_name, "debugtalk.py"), "file"), - (os.path.join(project_name, ".env"), "file") - ] - [create_path(p[0], p[1]) for p in path_list] +teststeps: +- + name: demo step 1 + api: path/to/api1.yml + variables: + user_agent: 'iOS/10.3' + device_sn: $device_sn + extract: + - token: content.token + validate: + - eq: ["status_code", 200] +- + name: demo step 2 + api: path/to/api2.yml + variables: + token: $token +""" + demo_testsuite_content = """ +config: + name: "demo testsuite" + variables: + device_sn: "XYZ" + base_url: "http://127.0.0.1:5000" - # create .gitignore file - ignore_file = os.path.join(project_name, ".gitignore") +testcases: +- + name: call demo_testcase with data 1 + testcase: path/to/demo_testcase.yml + variables: + device_sn: $device_sn +- + name: call demo_testcase with data 2 + testcase: path/to/demo_testcase.yml + variables: + device_sn: $device_sn +""" ignore_content = "\n".join([ ".env", "reports/*", @@ -440,8 +494,18 @@ def create_scaffold(project_name): ".python-version", "logs/*" ]) - with open(ignore_file, "w") as f: - f.write(ignore_content) + + create_folder(project_name) + create_folder(os.path.join(project_name, "api")) + create_folder(os.path.join(project_name, "testcases")) + create_folder(os.path.join(project_name, "testsuites")) + create_folder(os.path.join(project_name, "reports")) + create_file(os.path.join(project_name, "api", "demo_api.yml"), demo_api_content) + create_file(os.path.join(project_name, "testcases", "demo_testcase.yml"), demo_testcase_content) + create_file(os.path.join(project_name, "testsuites", "demo_testsuite.yml"), demo_testsuite_content) + create_file(os.path.join(project_name, "debugtalk.py"), "") + create_file(os.path.join(project_name, ".env"), "") + create_file(os.path.join(project_name, ".gitignore"), ignore_content) def gen_cartesian_product(*args): From 2222b276347dd8dd3f1255ee8f4ba219be91e4f3 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Tue, 25 Jun 2019 17:50:49 +0800 Subject: [PATCH 4/6] feat: add demo content to debugtalk.py/.env of new created scaffold project --- CHANGELOG.md | 1 + httprunner/utils.py | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6156b532..a4ab4ca1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - add demo api/testcase/testsuite to new created scaffold project - update default `.gitignore` of new created scaffold project +- add demo content to `debugtalk.py`/`.env` of new created scaffold project **Bugfixes** diff --git a/httprunner/utils.py b/httprunner/utils.py index 54fad0b6..f5f712c5 100644 --- a/httprunner/utils.py +++ b/httprunner/utils.py @@ -448,6 +448,8 @@ config: name: "demo testcase" variables: device_sn: "ABC" + username: ${ENV(USERNAME)} + password: ${ENV(PASSWORD)} base_url: "http://127.0.0.1:5000" teststeps: @@ -494,6 +496,16 @@ testcases: ".python-version", "logs/*" ]) + demo_debugtalk_content = """ +import time + +def sleep(n_secs): + time.sleep(n_secs) +""" + demo_env_content = "\n".join([ + "USERNAME=leolee", + "PASSWORD=123456" + ]) create_folder(project_name) create_folder(os.path.join(project_name, "api")) @@ -503,8 +515,8 @@ testcases: create_file(os.path.join(project_name, "api", "demo_api.yml"), demo_api_content) create_file(os.path.join(project_name, "testcases", "demo_testcase.yml"), demo_testcase_content) create_file(os.path.join(project_name, "testsuites", "demo_testsuite.yml"), demo_testsuite_content) - create_file(os.path.join(project_name, "debugtalk.py"), "") - create_file(os.path.join(project_name, ".env"), "") + create_file(os.path.join(project_name, "debugtalk.py"), demo_debugtalk_content) + create_file(os.path.join(project_name, ".env"), demo_env_content) create_file(os.path.join(project_name, ".gitignore"), ignore_content) From 38fe3591518afd5b7cde31c12f94cc7429f102ce Mon Sep 17 00:00:00 2001 From: debugtalk Date: Tue, 25 Jun 2019 20:53:25 +0800 Subject: [PATCH 5/6] fix: ImportError when locustio is not installed --- CHANGELOG.md | 1 + httprunner/cli.py | 12 +++++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4ab4ca1..1a6aa377 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ **Bugfixes** - fix extend with testcase reference in format version 2 +- fix ImportError when locustio is not installed ## 2.2.0 (2019-06-24) diff --git a/httprunner/cli.py b/httprunner/cli.py index 888f6a97..2bafe0c8 100644 --- a/httprunner/cli.py +++ b/httprunner/cli.py @@ -91,14 +91,12 @@ def main_hrun(): def main_locust(): """ Performance test with locust: parse command line options and run commands. """ - # monkey patch ssl at beginning to avoid RecursionError when running locust. - from gevent import monkey; monkey.patch_ssl() - - import multiprocessing - import sys - from httprunner import logger - try: + # monkey patch ssl at beginning to avoid RecursionError when running locust. + from gevent import monkey; monkey.patch_ssl() + import multiprocessing + import sys + from httprunner import logger from httprunner import locusts except ImportError: msg = "Locust is not installed, install first and try again.\n" From 01740004840ee4fa8c87e9710d2898167a5f5937 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Tue, 25 Jun 2019 20:56:09 +0800 Subject: [PATCH 6/6] fix: YAMLLoadWarning by specify yaml loader --- CHANGELOG.md | 1 + httprunner/loader.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a6aa377..36611042 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - fix extend with testcase reference in format version 2 - fix ImportError when locustio is not installed +- fix YAMLLoadWarning by specify yaml loader ## 2.2.0 (2019-06-24) diff --git a/httprunner/loader.py b/httprunner/loader.py index 8f1aadb7..bd346d42 100644 --- a/httprunner/loader.py +++ b/httprunner/loader.py @@ -35,7 +35,7 @@ def load_yaml_file(yaml_file): """ load yaml file and check file content format """ with io.open(yaml_file, 'r', encoding='utf-8') as stream: - yaml_content = yaml.load(stream) + yaml_content = yaml.load(stream, Loader=yaml.FullLoader) _check_format(yaml_file, yaml_content) return yaml_content