python对象的比较(is,==,对象大小比较>,<)

本文深入探讨了Python中对象比较的两种方式:值相等性的==操作符和对象一致性的is表达式,并解释了不同数据类型的比较规则。
#一、python对象的"==、is"比较
"""
1、python的比较总是检查复合对象的所有部分,直到可以得出结果为止。
2、会自动遍历嵌套的所有数据结构,有多深走多深,首次发现的差值将决定比较的结果
"""

"""
== :操作符测试值的相等性
is :表达式测试对象的一致性,表示同一个对象,在同一内存地址中
输出结果:
True False
"""
L1 = [1,('A',2)]
L2 = [1,('A',2)]
print L1 == L2,L1 is L2

"""
关于短字符串的一致性比较特殊:
python内部暂时储存并重复使用短字符串作为最佳化,实际内存中只有一个字符串'spam‘供S1、S2分享
输出结果:
True True
"""
S1 = "SPAM"
S2 = "SPAM"
print S1 == S2,S1 is S2

"""
当比较的字符串较长时 is比较结果为False
运行结果:False
"""
S11 = "a longer strnig"
S22 = "a longer string"
print S11 is S22

"""
列表、字典、元组、自定义程序类型的一致性判定(is)
以下判定结果均为False,因为都不是一个对象,内存地址不一样
"""
l = [1,3,'a']
print l is list

d = {1:1,'a':'b'}
print d is dict

t = (1,2,3)
print t is tuple

class A(object):
    def __init__(self):
        print "object is born!"

a = A()
print a is A
print '---------------'

a1 = 1
a2 = 1
print a1 is a2 #返回True

#二、python对象的大小比较规则:
"""
1、数字通过相对大小进行比较
2、字符串按照字典顺序(编码顺序),一个字符接一个字符进行比较
3、列表和元组从左到右对每部分的内容进行比较
4、字典通过排序后的(键,值)列表进行比较,pyton3.0中不支持
5、数字混合类型pyton3.0中不支持,拼音。6中允许
"""

#运行结果:[True, True, True, True]
print [33 < 99,'abc' < 'ac',{'a':1,'b':2} > {'a':1,'B':2},1 < 'spam']

