动态组装jmeter的件到jmx文件

str_element.py

# -*- coding: utf-8 -*-

has_tree_label_str = "<hashTree></hashTree>"

jmeter_test_plan_str = """
        <jmeterTestPlan version="1.2" properties="5.0" jmeter="5.4.1">
        </jmeterTestPlan>
        """

test_plane_str = """
            <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="测试计划" enabled="true">
              <stringProp name="TestPlan.comments"></stringProp>
              <boolProp name="TestPlan.functional_mode">false</boolProp>
              <boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
              <boolProp name="TestPlan.serialize_threadgroups">true</boolProp>
              <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
                <collectionProp name="Arguments.arguments"/>
              </elementProp>
              <stringProp name="TestPlan.user_define_classpath"></stringProp>
            </TestPlan>
        """

thread_group_str = """
        <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
          <boolProp name="LoopController.continue_forever">false</boolProp>
          <stringProp name="LoopController.loops">1</stringProp>
        </elementProp>
        <stringProp name="ThreadGroup.num_threads">1</stringProp>
        <stringProp name="ThreadGroup.ramp_time">1</stringProp>
        <boolProp name="ThreadGroup.scheduler">false</boolProp>
        <stringProp name="ThreadGroup.duration"></stringProp>
        <stringProp name="ThreadGroup.delay"></stringProp>
        <boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
        </ThreadGroup>
        """

http_sample_str = """
                <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="http请求" enabled="true">
                  <boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
                  <elementProp name="HTTPsampler.Arguments" elementType="Arguments">
                    <collectionProp name="Arguments.arguments">
                      <elementProp name="" elementType="HTTPArgument">
                        <boolProp name="HTTPArgument.always_encode">false</boolProp>
                        <stringProp name="Argument.value">FORMATQUERY</stringProp>
                        <stringProp name="Argument.metadata">=</stringProp>
                      </elementProp>
                    </collectionProp>
                  </elementProp>
                  <stringProp name="HTTPSampler.domain">IP</stringProp>
                  <stringProp name="HTTPSampler.port">URLPORT</stringProp>
                  <stringProp name="HTTPSampler.protocol">http</stringProp>
                  <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
                  <stringProp name="HTTPSampler.path">URLPATH</stringProp>
                  <stringProp name="HTTPSampler.method">POST</stringProp>
                  <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
                  <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
                  <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
                  <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
                  <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
                  <stringProp name="HTTPSampler.connect_timeout"></stringProp>
                  <stringProp name="HTTPSampler.response_timeout"></stringProp>
                </HTTPSamplerProxy>
        """

csv_data_str = """
                  <CSVDataSet guiclass="TestBeanGUI" testclass="CSVDataSet" testname="CSV 数据文件配置" enabled="true">
                    <stringProp name="delimiter">\t</stringProp>
                    <stringProp name="fileEncoding">UTF-8</stringProp>
                    <stringProp name="filename">QUERYPATH</stringProp>
                    <boolProp name="ignoreFirstLine">false</boolProp>
                    <boolProp name="quotedData">false</boolProp>
                    <boolProp name="recycle">false</boolProp>
                    <stringProp name="shareMode">shareMode.all</stringProp>
                    <boolProp name="stopThread">false</boolProp>
                    <stringProp name="variableNames">VARIABLENAMES</stringProp>
                  </CSVDataSet>
                """

constant_throughput_timer_str = """
          <ConstantThroughputTimer guiclass="TestBeanGUI" testclass="ConstantThroughputTimer" testname="常数吞吐量定时器" enabled="true">
            <intProp name="calcMode">1</intProp>
            <doubleProp>
              <name>throughput</name>
              <value>10.0</value>
              <savedValue>0.0</savedValue>
            </doubleProp>
          </ConstantThroughputTimer>
        """

summary_report_str = """
                  <ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="汇总报告" enabled="true">
                    <boolProp name="ResultCollector.error_logging">false</boolProp>
                    <objProp>
                      <name>saveConfig</name>
                      <value class="SampleSaveConfiguration">
                        <time>true</time>
                        <latency>true</latency>
                        <timestamp>true</timestamp>
                        <success>true</success>
                        <label>true</label>
                        <code>true</code>
                        <message>true</message>
                        <threadName>true</threadName>
                        <dataType>true</dataType>
                        <encoding>false</encoding>
                        <assertions>true</assertions>
                        <subresults>true</subresults>
                        <responseData>false</responseData>
                        <samplerData>false</samplerData>
                        <xml>false</xml>
                        <fieldNames>true</fieldNames>
                        <responseHeaders>false</responseHeaders>
                        <requestHeaders>false</requestHeaders>
                        <responseDataOnError>false</responseDataOnError>
                        <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
                        <assertionsResultsToSave>0</assertionsResultsToSave>
                        <bytes>true</bytes>
                        <sentBytes>true</sentBytes>
                        <url>true</url>
                        <threadCounts>true</threadCounts>
                        <idleTime>true</idleTime>
                        <connectTime>true</connectTime>
                      </value>
                    </objProp>
                    <stringProp name="filename"></stringProp>
                  </ResultCollector>
        """

