From 33dabbf027289c3bca264be0f4dadc45d212f28f Mon Sep 17 00:00:00 2001 From: debugtalk Date: Mon, 24 Jun 2019 16:09:10 +0800 Subject: [PATCH] feat: testcase in format version 2 --- httprunner/__about__.py | 2 +- httprunner/loader.py | 47 ++++++++++++++++++++++++++++ tests/test_loader.py | 29 ++++++++++++----- tests/testcases/setup.json | 59 +++++++++++++++++++++++++++++++++++ tests/testcases/setup.v2.json | 43 +++++++++++++++++++++++++ tests/testcases/setup.v2.yml | 32 +++++++++++++++++++ 6 files changed, 204 insertions(+), 8 deletions(-) create mode 100644 tests/testcases/setup.json create mode 100644 tests/testcases/setup.v2.json create mode 100644 tests/testcases/setup.v2.yml diff --git a/httprunner/__about__.py b/httprunner/__about__.py index 74d0888b..e3bd235e 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.1.3' +__version__ = '2.2.0' __author__ = 'debugtalk' __author_email__ = 'mail@debugtalk.com' __license__ = 'Apache-2.0' diff --git a/httprunner/loader.py b/httprunner/loader.py index 3fddb238..35e8b4d7 100644 --- a/httprunner/loader.py +++ b/httprunner/loader.py @@ -442,6 +442,44 @@ def load_testcase(raw_testcase): } +def load_testcase_v2(raw_testcase): + """ load testcase in version 2. + + Args: + raw_testcase (dict): raw testcase content loaded from JSON/YAML file: + { + "config": { + "name": "xxx", + "variables": {} + } + "teststeps": [ + { + "name": "teststep 1", + "request" {...} + }, + { + "name": "teststep 2", + "request" {...} + }, + ] + } + + Returns: + dict: loaded testcase content + { + "config": {}, + "teststeps": [test11, test12] + } + + """ + raw_teststeps = raw_testcase.pop("teststeps") + raw_testcase["teststeps"] = [ + load_teststep(teststep) + for teststep in raw_teststeps + ] + return raw_testcase + + def load_testsuite(raw_testsuite): """ load testsuite with testcase references. @@ -523,18 +561,27 @@ def load_test_file(path): loaded_content = load_testsuite(raw_content) loaded_content["path"] = path loaded_content["type"] = "testsuite" + + elif "teststeps" in raw_content: + # file_type: testcase (format version 2) + loaded_content = load_testcase_v2(raw_content) + loaded_content["path"] = path + loaded_content["type"] = "testcase" + elif "request" in raw_content: # file_type: api # TODO: add json schema validation for api loaded_content = raw_content loaded_content["path"] = path loaded_content["type"] = "api" + else: # invalid format logger.log_warning("Invalid test file format: {}".format(path)) elif isinstance(raw_content, list) and len(raw_content) > 0: # file_type: testcase + # make compatible with version < 2.2.0 # TODO: add json schema validation for testcase loaded_content = load_testcase(raw_content) loaded_content["path"] = path diff --git a/tests/test_loader.py b/tests/test_loader.py index 97845ddd..b9d46f1d 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -292,13 +292,28 @@ class TestSuiteLoader(unittest.TestCase): self.assertEqual(loaded_content["request"]["url"], "/api/users/$uid") def test_load_test_file_testcase(self): - loaded_content = loader.load_test_file("tests/testcases/setup.yml") - self.assertEqual(loaded_content["type"], "testcase") - self.assertIn("path", loaded_content) - self.assertIn("config", loaded_content) - self.assertEqual(loaded_content["config"]["name"], "setup and reset all.") - self.assertIn("teststeps", loaded_content) - self.assertEqual(len(loaded_content["teststeps"]), 2) + for loaded_content in [ + loader.load_test_file("tests/testcases/setup.yml"), + loader.load_test_file("tests/testcases/setup.json") + ]: + self.assertEqual(loaded_content["type"], "testcase") + self.assertIn("path", loaded_content) + self.assertIn("config", loaded_content) + self.assertEqual(loaded_content["config"]["name"], "setup and reset all.") + self.assertIn("teststeps", loaded_content) + self.assertEqual(len(loaded_content["teststeps"]), 2) + + def test_load_test_file_testcase_v2(self): + for loaded_content in [ + loader.load_test_file("tests/testcases/setup.v2.yml"), + loader.load_test_file("tests/testcases/setup.v2.json") + ]: + self.assertEqual(loaded_content["type"], "testcase") + self.assertIn("path", loaded_content) + self.assertIn("config", loaded_content) + self.assertEqual(loaded_content["config"]["name"], "setup and reset all.") + self.assertIn("teststeps", loaded_content) + self.assertEqual(len(loaded_content["teststeps"]), 2) def test_load_test_file_testsuite(self): loaded_content = loader.load_test_file("tests/testsuites/create_users.yml") diff --git a/tests/testcases/setup.json b/tests/testcases/setup.json new file mode 100644 index 00000000..d8690447 --- /dev/null +++ b/tests/testcases/setup.json @@ -0,0 +1,59 @@ +[ + { + "config": { + "name": "setup and reset all.", + "output": [ + "session_token" + ], + "verify": false, + "variables": { + "device_sn": "TESTCASE_SETUP_XXX", + "app_version": "2.8.6", + "os_platform": "ios", + "user_agent": "iOS/10.3" + }, + "base_url": "http://127.0.0.1:5000", + "id": "setup_and_reset" + } + }, + { + "test": { + "validate": [ + { + "eq": [ + "status_code", + 200 + ] + }, + { + "len_eq": [ + "content.token", + 16 + ] + } + ], + "api": "api/get_token.yml", + "extract": [ + { + "session_token": "content.token" + } + ], + "variables": { + "device_sn": "$device_sn", + "app_version": "2.8.6", + "os_platform": "ios", + "user_agent": "iOS/10.3" + }, + "name": "get token (setup)" + } + }, + { + "test": { + "variables": { + "token": "$session_token" + }, + "api": "api/reset_all.yml", + "name": "reset all users" + } + } +] \ No newline at end of file diff --git a/tests/testcases/setup.v2.json b/tests/testcases/setup.v2.json new file mode 100644 index 00000000..bbc2d3ed --- /dev/null +++ b/tests/testcases/setup.v2.json @@ -0,0 +1,43 @@ +{ + "config": { + "name": "setup and reset all.", + "base_url": "http://127.0.0.1:5000", + "variables": { + "device_sn": "TESTCASE_SETUP_XXX", + "app_version": "2.8.6", + "os_platform": "ios", + "user_agent": "iOS/10.3" + }, + "id": "setup_and_reset", + "verify": false, + "output": [ + "session_token" + ] + }, + "teststeps": [ + { + "name": "get token (setup)", + "api": "api/get_token.yml", + "variables": { + "device_sn": "$device_sn", + "app_version": "2.8.6", + "os_platform": "ios", + "user_agent": "iOS/10.3" + }, + "extract": [ + {"session_token": "content.token"} + ], + "validate": [ + {"eq": ["status_code", 200]}, + {"len_eq": ["content.token", 16]} + ] + }, + { + "name": "reset all users", + "api": "api/reset_all.yml", + "variables": { + "token": "$session_token" + } + } + ] +} \ No newline at end of file diff --git a/tests/testcases/setup.v2.yml b/tests/testcases/setup.v2.yml new file mode 100644 index 00000000..3cf58c1d --- /dev/null +++ b/tests/testcases/setup.v2.yml @@ -0,0 +1,32 @@ +config: + name: "setup and reset all." + id: setup_and_reset + variables: + user_agent: 'iOS/10.3' + device_sn: "TESTCASE_SETUP_XXX" + os_platform: 'ios' + app_version: '2.8.6' + base_url: "http://127.0.0.1:5000" + verify: False + output: + - session_token + +teststeps: +- + name: get token (setup) + api: api/get_token.yml + variables: + user_agent: 'iOS/10.3' + device_sn: $device_sn + os_platform: 'ios' + app_version: '2.8.6' + extract: + - session_token: content.token + validate: + - eq: ["status_code", 200] + - len_eq: ["content.token", 16] +- + name: reset all users + api: api/reset_all.yml + variables: + token: $session_token