由于接口文档编写耗时,而且需要持续维护,耗时耗力,后来发现一款 swagger 工具非常好用,可以一键自动生成接口文档,目前可视化已经在项目线上使用。
对于测试而言,自动化接口脚本也一样存在录制,编写,维护更新耗时耗力,于是想着能不能有种方法可以将 swagger-ui 文档转换为 jmx 文件?
import requests
import json
def get_test_plan():
url = ""
response = requests.get(url)
data = json.loads(response.text)
print(data.get("swagger"))
host = data.get("host")
base_path = data.get("basePath")
path = data.get("paths")
thread_groups = data.get("tags")
definitions = data.get("definitions")
for thread_group in thread_groups:
thread_group['host'] = str(host).split(":")[0]
thread_group["port"] = str(host).split(":")[1]
thread_group['sample'] = []
for path_key,path_value in path.items():
if isinstance(path_value,dict):
for method,sample_value in path_value.items():
if isinstance(sample_value,dict):
if sample_value.get("tags")[0] == thread_group.get("name"):
parameters = {}
if isinstance(sample_value.get("parameters"),list):
if sample_value.get("parameters").__len__()>1:
for param in sample_value.get("parameters"):
parameters[param.get("name")] = "${" + param.get("name") + "}"
else:
for param in sample_value.get("parameters"):
model_name = (param.get("name"))[0].upper()+(param.get("name"))[1:]
if model_name in list(definitions.keys()):
model_value = definitions.get(model_name)
for param_name,param_value in model_value.get("properties").items():
parameters[param_name] = "${" + param_name + "}"
thread_group['sample'].append({"path":base_path+path_key,"method":method,"params":parameters,"sampler_comments":sample_value.get("description")})
return thread_groups
if __name__ == '__main__':
thread_group = get_test_plan()
print(thread_group)
# *_*coding:utf-8 *_*
import json
from lxml import etree
import ThreadGroup
def jmeter_test_plan(root_xml):
JmeterTestPlan = root_xml
JmeterTestPlan.set('version','1.2')
JmeterTestPlan.set('properties','2.3')
JmeterTestPlan.set('jmeter','5.1.1 r1855137')
return etree.SubElement(JmeterTestPlan,'hashTree')
def test_plan(parent_xml):
testPlan = etree.SubElement(parent_xml,'TestPlan')
testPlan.set("guiclass","TestPlanGui")
testPlan.set("testclass","TestPlan")
testPlan.set("testname","Test Plan")
testPlan.set("enabled","true")
stringProp = etree.SubElement(testPlan,"stringProp")
stringProp.set("name","TestPlan.comments")
stringProp.text = ''
boolProp1 = etree.SubElement(testPlan,"boolProp")
boolProp1.set("name","TestPlan.functional_mode")
boolProp1.text = "false"
boolProp2 = etree.SubElement(testPlan,"boolProp")
boolProp2.set("name","TestPlan.tearDown_on_shutdown")
boolProp2.text = "true"
boolProp3 = etree.SubElement(testPlan,"boolProp")
boolProp3.set("name","TestPlan.serialize_threadgroups")
boolProp3.text = "false"
elementProp = etree.SubElement(testPlan,"elementProp")
elementProp.set("name","TestPlan.user_defined_variables")
elementProp.set("elementType","Arguments")
elementProp.set("guiclass","ArgumentsPanel")
elementProp.set("testclass","Arguments")
elementProp.set("testname","User Defined Variables")
elementProp.set("enabled","true")
collectionProp = etree.SubElement(elementProp,"collectionProp")
collectionProp.set("name","Arguments.arguments")
stringProp2 = etree.SubElement(testPlan,"stringProp")
stringProp2.set("name","TestPlan.user_define_classpath")
stringProp2.text = ''
return etree.SubElement(parent_xml,'hashTree')
def thread_group(parent_xml):
theadGroup = etree.SubElement(parent_xml,"ThreadGroup")
theadGroup.set("guiclass","ThreadGroupGui")
theadGroup.set("testclass","ThreadGroup")
theadGroup.set("testname","Thread Group")
theadGroup.set("enabled","true")
stringProp = etree.SubElement(theadGroup,"stringProp")
stringProp.set("name","ThreadGroup.on_sample_error")
stringProp.text = "continue"
elementProp = etree.SubElement(theadGroup,"elementProp")
common_api(elementProp,{"name":"ThreadGroup.main_controller","elementType":"LoopController","guiclass":"LoopControlPanel","testclass":"LoopController","testname":"Loop Controller","enabled":"true"})
boolProp = etree.SubElement(elementProp,"boolProp")
boolProp.set("name","LoopController.continue_forever")
boolProp.text = "false"
stringProp = etree.SubElement(elementProp,"stringProp")
stringProp.set("name","LoopController.loops")
stringProp.text = "1"
stringProp = etree.SubElement(theadGroup,"stringProp")
stringProp.set("name","ThreadGroup.num_threads")
stringProp.text = "1"
boolProp = etree.SubElement(theadGroup, "boolProp")
boolProp.set("name", "ThreadGroup.scheduler")
boolProp.text = "false"
stringProp = etree.SubElement(theadGroup, "stringProp")
stringProp.set("name", "ThreadGroup.duration")
stringProp.text = ''
stringProp = etree.SubElement(theadGroup, "stringProp")
stringProp.set("name", "ThreadGroup.delay")
stringProp.text = ''
return etree.SubElement(parent_xml,"hashTree")
def controller(parent_xml,result):
for data in result:
GenericController = etree.SubElement(parent_xml, "GenericController")
GenericController.set("guiclass", "LogicControllerGui")
GenericController.set("testclass", "GenericController")
GenericController.set("testname", data.get("name"))
GenericController.set("enabled", "true")
stringProp = etree.SubElement(GenericController, "stringProp")
stringProp.set("name", "TestPlan.comments")
stringProp.text = data.get("description")
shashTree = etree.SubElement(parent_xml, "hashTree")
for sample in data.get("sample"):
HTTPSamplerProxy = etree.SubElement(shashTree, "HTTPSamplerProxy")
common_api(HTTPSamplerProxy,
{"guiclass": "HttpTestSampleGui", "testclass": "HTTPSamplerProxy",
"testname": sample.get('path'),
"enabled": "true"})
if sample.get("params").__len__() < 1:
elementProp = etree.SubElement(HTTPSamplerProxy, "elementProp")
common_api(elementProp, {"name": "HTTPsampler.Arguments", "elementType": "Arguments",
"guiclass": "HTTPArgumentsPanel", "testclass": "Arguments",
"testname": "User Defined Variables", "enabled": "true"})
collectionProp = etree.SubElement(elementProp, "collectionProp")
collectionProp.set("name", "Arguments.arguments")
else:
boolProp = etree.SubElement(HTTPSamplerProxy, "boolProp")
boolProp.set("name", "HTTPSampler.postBodyRaw")
boolProp.text = "true"
elementProp = etree.SubElement(HTTPSamplerProxy, "elementProp")
common_api(elementProp, {"name": "HTTPsampler.Arguments", "elementType": "Arguments"})
collectionProp = etree.SubElement(elementProp, "collectionProp")
collectionProp.set("name", "Arguments.arguments")
elementProp = etree.SubElement(collectionProp, "elementProp")
elementProp.set("name", "")
elementProp.set("elementType", "HTTPArgument")
boolProp = etree.SubElement(elementProp, "boolProp")
boolProp.set("name", "HTTPArgument.always_encode")
boolProp.text = "false"
stringProp = etree.SubElement(elementProp, "stringProp")
stringProp.set("name", "Argument.value")
# stringProp.text = json.dumps(sample.get("params")).replace("\"", """)
stringProp.text = json.dumps(sample.get("params"))
stringProp = etree.SubElement(elementProp, "stringProp")
stringProp.set("name", "Argument.metadata")
stringProp.text = "="
###host
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
stringProp.set("name", "HTTPSampler.domain")
stringProp.text = data.get("host")
###port
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
stringProp.set("name", "HTTPSampler.port")
stringProp.text = data.get("port")
##protocol
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
stringProp.set("name", "HTTPSampler.protocol")
stringProp.text = "http"
# encoding
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
stringProp.set("name", "HTTPSampler.contentEncoding")
stringProp.text = "utf8"
# path
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
stringProp.set("name", "HTTPSampler.path")
stringProp.text = sample.get("path")
# method
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
stringProp.set("name", "HTTPSampler.method")
stringProp.text = sample.get("method")
# follow redirects
boolProp = etree.SubElement(HTTPSamplerProxy, "boolProp")
boolProp.set("name", "HTTPSampler.follow_redirects")
boolProp.text = "true"
# auto redirects
boolProp = etree.SubElement(HTTPSamplerProxy, "boolProp")
boolProp.set("name", "HTTPSampler.auto_redirects")
boolProp.text = "false"
# use keepalive
boolProp = etree.SubElement(HTTPSamplerProxy, "boolProp")
boolProp.set("name", "HTTPSampler.use_keepalive")
boolProp.text = "true"
# DO MULTIPART POST
boolProp = etree.SubElement(HTTPSamplerProxy, "boolProp")
boolProp.set("name", "HTTPSampler.DO_MULTIPART_POST")
boolProp.text = "false"
# embedded url re
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
stringProp.set("name", "HTTPSampler.embedded_url_re")
stringProp.text = ""
# connect timeout
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
stringProp.set("name", "HTTPSampler.connect_timeout")
stringProp.text = ""
# response timeout
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
stringProp.set("name", "HTTPSampler.response_timeout")
stringProp.text = ""
# comments
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
stringProp.set("name", "TestPlan.comments")
stringProp.text = sample.get("sampler_comments")
hash_tree = etree.SubElement(shashTree, "hashTree")
def common_api(obj_xml,datas):
for key,value in datas.items():
obj_xml.set(key,value)
if __name__ == '__main__':
result = ThreadGroup.get_test_plan()
jmeterTestPlan = etree.Element("jmeterTestPlan")
hashTree = jmeter_test_plan(jmeterTestPlan)
testPlan = test_plan(hashTree)
threadGroup = thread_group(testPlan)
control = controller(threadGroup,result)
print(etree.tostring(jmeterTestPlan,pretty_print=True))
tree = etree.ElementTree(jmeterTestPlan)
tree.write('text.xml', pretty_print=True, xml_declaration=True, encoding='utf-8')