+ 首页>>工具>>内容

工具阿里聚石塔性能测试服务,另一个云端nGrinder?210次围观
阿里聚石塔性能测试服务,另一个云端nGrinder?

PTS

聚石塔性能测试服务(Performance Testing Service,简称PTS)是集测试机管理、测试数据管理、测试脚本管理、测试场景管理、测试任务管理、测试结果管理、缺陷管理为一体的性能自动化测试平台。有别于以往传统的压测工具,PTS具备分布式高并发压测、脚本在线编辑调试、任务定时启动停止、结果实时展示并持久化保存等特点。针对塔内用户复杂的分布式应用,PTS可以快速扩容动态配置域名,满足不断增长的集群压测需求。

这个介绍跟nGrinder+agent的方式已然非常相似,我们继续往下看。

透过淘宝开放平台的文档中心,我们发现了熟悉的代码,这段利用grinder负载测试框架+Jython完成的业务脚本就是在这个平台上完成的,从这点上来看,pts和ngrinder确有相似之处,都是Jython+grinder,都是通过agent进行不断的集群式负载扩容,通过Jython强大的特性,利用HTTPClient库我们能够轻松完成各种业务,也就是说,pts很好地继承了这一切优点。

#! /usr/bin/env python   
# -*- coding: utf-8 -*-
from net.grinder.script.Grinder import grinder
from net.grinder.script import Test
from util import Trunner
import json

# 导入HTTP支持模块
from net.grinder.plugin.http import HTTPPluginControl
from net.grinder.plugin.http import HTTPRequest
from HTTPClient import CookieModule
from HTTPClient import NVPair

# 导入Java标准类库中的类来使用
from java.util import Random
from com.taobao.qa.perf.tr.script import PapClient

# 获取默认HTTP连接配置对象
connectionDefaults = HTTPPluginControl.getConnectionDefaults()
# 设置HTTP客户端发送请求时,使用GBK来进行URL编码
connectionDefaults.setEncoding('GBK')