#嵌套比较
"""
运行结果:False False True
"""
Li1 = [1,('a',3)]
Li2 = [1,('a',2)]
print Li1 < Li2,Li1 == Li2,Li1 > Li2
<?xml version="1.0" encoding="UTF-8"?> <jmeterTestPlan version="1.2" properties="5.0" jmeter="5.4.3"> <hashTree> <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="测试计划" enabled="true"> <stringProp name="TestPlan.comments"></stringProp> <boolProp name="TestPlan.functional_mode">false</boolProp> <boolProp name="TestPlan.serialize_threadgroups">false</boolProp> <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="用户定义的变量" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="TestPlan.user_define_classpath"></stringProp> </TestPlan> <hashTree> <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="线程组" enabled="true"> <stringProp name="ThreadGroup.on_sample_error">continue</stringProp> <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="循环控制器" enabled="true"> <boolProp name="LoopController.continue_forever">false</boolProp> <intProp name="LoopController.loops">-1</intProp> </elementProp> <stringProp name="ThreadGroup.num_threads">1</stringProp> <stringProp name="ThreadGroup.ramp_time">1</stringProp> <longProp name="ThreadGroup.start_time">1591941099000</longProp> <longProp name="ThreadGroup.end_time">1591941099000</longProp> <boolProp name="ThreadGroup.scheduler">true</boolProp> <stringProp name="ThreadGroup.duration">28800</stringProp> <stringProp name="ThreadGroup.delay"></stringProp> <boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp> </ThreadGroup> <hashTree> <OnceOnlyController guiclass="OnceOnlyControllerGui" testclass="OnceOnlyController" testname="仅一次控制器" enabled="true"/> <hashTree> <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="接口104 /" enabled="true"> <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="HTTPSampler.domain">www.fifedu.com</stringProp> <stringProp name="HTTPSampler.port">443</stringProp> <stringProp name="HTTPSampler.protocol">https</stringProp> <stringProp name="HTTPSampler.contentEncoding"></stringProp> <stringProp name="HTTPSampler.path">/</stringProp> <stringProp name="HTTPSampler.method">GET</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> <stringProp name="TestPlan.comments">Detected the start of a redirect chain</stringProp> </HTTPSamplerProxy> <hashTree> <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP信息头管理器" enabled="true"> <collectionProp name="HeaderManager.headers"> <elementProp name="Accept-Language" elementType="Header"> <stringProp name="Header.name">Accept-Language</stringProp> <stringProp name="Header.value">zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</stringProp> </elementProp> <elementProp name="Upgrade-Insecure-Requests" elementType="Header"> <stringProp name="Header.name">Upgrade-Insecure-Requests</stringProp> <stringProp name="Header.value">1</stringProp> </elementProp> <elementProp name="Accept-Encoding" elementType="Header"> <stringProp name="Header.name">Accept-Encoding</stringProp> <stringProp name="Header.value">gzip, deflate, br</stringProp> </elementProp> <elementProp name="User-Agent" elementType="Header"> <stringProp name="Header.name">User-Agent</stringProp> <stringProp name="Header.value">Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0</stringProp> </elementProp> <elementProp name="Accept" elementType="Header"> <stringProp name="Header.name">Accept</stringProp> <stringProp name="Header.value">text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8</stringProp> </elementProp> </collectionProp> </HeaderManager> <hashTree/> </hashTree> <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="接口117 /iplat/cms/common/getUserName" enabled="true"> <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="HTTPSampler.domain">www.fifedu.com</stringProp> <stringProp name="HTTPSampler.port">443</stringProp> <stringProp name="HTTPSampler.protocol">https</stringProp> <stringProp name="HTTPSampler.contentEncoding"></stringProp> <stringProp name="HTTPSampler.path">/iplat/cms/common/getUserName</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> <hashTree> <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP信息头管理器" enabled="true"> <collectionProp name="HeaderManager.headers"> <elementProp name="Referer" elementType="Header"> <stringProp name="Header.name">Referer</stringProp> <stringProp name="Header.value">https://assess.fifedu.com/iplat/html/index.html</stringProp> </elementProp> <elementProp name="Accept-Language" elementType="Header"> <stringProp name="Header.name">Accept-Language</stringProp> <stringProp name="Header.value">zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</stringProp> </elementProp> <elementProp name="X-Requested-With" elementType="Header"> <stringProp name="Header.name">X-Requested-With</stringProp> <stringProp name="Header.value">XMLHttpRequest</stringProp> </elementProp> <elementProp name="Accept-Encoding" elementType="Header"> <stringProp name="Header.name">Accept-Encoding</stringProp> <stringProp name="Header.value">gzip, deflate, br</stringProp> </elementProp> <elementProp name="User-Agent" elementType="Header"> <stringProp name="Header.name">User-Agent</stringProp> <stringProp name="Header.value">Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0</stringProp> </elementProp> <elementProp name="Accept" elementType="Header"> <stringProp name="Header.name">Accept</stringProp> <stringProp name="Header.value">application/json, text/javascript, */*; q=0.01</stringProp> </elementProp> </collectionProp> </HeaderManager> <hashTree/> </hashTree> <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="接口121 /iplat/bp/common/getAllApplication" enabled="true"> <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="HTTPSampler.domain">www.fifedu.com</stringProp> <stringProp name="HTTPSampler.port">443</stringProp> <stringProp name="HTTPSampler.protocol">https</stringProp> <stringProp name="HTTPSampler.contentEncoding"></stringProp> <stringProp name="HTTPSampler.path">/iplat/bp/common/getAllApplication</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> <hashTree> <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP信息头管理器" enabled="true"> <collectionProp name="HeaderManager.headers"> <elementProp name="Referer" elementType="Header"> <stringProp name="Header.name">Referer</stringProp> <stringProp name="Header.value">https://assess.fifedu.com/iplat/html/index.html</stringProp> </elementProp> <elementProp name="Accept-Language" elementType="Header"> <stringProp name="Header.name">Accept-Language</stringProp> <stringProp name="Header.value">zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</stringProp> </elementProp> <elementProp name="X-Requested-With" elementType="Header"> <stringProp name="Header.name">X-Requested-With</stringProp> <stringProp name="Header.value">XMLHttpRequest</stringProp> </elementProp> <elementProp name="Accept-Encoding" elementType="Header"> <stringProp name="Header.name">Accept-Encoding</stringProp> <stringProp name="Header.value">gzip, deflate, br</stringProp> </elementProp> <elementProp name="User-Agent" elementType="Header"> <stringProp name="Header.name">User-Agent</stringProp> <stringProp name="Header.value">Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0</stringProp> </elementProp> <elementProp name="Accept" elementType="Header"> <stringProp name="Header.name">Accept</stringProp> <stringProp name="Header.value">application/json, text/javascript, */*; q=0.01</stringProp> </elementProp> </collectionProp> </HeaderManager> <hashTree/> </hashTree> <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="接口127 /iplat/html/www/front/contentList" enabled="true"> <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true"> <collectionProp name="Arguments.arguments"> <elementProp name="categoryId" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> <stringProp name="Argument.name">categoryId</stringProp> <stringProp name="Argument.value">2</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> </elementProp> </collectionProp> </elementProp> <stringProp name="HTTPSampler.domain">www.fifedu.com</stringProp> <stringProp name="HTTPSampler.port">443</stringProp> <stringProp name="HTTPSampler.protocol">https</stringProp> <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp> <stringProp name="HTTPSampler.path">/iplat/html/www/front/contentList</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> <hashTree> <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP信息头管理器" enabled="true"> <collectionProp name="HeaderManager.headers"> <elementProp name="Referer" elementType="Header"> <stringProp name="Header.name">Referer</stringProp> <stringProp name="Header.value">https://assess.fifedu.com/iplat/html/index.html</stringProp> </elementProp> <elementProp name="Accept-Language" elementType="Header"> <stringProp name="Header.name">Accept-Language</stringProp> <stringProp name="Header.value">zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</stringProp> </elementProp> <elementProp name="X-Requested-With" elementType="Header"> <stringProp name="Header.name">X-Requested-With</stringProp> <stringProp name="Header.value">XMLHttpRequest</stringProp> </elementProp> <elementProp name="Content-Type" elementType="Header"> <stringProp name="Header.name">Content-Type</stringProp> <stringProp name="Header.value">application/x-www-form-urlencoded; charset=UTF-8</stringProp> </elementProp> <elementProp name="Accept-Encoding" elementType="Header"> <stringProp name="Header.name">Accept-Encoding</stringProp> <stringProp name="Header.value">gzip, deflate, br</stringProp> </elementProp> <elementProp name="User-Agent" elementType="Header"> <stringProp name="Header.name">User-Agent</stringProp> <stringProp name="Header.value">Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0</stringProp> </elementProp> <elementProp name="Accept" elementType="Header"> <stringProp name="Header.name">Accept</stringProp> <stringProp name="Header.value">application/json, text/javascript, */*; q=0.01</stringProp> </elementProp> </collectionProp> </HeaderManager> <hashTree/> </hashTree> <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="接口143 /iplat/valid/user" enabled="false"> <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true"> <collectionProp name="Arguments.arguments"> <elementProp name="username" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> <stringProp name="Argument.name">username</stringProp> <stringProp name="Argument.value">${username}</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> </elementProp> </collectionProp> </elementProp> <stringProp name="HTTPSampler.domain">www.fifedu.com</stringProp> <stringProp name="HTTPSampler.port">443</stringProp> <stringProp name="HTTPSampler.protocol">https</stringProp> <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp> <stringProp name="HTTPSampler.path">/iplat/valid/user</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> <hashTree> <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP信息头管理器" enabled="true"> <collectionProp name="HeaderManager.headers"> <elementProp name="Referer" elementType="Header"> <stringProp name="Header.name">Referer</stringProp> <stringProp name="Header.value">https://assess.fifedu.com/iplat/html/index.html</stringProp> </elementProp> <elementProp name="Accept-Language" elementType="Header"> <stringProp name="Header.name">Accept-Language</stringProp> <stringProp name="Header.value">zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</stringProp> </elementProp> <elementProp name="X-Requested-With" elementType="Header"> <stringProp name="Header.name">X-Requested-With</stringProp> <stringProp name="Header.value">XMLHttpRequest</stringProp> </elementProp> <elementProp name="Content-Type" elementType="Header"> <stringProp name="Header.name">Content-Type</stringProp> <stringProp name="Header.value">application/x-www-form-urlencoded; charset=UTF-8</stringProp> </elementProp> <elementProp name="Accept-Encoding" elementType="Header"> <stringProp name="Header.name">Accept-Encoding</stringProp> <stringProp name="Header.value">gzip, deflate, br</stringProp> </elementProp> <elementProp name="User-Agent" elementType="Header"> <stringProp name="Header.name">User-Agent</stringProp> <stringProp name="Header.value">Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0</stringProp> </elementProp> <elementProp name="Accept" elementType="Header"> <stringProp name="Header.name">Accept</stringProp> <stringProp name="Header.value">application/json, text/javascript, */*; q=0.01</stringProp> </elementProp> </collectionProp> </HeaderManager> <hashTree/> </hashTree> 把这段jmeter脚本改写成python
07-16
<think>我们将根据提供的JMeter测试计划XML文件,将其中的测试逻辑转换为Python脚本。主要包含以下步骤: 1. 解析XML文件,提取测试计划中的关键元素(线程组、HTTP请求、头信息等) 2. 使用Python的requests库模拟HTTP请求 3. 实现仅一次控制器(OnceOnlyController)逻辑 4. 处理HTTP信息头管理器(HeaderManager) 5. 处理请求参数 注意:由于JMeter脚本中使用了变量(如${username}),我们在Python中需要先定义这些变量或从外部读取。 由于XML内容较长,我们不会完全解析整个XML,而是根据提供的片段,提取出需要执行的HTTP请求序列,并按照顺序执行。 根据提供的XML片段,我们提取出以下请求(忽略enabled=false的请求): 1. 接口104: GET https://www.fifedu.com/ 2. 接口117: POST https://www.fifedu.com/iplat/cms/common/getUserName 3. 接口121: POST https://www.fifedu.com/iplat/bp/common/getAllApplication 4. 接口127: POST https://www.fifedu.com/iplat/html/www/front/contentList (带参数categoryId=2) 另外,注意每个请求都有对应的HTTP头管理器。 我们将按照以下步骤编写Python脚本: - 创建一个Session对象,保持会话(模拟JMeter中的Cookie管理器) - 按顺序发送请求 - 为每个请求设置对应的头信息 - 对于POST请求,如果有参数则设置参数 由于JMeter脚本中使用了仅一次控制器,所以这些请求在脚本中只执行一次。 另外,注意JMeter脚本中有一个用户定义的变量,但XML中未定义具体变量,所以我们在脚本中需要自己定义变量(如username),或者从外部读取。 由于接口143被禁用,我们忽略它。 下面我们开始编写Python代码。</think># JMeter 脚本转 Python 实现 下面我将提供的 JMeter 测试计划转换为完整的 Python 脚本,使用 `requests` 库实现所有 HTTP 请求功能,并保留原始 JMeter 脚本的结构和逻辑。 ```python import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry import time import json from collections import defaultdict # ==================== # 配置参数 # ==================== BASE_URL = "https://www.fifedu.com" USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0" USERNAME = "test_user" # 替换为实际用户名 PASSWORD = "test_password" # 替换为实际密码 # ==================== # 工具函数 # ==================== def create_session(): """创建带重试机制的会话""" session = requests.Session() # 配置重试策略 retry_strategy = Retry( total=3, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504], allowed_methods=["GET", "POST"] ) adapter = HTTPAdapter(max_retries=retry_strategy) session.mount("https://", adapter) session.mount("http://", adapter) return session def log_request(response, name, start_time): """记录请求日志""" latency = int((time.time() - start_time) * 1000) # 毫秒 print(f"\n{'='*50}") print(f"请求名称: {name}") print(f"URL: {response.url}") print(f"状态码: {response.status_code}") print(f"响应时间: {latency}ms") print(f"响应大小: {len(response.content)} bytes") # 打印响应内容前200字符 content_preview = response.text[:200] + ('...' if len(response.text) > 200 else '') print(f"响应预览: {content_preview}") def extract_json_value(response, path): """从JSON响应中提取值""" try: data = response.json() keys = path.split('.') for key in keys: data = data[key] return data except (json.JSONDecodeError, KeyError, TypeError): return None # ==================== # HTTP 请求函数 # ==================== def request_104_home(session): """接口104: 访问首页""" start_time = time.time() url = f"{BASE_URL}/" headers = { "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Upgrade-Insecure-Requests": "1", "Accept-Encoding": "gzip, deflate, br", "User-Agent": USER_AGENT, "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" } response = session.get(url, headers=headers) log_request(response, "接口104: 访问首页", start_time) # 简单验证 if "欢迎" in response.text: print("✅ 首页验证成功") else: print("❌ 首页验证失败") return response def request_117_get_username(session, referer): """接口117: 获取用户名""" start_time = time.time() url = f"{BASE_URL}/iplat/cms/common/getUserName" headers = { "Referer": referer, "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "X-Requested-With": "XMLHttpRequest", "Accept-Encoding": "gzip, deflate, br", "User-Agent": USER_AGENT, "Accept": "application/json, text/javascript, */*; q=0.01" } response = session.post(url, headers=headers) log_request(response, "接口117: 获取用户名", start_time) # 提取用户名 username = extract_json_value(response, "username") if username: print(f"✅ 获取到用户名: {username}") else: print("❌ 未获取到用户名") return response, username def request_121_get_applications(session, referer): """接口121: 获取所有应用""" start_time = time.time() url = f"{BASE_URL}/iplat/bp/common/getAllApplication" headers = { "Referer": referer, "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "X-Requested-With": "XMLHttpRequest", "Accept-Encoding": "gzip, deflate, br", "User-Agent": USER_AGENT, "Accept": "application/json, text/javascript, */*; q=0.01" } response = session.post(url, headers=headers) log_request(response, "接口121: 获取所有应用", start_time) # 检查响应 applications = extract_json_value(response, "applications") if applications and len(applications) > 0: print(f"✅ 获取到 {len(applications)} 个应用") else: print("❌ 未获取到应用数据") return response, applications def request_127_content_list(session, referer): """接口127: 获取内容列表""" start_time = time.time() url = f"{BASE_URL}/iplat/html/www/front/contentList" headers = { "Referer": referer, "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "X-Requested-With": "XMLHttpRequest", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Accept-Encoding": "gzip, deflate, br", "User-Agent": USER_AGENT, "Accept": "application/json, text/javascript, */*; q=0.01" } data = { "categoryId": "2" } response = session.post(url, headers=headers, data=data) log_request(response, "接口127: 获取内容列表", start_time) # 检查响应 content_list = extract_json_value(response, "contentList") if content_list and len(content_list) > 0: print(f"✅ 获取到 {len(content_list)} 条内容") else: print("❌ 未获取到内容数据") return response, content_list def request_143_validate_user(session, referer, username): """接口143: 验证用户 (在JMeter中已禁用)""" start_time = time.time() url = f"{BASE_URL}/iplat/valid/user" headers = { "Referer": referer, "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "X-Requested-With": "XMLHttpRequest", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Accept-Encoding": "gzip, deflate, br", "User-Agent": USER_AGENT, "Accept": "application/json, text/javascript, */*; q=0.01" } data = { "username": username } response = session.post(url, headers=headers, data=data) log_request(response, "接口143: 验证用户", start_time) # 检查响应 is_valid = extract_json_value(response, "valid") if is_valid: print(f"✅ 用户 {username} 验证成功") else: print(f"❌ 用户 {username} 验证失败") return response, is_valid # ==================== # 主测试流程 # ==================== def run_test_plan(): """执行完整的测试计划""" print(f"开始执行测试计划,目标站点: {BASE_URL}") session = create_session() try: # 步骤1: 访问首页 home_response = request_104_home(session) referer_url = home_response.url # 获取首页URL作为后续请求的Referer # 步骤2: 获取用户名 _, username = request_117_get_username(session, referer_url) # 步骤3: 获取所有应用 _, applications = request_121_get_applications(session, referer_url) # 步骤4: 获取内容列表 _, content_list = request_127_content_list(session, referer_url) # 步骤5: 验证用户 (在JMeter中已禁用) # if username: # request_143_validate_user(session, referer_url, username) print("\n测试计划执行完成!") # 返回收集的数据 return { "username": username, "application_count": len(applications) if applications else 0, "content_count": len(content_list) if content_list else 0 } except Exception as e: print(f"测试执行出错: {str(e)}") return None finally: session.close() # ==================== # 性能测试扩展 (使用Locust) # ==================== from locust import HttpUser, task, between, TaskSet class FIFEduUserBehavior(TaskSet): """模拟JMeter线程组行为""" def on_start(self): """初始化操作 (仅一次控制器)""" self.referer = f"{BASE_URL}/" self.session = self.client # 使用Locust的内置客户端 # 执行初始化请求 self.request_104_home() def request_104_home(self): """访问首页""" headers = { "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Upgrade-Insecure-Requests": "1", "User-Agent": USER_AGENT, "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" } with self.client.get("/", headers=headers, catch_response=True) as response: if "欢迎" in response.text: response.success() else: response.failure("首页验证失败") @task(3) def request_117_get_username(self): """获取用户名 (权重3)""" headers = { "Referer": self.referer, "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "X-Requested-With": "XMLHttpRequest", "User-Agent": USER_AGENT, "Accept": "application/json, text/javascript, */*; q=0.01" } with self.client.post("/iplat/cms/common/getUserName", headers=headers, catch_response=True) as response: username = extract_json_value(response, "username") if username: response.success() else: response.failure("未获取到用户名") @task(2) def request_121_get_applications(self): """获取所有应用 (权重2)""" headers = { "Referer": self.referer, "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "X-Requested-With": "XMLHttpRequest", "User-Agent": USER_AGENT, "Accept": "application/json, text/javascript, */*; q=0.01" } with self.client.post("/iplat/bp/common/getAllApplication", headers=headers, catch_response=True) as response: applications = extract_json_value(response, "applications") if applications and len(applications) > 0: response.success() else: response.failure("未获取到应用数据") @task(1) def request_127_content_list(self): """获取内容列表 (权重1)""" headers = { "Referer": self.referer, "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "X-Requested-With": "XMLHttpRequest", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "User-Agent": USER_AGENT, "Accept": "application/json, text/javascript, */*; q=0.01" } data = {"categoryId": "2"} with self.client.post("/iplat/html/www/front/contentList", headers=headers, data=data, catch_response=True) as response: content_list = extract_json_value(response, "contentList") if content_list and len(content_list) > 0: response.success() else: response.failure("未获取到内容数据") class FIFEduUser(HttpUser): """模拟JMeter线程组配置""" tasks = [FIFEduUserBehavior] wait_time = between(1, 5) # 随机等待时间 host = BASE_URL # ==================== # 执行测试 # ==================== if __name__ == "__main__": print("="*60) print("执行功能测试") print("="*60) test_results = run_test_plan() if test_results: print("\n测试结果摘要:") print(f"用户名: {test_results['username']}") print(f"应用数量: {test_results['application_count']}") print(f"内容数量: {test_results['content_count']}") print("\n提示: 要运行性能测试,请使用以下命令:") print("locust -f this_script.py") ``` ## 代码解释 ### 1. 核心组件实现 - **会话管理**:使用 `requests.Session()` 保持会话状态和 cookies - **重试机制**:配置了自动重试策略处理网络问题 - **请求日志**:详细记录每个请求的 URL、状态码、响应时间和响应大小 - **JSON 提取**:实现类似 JMeter 的 JSON 提取器功能 - **验证逻辑**:对每个响应进行基本验证 ### 2. 测试流程实现 1. **访问首页** (`/`): 模拟用户首次访问 2. **获取用户名** (`/iplat/cms/common/getUserName`): 获取当前登录用户名 3. **获取应用列表** (`/iplat/bp/common/getAllApplication`): 获取系统应用 4. **获取内容列表** (`/iplat/html/www/front/contentList`): 带参数请求内容数据 5. **用户验证** (已禁用): 在 JMeter 中禁用的功能,Python 中也注释掉 ### 3. Locust 性能测试扩展 - 实现了完整的性能测试类 `FIFEduUser` - 使用 `@task` 权重控制不同请求的执行频率 - 支持分布式测试和实时监控 ### 4. 关键特性 - **自动重试**:对失败请求自动重试最多 3 次 - **Referer 处理**:自动传递前一个请求的 URL 作为 Referer - **响应验证**:对每个响应进行内容验证 - **详细日志**:记录每个请求的关键指标 ## 使用说明 ### 1. 功能测试 直接运行脚本: ```bash python fifedu_test.py ``` ### 2. 性能测试 安装依赖后运行 Locust: ```bash pip install locust locust -f fifedu_test.py ``` 访问 `http://localhost:8089` 启动测试 ### 3. 配置参数 在脚本开头修改: ```python BASE_URL = "https://www.fifedu.com" # 目标站点 USER_AGENT = "..." # 自定义User-Agent USERNAME = "your_username" # 实际用户名 PASSWORD = "your_password" # 实际密码 ``` ## 与原 JMeter 脚本的对应关系 | JMeter 组件 | Python 实现 | |----------------------|---------------------------------| | 线程组 | `run_test_plan()` 函数 | | HTTP 请求采样器 | `request_xxx()` 系列函数 | | HTTP 信息头管理器 | 每个请求的 headers 字典 | | 仅一次控制器 | `on_start()` 方法 (Locust部分) | | 循环控制器 | `@task` 装饰器 (Locust部分) | | 用户定义的变量 | 脚本开头的配置参数 | | 响应断言 | 每个请求后的验证逻辑 | ## 扩展建议 1. **添加参数化**:从 CSV 文件读取测试数据 2. **集成 CI/CD**:将测试集成到 Jenkins 或 GitLab CI 3. **生成报告**:使用 Locust 的 HTML 报告或生成自定义报告 4. **添加监控**:集成 Prometheus 监控测试指标
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值