aggregate_report_str = """
                  <ResultCollector guiclass="StatVisualizer" testclass="ResultCollector" testname="聚合报告" enabled="true">
                    <boolProp name="ResultCollector.error_logging">false</boolProp>
                    <objProp>
                      <name>saveConfig</name>
                      <value class="SampleSaveConfiguration">
                        <time>true</time>
                        <latency>true</latency>
                        <timestamp>true</timestamp>
                        <success>true</success>
                        <label>true</label>
                        <code>true</code>
                        <message>true</message>
                        <threadName>true</threadName>
                        <dataType>true</dataType>
                        <encoding>false</encoding>
                        <assertions>true</assertions>
                        <subresults>true</subresults>
                        <responseData>false</responseData>
                        <samplerData>false</samplerData>
                        <xml>false</xml>
                        <fieldNames>true</fieldNames>
                        <responseHeaders>false</responseHeaders>
                        <requestHeaders>false</requestHeaders>
                        <responseDataOnError>false</responseDataOnError>
                        <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
                        <assertionsResultsToSave>0</assertionsResultsToSave>
                        <bytes>true</bytes>
                        <sentBytes>true</sentBytes>
                        <url>true</url>
                        <threadCounts>true</threadCounts>
                        <idleTime>true</idleTime>
                        <connectTime>true</connectTime>
                      </value>
                    </objProp>
                    <stringProp name="filename"></stringProp>
                  </ResultCollector>
        """

view_result_tree_str = """
                  <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="查看结果树" enabled="true">
                    <boolProp name="ResultCollector.error_logging">false</boolProp>
                    <objProp>
                      <name>saveConfig</name>
                      <value class="SampleSaveConfiguration">
                        <time>false</time>
                        <latency>false</latency>
                        <timestamp>true</timestamp>
                        <success>false</success>
                        <label>false</label>
                        <code>false</code>
                        <message>true</message>
                        <threadName>false</threadName>
                        <dataType>false</dataType>
                        <encoding>false</encoding>
                        <assertions>false</assertions>
                        <subresults>false</subresults>
                        <responseData>true</responseData>
                        <samplerData>true</samplerData>
                        <xml>true</xml>
                        <fieldNames>false</fieldNames>
                        <responseHeaders>false</responseHeaders>
                        <requestHeaders>false</requestHeaders>
                        <responseDataOnError>false</responseDataOnError>
                        <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
                        <assertionsResultsToSave>0</assertionsResultsToSave>
                      </value>
                    </objProp>
                    <stringProp name="filename">RESTREEPATH</stringProp>
                  </ResultCollector>
        """

json_assertion_str = """
          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
            <stringProp name="JSON_PATH"></stringProp>
            <stringProp name="EXPECTED_VALUE"></stringProp>
            <boolProp name="JSONVALIDATION">false</boolProp>
            <boolProp name="EXPECT_NULL">false</boolProp>
            <boolProp name="INVERT">false</boolProp>
            <boolProp name="ISREGEX">true</boolProp>
          </JSONPathAssertion>
        """

json_post_processor_str = """
        <JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="后置JSON抽取器" enabled="true">
            <stringProp name="JSONPostProcessor.referenceNames"></stringProp>
            <stringProp name="JSONPostProcessor.jsonPathExprs"></stringProp>
            <stringProp name="JSONPostProcessor.match_numbers"></stringProp>
        </JSONPostProcessor>
        """

jmeter.py

# -*- coding: utf-8 -*-


from str_elements import *
from xml.dom import minidom
from xml.dom.minidom import Document


