之前的文章写了怎么用python生成JMeter脚本,生成了测试计划、线程组、Http监听器组件,详细内容查看文章《Python生成JMeter测试脚本》。本篇内容接着讲怎么用python生成响应断言和查看结果树组件。
响应断言的测试字段和模型匹配规则,在代码中已经注释了,对应着JMeter GUI工具的操作。首先使用set方法修改响应断言的参数,然后使用get方法生成响应断言组件,将组件添加到线程组中,如果想添加到Http监听器中,只需要get方法的parent传http监听器就可以。
import xml.etree.ElementTree as ET
from base import General
from HashCode import GetHashCode
class JMeterResponseAssert:
def __init__(self):
# 断言名称
self.__assert_name = '响应断言'
# 注释
self.__comments = ''
# 自定义失败消息
self.__custom_message = ''
# 测试字段 Assertion.response_data 响应文本 Assertion.response_code 响应代码 Assertion.response_message 响应信息
# Assertion.request_headers 请求头 Assertion.sample_label url样本 Assertion.response_data_as_document 文档(文本)
# Assertion.request_data 请求数据
self.__test_field = 'Assertion.response_data'
self.__assume_success = 'false'
# 模式匹配规则 1 匹配 2 包含 5 不匹配 6 不包含 8 相等 12 不相等 16 子字符串 20 不是子字符串 33 或者匹配 34 或者包含
# 37 或者不匹配 38 或者不包含 40 或者相等 44 或者不相等 48 或者是子字符串 52 或者不是子字符串
self.__test_type = ''
# 适用方式 all 主样本和分支样本 children 分支样本 variable 使用jmeter变量名称 默认为空仅主样本
self.__scope = ''
# 变量名称
self.__scope_variable = ''
self.__assert_text = []
def get_assert_name(self):
return self.__assert_name
def set_assert_name(self, name):
self.__assert_name = name
def get_comments(self):
return self.__comments
def set_comments(self, comments):
self.__comments = comments
def get_custom_message(self):
return self.__custom_message
def set_custom_message(self, custom_message):
self.__custom_message = custom_message
def get_test_field(self):
return self.__test_field
def set_test_field(self, test_field):
self.__test_field = test_field
def get_assume_type(self):
return self.__assume_success
def set_assume_type(self, assume_type):
self.__assume_success = assume_type
def get_test_type(self):
return self.__test_type
def set_test_type(self, test_type):
self.__test_type = test_type
def get_scope(self):
return self.__scope
def set_scope(self, scope):
self.__scope = scope
def get_scope_variable(self):
return self.__scope_variable
def get_scope_variable(self, scope_variable):
self.__scope_variable = scope_variable
def get_assert_text(self):
return self.__assert_text
def set_assert_text(self, assert_text):
self.__assert_text = assert_text
def items(self):
dicts = {
'comments': self.__comments,
'custom_message': self.__custom_message,
'test_field': self.__test_field,
'assume_success': self.__assume_success,
'test_type': self.__test_type,
'scope': self.__scope,
'scope_variable': self.__scope_variable,
}
return dicts
def get(self, parent):
prop_map = {
'comments': General.add_str_prop,
'custom_message': General.add_str_prop,
'test_field': General.add_str_prop,
'assume_success': General.add_bool_prop,
'test_type': General.add_int_prop,
'scope': General.add_str_prop,
'scope_variable': General.add_str_prop
}
keys_map = {
'comments': 'TestPlan.comments',
'custom_message': 'Assertion.custom_message',
'test_field': 'Assertion.test_field',
'assume_success': 'Assertion.assume_success',
'test_type': 'Assertion.test_type',
'scope': 'Assertion.scope',
'scope_variable': 'Scope.variable'
}
assert_prop = ET.SubElement(parent, 'ResponseAssertion')
assert_prop.set('guiclass', 'AssertionGui')
assert_prop.set('testclass', 'ResponseAssertion')
assert_prop.set('testname', self.__assert_name)
if self.__assert_text:
collection_prop = ET.SubElement(assert_prop, 'collectionProp')
collection_prop.set('name', 'Asserion.test_strings')
for text in self.__assert_text:
General.add_str_prop(self, collection_prop, str(GetHashCode.getHashCode(text)), text)
for key, value in self.items().items():
if key in prop_map:
if value == '' or value == 'false':
pass
else:
prop_map[key](self, assert_prop, keys_map[key], str(value))
hashtree = ET.SubElement(parent, 'hashTree')
return assert_prop
查看结果树组件中的__sample_save_config参数,对应GUI工具中的配置,可以配置查看结果树。
import xml.etree.ElementTree as ET
from base import General
class JMeterResultCollector:
def __init__(self):
self.__result_collector_name = '查看结果树'
# 显示日志内容 为true时勾选仅错误日志
self.__error_logging = 'false'
# 显示日志内容 为true时勾选仅成功日志,与错误日志只能选择一个
self.__success_only_logging = ''
# 数据写入文件的文件名称
self.__filename = ''
# 示例保存配置
self.__sample_save_config = {
'time': 'true',
'latency': 'true',
'timestamp': 'true',
'success': 'true',
'label': 'true',
'code': 'true',
'message': 'true',
'threadName': 'true',
'dataType': 'true',
'encoding': 'false',
'assertions': 'true',
'subresults': 'true',
'responseData': 'false',
'samplerData': 'false',
'xml': 'false',
'fieldNames': 'true',
'responseHeaders': 'false',
'requestHeaders': 'false',
'responseDataOnError': 'false',
'saveAssertionResultsFailureMessage': 'true',
'assertionsResultsToSave': '0',
'bytes': 'true',
'sentBytes': 'true',
'url': 'true',
'threadCounts': 'true',
'idleTime': 'true',
'connectTime': 'true'
}
def get_result_collector_name(self):
return self.__result_collector_name
def set_result_collector_name(self, result_collector_name):
self.__result_collector_name = result_collector_name
def get_error_logging(self):
return self.__error_logging
def set_error_logging(self, error_logging):
self.__error_logging = error_logging
def get_success_only_logging(self):
return self.__success_only_logging
def set_success_only_logging(self, success_only_logging):
self.__success_only_logging = success_only_logging
def get_filename(self):
return self.__filename
def set_filename(self, filename):
self.__filename = filename
def get_sample_save_config(self):
return self.__sample_save_config
def set_sample_save_config(self, sample_save_config: dict):
self.__sample_save_config = sample_save_config
def set_config(self, config: dict):
for key, value in config.items():
self.__sample_save_config[key] = value
def items(self):
dicts = {
'error_logging': self.__error_logging,
'success_only_logging': self.__success_only_logging,
'filename': self.__filename
}
return dicts
def get(self, parent):
prop_map = {
'error_logging': General.add_bool_prop,
'success_only_logging': General.add_bool_prop,
'filename': General.add_str_prop
}
keys_map = {
'error_logging': 'ResultCollector.error_logging',
'success_only_logging': 'ResultCollector.success_only_logging',
'filename': 'filename'
}
result_collector_prop = ET.SubElement(parent, 'ResultCollector')
result_collector_prop.set('guiclass', 'ViewResultsFullVisualizer')
result_collector_prop.set('testclass', 'ResultCollector')
result_collector_prop.set('testname', self.__result_collector_name)
for key, value in self.items().items():
if key in prop_map:
prop_map[key](self, result_collector_prop, keys_map[key], str(value))
# if value == '' or value == 'false':
# pass
# else:
# prop_map[key](self, result_collector_prop, keys_map[key], str(value))
obj_prop = ET.SubElement(result_collector_prop, 'objProp')
config_name_prop = ET.SubElement(obj_prop, 'name')
config_name_prop.text = 'saveConfig'
value_prop = ET.SubElement(obj_prop, 'value')
value_prop.set('class', 'SampleSaveConfiguration')
for key, value in self.__sample_save_config.items():
props = ET.SubElement(value_prop, key)
props.text = str(value)
hashtree = ET.SubElement(parent, 'hashTree')
return result_collector_prop
http监听器组件、响应 断言组件、查看结果树组件都在同一个hashtree下,所以先创建一个test_hashtree,然后生成方法都穿这个标签。
import xml.etree.ElementTree as ET
import JMeter
from JMeterThreadGroup import JMeterThreadGroup
from JMeterTestPlan import JMeterTestPlan
from JMeterHttpSampler import JMeterHttpSampler
from JMeterResponseAssert import JMeterResponseAssert
from JMeterResultCollector import JMeterResultCollector
import base
class GenJMeter:
jmeter_script = JMeter.get()
hash_tree = ET.SubElement(jmeter_script, 'hashTree')
test_plan = JMeterTestPlan()
test_plan = test_plan.get(hash_tree)
thread_group_tree = ET.SubElement(hash_tree, 'hashTree')
thread_group = JMeterThreadGroup().get(thread_group_tree)
test_hashtree = ET.SubElement(thread_group_tree, 'hashTree')
http_sampler = JMeterHttpSampler()
http_sampler.set_params({'test': 123})
http_sampler.set_files({'file': 'test.txt'})
http_sampler.get(test_hashtree)
response_assert = JMeterResponseAssert()
response_assert.set_assert_name('断言')
response_assert.set_assert_text(['test', '123'])
response_assert.set_test_type('2')
response_assert.get(test_hashtree)
result_collector_prop = JMeterResultCollector()
result_collector_prop.get(test_hashtree)
bases = base.General()
tree = ET.ElementTree(jmeter_script)
bases.indent(jmeter_script)
with open('test.jmx', "wb") as f:
tree.write(f, encoding="utf-8", xml_declaration=True, method="xml")
其他组件实现方式待续