# 用户自定义HTTP请求头信息
defaultHeaders = [NVPair('Accept-Encoding', 'gzip'), \
           NVPair('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'), \
           NVPair('User-Agent' , 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172')
           ]

# 测试类框架,每个测试线程辉创建一个TestRunner对象,对象成员线程安全
# __init__方法对象创建时调用一次,__call__方法在测试过程中被循环多次调用,__del__在对象销毁时执行一次
class TestRunner:
    
    def __init__(self):
        # 在__init__方法中执行登录方法,这样用户登录一次,后续可以多次执行业务操作
        self.login()
        # 获得登录后的HTTP Cookie信息,保存在TestRunner对象的成员变量login_cookies中
        self.threadContext = HTTPPluginControl.getThreadHTTPClientContext()
        self.login_cookies = CookieModule.listAllCookies(self.threadContext)
        # 创建一个随机对象
        self.rd = Random()

    # 成员方法,用来实现用户登录
    def login(self):  
        request = HTTPRequest()
        request.setHeaders([NVPair('Content-Type', 'application/json'),])
        result = request.POST('http://xxx.xxxx.xxx.xxx/login/emailLogin', '{"email":"xxx@xxxx.com","pwd":"xxx"}')                    
    
    # 定义一个性能测试事务:发货单发货,先获取列表,然后遍历一一打单(填充物流单)、发货
    def deliveryOrderDeliveryList(self):
        total=0
        page=1
        rows=10
        pageCount=1
        statusCode = [0L, 0L, 0L, 0L]
        while page<=pageCount:  
            request = HTTPRequest()
            result = request.GET('http://xxx.xxx.xxx.xxx/tc/delivery/delivery_order_header/data/list?page='+str(page)+'&rows='+str(rows)+'&delivery=0&time='+str(Random()))  
            Trunner.addHttpCode(result.getStatusCode(), statusCode)
            # 返回结果是json格式,包含订单总数,一页的订单信息
            jsonStr = json.read(result.getText())
            total=jsonStr .get('total')
            rowsList=jsonStr.get('rows')
            # 将返回的订单信息中的id抽取出来
            ids=self._convertToStr(rowsList)
            ids1=self._convertToStr1(rowsList)
            
            # 将抽取出来的订单填充物流信息
            statusCode2=self._fillLogistics(ids1)
            Trunner.setExtraData(statusCode2)
            
            # 将填充好物流信息的订单进行发货操作
            statusCode1=self._deliveryOrderDelivery(ids) 
            Trunner.setExtraData(statusCode1)
            page=page+1             
            # 如果没有更多订单推出循环
            if(total==0):
                break
            # 如果有订单,计算查询到的订单页数
            else:
                if(total%rows<=0):
                    pageCount=total/rows              
                else:
                    pageCount=total/rows+1
        return statusCode

    # 订单进行发货操作的子函数
    def _deliveryOrderDelivery(self,ids):
        statusCode = [0L, 0L, 0L, 0L]
        request = HTTPRequest()
        request.setHeaders([NVPair('Content-Type', 'application/json'),])
        result = request.POST('http://xxx.xxx.xxx.xxx/tc/delivery/delivery_order_header/delivery',ids)
        Trunner.addHttpCode(result.getStatusCode(), statusCode)
        return statusCode
    
    # 订单进行物流信息填充的子函数
    def _fillLogistics(self,ids):
        statusCode = [0L, 0L, 0L, 0L]
        request = HTTPRequest()
        request.setHeaders([NVPair('Content-Type', 'application/json'),])
        result = request.POST('http://xxx.xxx.xxx.xxx/tc/delivery/logistics/fillLogistics',ids)
        Trunner.addHttpCode(result.getStatusCode(), statusCode)
        return statusCode
    
    # 用于将json格式的订单信息转换成id列表的子函数
    def _convertToStr(self,rowsList):
        tempIds='['
        for x in range(len(rowsList)):
            if(x==0):
                tempIds=tempIds+'{"id":"'+rowsList[x]['id']+'"}'
            else:
                tempIds=tempIds+',{"id":"'+rowsList[x]['id']+'"}'
        tempIds=tempIds+']'
        return tempIds
    
    def _convertToStr1(self,rowsList):
        tempIds='['
        for x in range(len(rowsList)):
            if(x==0):
                tempIds=tempIds+'{"id":"'+rowsList[x]['id']+'","mailNo":"'+str(Random().nextInt())+'"}'
            else:
                tempIds=tempIds+',{"id":"'+rowsList[x]['id']+'","mailNo":"'+str(Random().nextInt())+'"}'
        tempIds=tempIds+']'
        return tempIds
    
    def __call__(self):
        # 由于每次__call__循环回丢弃所有cookie信息,所以需要手动添加__init__方法中保存的登录cookie信息
        for c in self.login_cookies:
            CookieModule.addCookie(c, self.threadContext)
        # 框架代码,延迟性能数据汇报,等待所有事务运行结束再汇报
        grinder.statistics.delayReports = 1
        # 调用查询订单并进行填充发货的事务
        statusCode=self.deliveryOrderDeliveryList()
        Trunner.setExtraData(statusCode)
        # 框架代码,强制汇报性能数据
        grinder.statistics.report()
        grinder.statistics.delayReports = 0

# Instrument性能测试事务,参数为:事务所在脚本ID,事务名称,事务描述,事务对应的方法名称,TestRunner类
Trunner.instrumentMethod(Test(PapClient.getId(1415, 'deliveryOrderDeliveryList'), 'deliveryOrderDeliveryList'), 'deliveryOrderDeliveryList', TestRunner)
Trunner.instrumentMethod(Test(PapClient.getId(1415, '_deliveryOrderDelivery'), '_deliveryOrderDelivery'), '_deliveryOrderDelivery', TestRunner)
Trunner.instrumentMethod(Test(PapClient.getId(1415, '_fillLogistics'), '_fillLogistics'), '_fillLogistics', TestRunner)

熟悉nGrinder或者grinder负载测试框架的同学不妨可以尝试一下pts平台,就性能测试而言,淘宝在电商行业积累的经验是值得每一位测试人学习的,既然pts已经打造成一个"云端性能测试平台",那么我们可以利用他最大的优势:现成的资源,不需要再去关注agent及其他资源的搭建,专注于测试业务脚本的开发就可以了,从介绍上来看,部署还是比较容易的。

平台地址

传送门

+ 猜你喜欢...

===== 关于 DiggerPlus =====
DiggerPlus是国内新锐测试人垂直内容博客,专注于挖掘测试工具,普及测试技术,专注于测试人能力提升,博客上线后就受到广大测试人的热烈追捧;此外,DiggerPlus深度整合评测资源,揭秘科技数据和真相,让读者更懂科技,更好地把玩科技。 我们始终保持"独立,客观,严谨,优秀"的优良作风,努力为读者带来源源不断的优质内容。想访问更多酷毙的测试人网站?赶紧来DiggerPlus测试人网址导航看看吧!

===== DiggerPlus Team =====
DiggerPlus Team是DiggerPlus官方发起的团队,这是一群热爱科技,热爱测试,喜欢深度挖掘的热血测试人,他们是评测师,测试专家。 我们欢迎优秀的测试人加入DiggerPlus Team。 加入DiggerPlus,可以成为我们的认证Dper,认证Dper拥有DiggerPlus独一无二的专栏并得到个人展示。

===== DiggerPlus 官方读者群 =====
DiggerPlus官方读者群(一)

+ 关于本文作者

Python/C/C++/Javascript程序员,持续学习者,目前专注于前端开发。

的专栏 | 专栏作者 | 访问小A的主页

+ 发表评论

开源中国精彩推送

基于开源中国OpenAPI开发
  • Copyright © 2014 DiggerPlus. 81 queries in 1.456 seconds.
    使用合作网站账号快速登录,更多精彩等着您: 开源中国