class Jmeter(object):
    """
    jmeter工具,根据参数自动生成jmx文件
    组装jmx文件规则:
    1. 组件(配置元件、定时器、前置处理器、后置处理器、断言与监听器)结束地方需要使用 <hashTree/>做分隔,
    2.上层测试元素包含子测试元素时候需要将子测试元素包裹在 <hashTree> ... </hashTree> 中
    """
    def __init__(self):
        """
        init
        """
        pass

    def create_has_tree(self):
        """
        创建标签 hashTree
        """
        has_tree_label = minidom.parseString(has_tree_label_str).getElementsByTagName('hashTree')[0]
        return has_tree_label

    def get_element_with_has_tree(self, element_str, tag_name, sub_element):
        """
        从str类型的element中解析出Element对象元素,并将子对象元素放入element中
        :param element_str: str类型的element
        :param sub_element: 子节点对象
        :param tag_name: element_str的tag名字
        :return: Element类型元素
        """
        has_tree = self.create_has_tree()
        element = minidom.parseString(element_str).getElementsByTagName(tag_name)[0]
        has_tree.appendChild(element)
        has_tree.appendChild(sub_element)
        return has_tree

    def create_jmeter_test_plane(self, sub_element):
        """
        生成 jmeterTestPlan,也是根节点
        :param sub_element: 子节点对象
        :return: Document
        """
        dom_tree = Document()  # 创建xml
        element = minidom.parseString(jmeter_test_plan_str).getElementsByTagName('jmeterTestPlan')[0]
        element.appendChild(sub_element)
        dom_tree.appendChild(element)  # document只能添加一个根节点
        return dom_tree

    def create_test_plane(self, sub_element):
        """
        生成 TestPlan (测试计划)
        :param sub_element: 子节点对象
        :return: Element类型元素
        """
        return self.get_element_with_has_tree(test_plane_str, 'TestPlan', sub_element)

    def create_thread_group(self, sub_element):
        """
        生成 ThreadGroup (线程组)
        :param sub_element: 子节点对象
        :return: Element类型元素
        """
        return self.get_element_with_has_tree(thread_group_str, 'ThreadGroup', sub_element)

    def create_http_sample(self, sub_element):
        """
        生成 HTTPSamplerProxy (采样器 http请求)
        :param sub_element: 子节点对象
        :return: Element类型元素
        """
        return self.get_element_with_has_tree(http_sample_str, 'HTTPSamplerProxy', sub_element)

    # 下方为创建jmeter组件,创建方法与测试计划、线程组、控制器 不同
    @classmethod
    def create_csv_data_set(cls):
        """
        生成 CSVDataSet (配置元件)
        :return: Element类型的组件元素
        """
        return minidom.parseString(csv_data_str).getElementsByTagName('CSVDataSet')[0]

    @classmethod
    def create_constant_throughput_timer(cls):
        """
        生成 ConstantThroughputTimer (常数吞吐量定时器 配置元件)
        :return:Element类型的组件元素
        """
        return minidom.parseString(constant_throughput_timer_str).getElementsByTagName('ConstantThroughputTimer')[0]

    @classmethod
    def create_summary_report(cls):
        """
        生成 SummaryReport  (配置元件)
        :return:Element类型的组件元素
        """
        return minidom.parseString(summary_report_str).getElementsByTagName('ResultCollector')[0]

    @classmethod
    def create_aggregate_report(cls):
        """
        生成 StatVisualizer(聚合报告)  (配置元件)
        :return: Element类型的组件元素
        """
        return minidom.parseString(aggregate_report_str).getElementsByTagName('ResultCollector')[0]

    @classmethod
    def create_view_result_tree(cls):
        """
        生成 ViewResultsFullVisualizer  查看结果树 (配置元件)
        :return: Element类型的组件元素
        """

        return minidom.parseString(view_result_tree_str).getElementsByTagName('ResultCollector')[0]

    @classmethod
    def create_json_assertion(cls):
        """
        生成 JSONPathAssertion  (配置元件,JSON断言可以对服务器返回的JSON文档进行验证)
        :return: Element类型的组件元素
        """
        return minidom.parseString(json_assertion_str).getElementsByTagName('JSONPathAssertion')[0]

    @classmethod
    def create_json_post_processor(cls):
        """
        后置JSON抽取器
        :return: Element类型的组件元素
        """
        return minidom.parseString(json_post_processor_str).getElementsByTagName('JSONPostProcessor')[0]


if __name__ == '__main__':
    """
    main
    """
    j = Jmeter()
    sub_unit = j.create_has_tree()
    has_tree2 = j.create_has_tree()

    csv_data = j.create_csv_data_set()
    agg_report = j.create_aggregate_report()
    visual_tree = j.create_view_result_tree()
    constant_timer = j.create_constant_throughput_timer()
    json_post_processor = j.create_json_post_processor()
    # ---------------------------------------------------
    sub_unit.appendChild(csv_data)
    sub_unit.appendChild(has_tree2.cloneNode(True))

    sub_unit.appendChild(agg_report)
    sub_unit.appendChild(has_tree2.cloneNode(True))

    sub_unit.appendChild(visual_tree)
    sub_unit.appendChild(has_tree2.cloneNode(True))

    sub_unit.appendChild(constant_timer)
    sub_unit.appendChild(has_tree2.cloneNode(True))

    sub_unit.appendChild(json_post_processor)
    sub_unit.appendChild(has_tree2.cloneNode(True))

    # ---------------------------------------------------
    http = j.create_http_sample(sub_unit)

    thread = j.create_thread_group(http)
    test_plane = j.create_test_plane(thread)

    jmeter_plane = j.create_jmeter_test_plane(test_plane)
    with open('test1.xml', 'w', encoding="UTF-8") as f:
        jmeter_plane.writexml(f, addindent='  ', encoding='utf-8')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值