diff --git a/ate/testcase.py b/ate/testcase.py new file mode 100644 index 00000000..80b1c6aa --- /dev/null +++ b/ate/testcase.py @@ -0,0 +1,68 @@ +import re +from ate import exception + +class TestcaseParser(object): + + def __init__(self, variables_binds={}): + self.variables_binds = variables_binds + + def parse(self, testcase_template): + """ parse testcase_template, replace all variables with bind value. + variables marker: ${variable}. + @param testcase_template + "request": { + "url": "http://127.0.0.1:5000/api/users/${uid}", + "method": "POST", + "headers": { + "Content-Type": "application/json", + "authorization": "${authorization}", + "random": "${random}" + }, + "body": "${json}" + }, + "response": { + "status_code": "${expected_status}", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": True, + "msg": "user created successfully." + } + } + """ + return self.substitute(testcase_template) + + def substitute(self, content): + """ substitute content recursively, each variable will be replaced with bind value. + variables marker: ${variable}. + """ + if isinstance(content, str): + # check if content includes ${variable} + matched = re.match(r"(.*)\$\{(.*)\}(.*)", content) + if matched: + # this is a variable, and will replace with its bind value + variable_name = matched.group(2) + value = self.variables_binds.get(variable_name) + if value is None: + raise exception.ParamsError( + "%s is not defined in bind variables!" % variable_name) + if matched.group(1) or matched.group(3): + # e.g. /api/users/${uid} + return re.sub(r"\$\{.*\}", value, content) + + return value + + return content + + if isinstance(content, list): + return [self.substitute(item) for item in content] + + if isinstance(content, dict): + parsed_content = {} + for key, value in content.items(): + parsed_content[key] = self.substitute(value) + + return parsed_content + + return content diff --git a/test/test_testcase.py b/test/test_testcase.py new file mode 100644 index 00000000..5ae5aa55 --- /dev/null +++ b/test/test_testcase.py @@ -0,0 +1,81 @@ +import unittest + +from ate.testcase import TestcaseParser +from ate import exception + + +class TestcaseParserUnittest(unittest.TestCase): + + def setUp(self): + self.variables_binds = { + "uid": "1000", + "random": "A2dEx", + "authorization": "a83de0ff8d2e896dbd8efb81ba14e17d", + "json": { + "name": "user1", + "password": "123456" + }, + "expected_status": 201, + "expected_success": True + } + self.testcase_parser = TestcaseParser(self.variables_binds) + + def test_parse_testcase_template(self): + testcase = { + "request": { + "url": "http://127.0.0.1:5000/api/users/${uid}", + "method": "POST", + "headers": { + "Content-Type": "application/json", + "authorization": "${authorization}", + "random": "${random}" + }, + "body": "${json}" + }, + "response": { + "status_code": "${expected_status}", + "headers": { + "Content-Type": "application/json" + }, + "body": { + "success": "${expected_success}", + "msg": "user created successfully." + } + } + } + parsed_testcase = self.testcase_parser.parse(testcase) + + self.assertEqual( + parsed_testcase["request"]["url"], + "http://127.0.0.1:5000/api/users/%s" % self.variables_binds["uid"] + ) + self.assertEqual( + parsed_testcase["request"]["headers"]["authorization"], + self.variables_binds["authorization"] + ) + self.assertEqual( + parsed_testcase["request"]["headers"]["random"], + self.variables_binds["random"] + ) + self.assertEqual( + parsed_testcase["request"]["body"], + self.variables_binds["json"] + ) + self.assertEqual( + parsed_testcase["response"]["status_code"], + self.variables_binds["expected_status"] + ) + self.assertEqual( + parsed_testcase["response"]["body"]["success"], + self.variables_binds["expected_success"] + ) + + def test_parse_testcase_template_miss_bind_variable(self): + testcase = { + "request": { + "url": "http://127.0.0.1:5000/api/users/${uid}", + "method": "${method}" + } + } + with self.assertRaises(exception.ParamsError): + self.testcase_parser.parse(testcase)